#pragma once #include namespace sp { template class SerializableMessage { using MessageBaseType = typename TMessageFactory::MessageBaseType; using HandlerType = typename MessageBaseType::HandlerType; using MessageIdType = typename MessageBaseType::MessageIdType; public: std::shared_ptr m_Message; SerializableMessage() {} SerializableMessage(std::shared_ptr&& a_Message) : m_Message(a_Message) {} SerializableMessage(const std::shared_ptr& a_Message) : m_Message(a_Message) {} MessageBaseType* operator->() { return m_Message.get(); } operator bool() { return m_Message.get(); } const MessageBaseType* operator->() const { return m_Message.get(); } }; template DataBuffer& operator<<(DataBuffer& a_Buffer, const SerializableMessage& a_Message) { return a_Buffer << VarInt{static_cast(a_Message->GetId())} << a_Message->Write(); } template DataBuffer& operator>>(DataBuffer& a_Buffer, SerializableMessage& a_Message) { using MsgId = typename TMessageFactory::IdType; using MsgBase = typename TMessageFactory::MessageBaseType; static TMessageFactory factory; VarInt msgId; a_Buffer >> msgId; auto msgPtr = std::shared_ptr(factory.CreateMessage(MsgId(msgId.GetValue())).release()); a_Message = SerializableMessage(msgPtr); a_Message->Read(a_Buffer); return a_Buffer; } } // namespace sp