#pragma once /** * \file Packets.h * \brief File containing the definitions of the packets */ #include #include #include #include namespace sp { namespace protocol { class PacketVisitor; /** A Packet id is 8 bits wide */ using PacketID = std::uint8_t; using PeerID = std::uint16_t; #define DeclarePacket(PacketName, ...) /** PacketName */ PacketName, /** * \enum PacketType * \brief Map a Packet to an id */ enum class PacketType : PacketID { DeclareAllPacket() /** The number of packets */ PACKET_COUNT }; #undef DeclarePacket class Packet : private NonCopyable { public: /** * \return The real type of the packet */ virtual PacketType GetType() const = 0; /** * \brief The network peer who sent the packet */ PeerID m_Sender; private: /** Use a PacketVisitor to make double-dispatch possible */ virtual void Accept(PacketVisitor& a_Visitor) const = 0; friend class PacketVisitor; }; namespace packets { /** * \class ConcretePacket * \brief A Packet associated with an id and holding data * \tparam PT The packet type * \tparam Data The structure holding the data of the packet (in sp::protocol::data namespace) */ template class ConcretePacket : public Packet { public: /** The type of the struct holding the data */ using PacketDataType = Data; /** The structure holding the actual data */ PacketDataType m_Data; /** Construct the packet with data of type PacketDataType */ ConcretePacket(const PacketDataType& a_Data = {}); constexpr PacketType GetType() const override { return PT; }; private: void Accept(PacketVisitor& a_Visitor) const override; }; // define SP_INSTANCIATE_PACKETS // before including this file // if you want to instantiate templates #ifdef SP_INSTANCIATE_PACKETS #define DeclarePacket(PacketName, ...) \ using PacketName = ConcretePacket; \ template class ConcretePacket; #else #define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \ using PacketName = ConcretePacket; #endif // DeclareAllPacket() #undef DeclarePacket } // namespace packets } // namespace protocol } // namespace sp