#pragma once #include #include #include namespace blitz { namespace protocol { class PacketVisitor; using PacketID = std::uint8_t; #define DeclarePacket(PacketName, ...) PacketName, enum class PacketType : PacketID { DeclareAllPacket() PACKET_COUNT }; #undef DeclarePacket class Packet { public: virtual PacketType GetType() const = 0; virtual void Accept(PacketVisitor& a_Visitor) const = 0; }; namespace packets { /** * \tparam PT The packet type * \tparam Data The structure holding the data of the packet (in blitz::protocol::data namespace) */ template class ConcretePacket : public Packet { public: using PacketDataType = Data; PacketDataType m_Data; ConcretePacket(const PacketDataType& a_Data = {}); constexpr PacketType GetType() const override { return PT; }; private: void Accept(PacketVisitor& a_Visitor) const override; friend class PacketVisitor; }; // define BLITZ_INSTANCIATE_PACKETS // before including this file // if you want to instantiate templates #ifdef BLITZ_INSTANCIATE_PACKETS #define DeclarePacket(PacketName, ...) \ using PacketName = ConcretePacket; \ template class ConcretePacket; #else #define DeclarePacket(PacketName, ...) using PacketName = ConcretePacket; #endif DeclareAllPacket() #undef DeclarePacket } // namespace packets } // namespace protocol } // namespace blitz