#pragma once #include namespace sp { template class SerializableMessage { using MessageBaseType = typename TMessageFactory::MessageBaseType; using HandlerType = typename MessageBaseType::HandlerType; using MessageIdType = typename MessageBaseType::MessageIdType; private: std::unique_ptr m_Message; public: SerializableMessage(std::unique_ptr&& a_MessagePtr) : m_Message(std::move(a_MessagePtr)) {} operator MessageBaseType&() { return *m_Message; } SerializableMessage& operator=(std::unique_ptr&& a_MessagePtr) { m_Message = std::move(a_MessagePtr); return *this; } MessageIdType GetId() const { return m_Message->GetId(); } void Dispatch(HandlerType& handler) const { m_Message->Dispatch(handler); } void Read(DataBuffer& a_Buffer) { m_Message->Read(a_Buffer); } DataBuffer Write() const { return m_Message->Write(); } }; template DataBuffer& operator<<(DataBuffer& a_Buffer, const std::unique_ptr>& a_Message) { return a_Buffer << VarInt{static_cast(a_Message->GetId())} << a_Message->Write(); } template DataBuffer& operator<<(DataBuffer& a_Buffer, const std::shared_ptr>& a_Message) { return a_Buffer << VarInt{static_cast(a_Message->GetId())} << a_Message->Write(); } template DataBuffer& operator>>(DataBuffer& a_Buffer, std::unique_ptr>& a_Message) { using MsgId = typename TMessageFactory::IdType; static TMessageFactory factory; VarInt msgId; a_Buffer >> msgId; a_Message = std::make_unique>(std::move(factory.CreateMessage(MsgId(msgId.GetValue())))); a_Message->Read(a_Buffer); return a_Buffer; } template DataBuffer& operator>>(DataBuffer& a_Buffer, std::shared_ptr>& a_Message) { using MsgId = typename TMessageFactory::IdType; static TMessageFactory factory; VarInt msgId; a_Buffer >> msgId; a_Message = std::make_shared>(std::move(factory.CreateMessage(MsgId(msgId.GetValue())))); a_Message->Read(a_Buffer); return a_Buffer; } } // namespace sp