gros push encore

This commit is contained in:
2024-10-07 19:48:36 +02:00
parent 701b815dc1
commit 77317df56c
28 changed files with 777 additions and 105 deletions

View File

@@ -1,7 +1,7 @@
#pragma once
#include <cstdint>
#include <fpm/fpm.hpp>
#include <fpm/fixed.hpp>
namespace td {
@@ -63,4 +63,6 @@ struct EntityCoords {
fpm::fixed_16_16 y;
};
using PeerID = std::uint16_t;
} // namespace td

View File

@@ -0,0 +1,286 @@
#pragma once
/**
* \file DataBuffer.h
* \brief File containing the td::DataBuffer class
*/
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
namespace td {
/**
* \class DataBuffer
* \brief Class used to manipulate memory
*/
class DataBuffer {
private:
typedef std::vector<std::uint8_t> Data;
Data m_Buffer;
std::size_t m_ReadOffset;
public:
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;
typedef Data::reference reference;
typedef Data::const_reference const_reference;
typedef Data::difference_type difference_type;
DataBuffer();
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, difference_type offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
/**
* \brief Append data to the buffer
*/
template <typename T>
void Append(const T& data) {
std::size_t size = sizeof(data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
std::memcpy(&m_Buffer[end_pos], &data, size);
}
/**
* \brief Append data to the buffer
*/
template <typename T>
DataBuffer& operator<<(const T& data) {
Append(data);
return *this;
}
/**
* \brief Append a string to the buffer
* \warning Don't use it for binary data !
* \param str The string to append
*/
DataBuffer& operator<<(const std::string& str) {
std::size_t strlen = str.length() + 1; // including null character
Resize(GetSize() + strlen);
std::memcpy(m_Buffer.data() + GetSize() - strlen, str.data(), strlen);
return *this;
}
/**
* \brief Append data to the buffer from another const buffer
* \param data The buffer to append
*/
DataBuffer& operator<<(const DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
/**
* \brief Read some data from the buffer and assign to desired variable
*/
template <typename T>
DataBuffer& operator>>(T& data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
m_ReadOffset += sizeof(T);
return *this;
}
/**
* \brief Read some data from the buffer and assign to the new buffer
* \param data The buffer to assign
*/
DataBuffer& operator>>(DataBuffer& data) {
data.Resize(GetSize() - m_ReadOffset);
std::copy(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
m_ReadOffset = m_Buffer.size();
return *this;
}
/**
* \brief Read a string from the buffer
* \param str The string to assign in the new buffer
* \warning Don't use it for binary data !
*/
DataBuffer& operator>>(std::string& str) {
std::size_t stringSize =
strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
str.resize(stringSize);
std::copy(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset),
m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset + stringSize), str.begin());
m_ReadOffset += stringSize;
return *this;
}
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const char* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
std::memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
/**
* \brief Write some data to the buffer
* \param buffer The buffer to write
* \param amount The amount of data to write
*/
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
std::memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(char* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
/**
* \brief Read some data from the buffer
* \param buffer The buffer to Read
* \param amount The amount of data from the buffer
*/
void ReadSome(DataBuffer& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.Resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
/**
* \brief Resize the buffer
* \param size The new size of the buffer
*/
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
/**
* \brief Reserve some space in the buffer
* \param amount The amount of space to reserve
*/
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
/**
* \brief Clear the buffer
*/
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
/**
* \brief When the buffer has been read entirely
*/
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
/**
* \brief Get the buffer data
*/
std::uint8_t* data() {
return m_Buffer.data();
}
/**
* \brief Get the buffer data
*/
const std::uint8_t* data() const {
return m_Buffer.data();
}
/**
* \brief Get the read offset
*/
std::size_t GetReadOffset() const {
return m_ReadOffset;
}
/**
* \brief Set the read offset
* \param pos The new read offset
*/
void SetReadOffset(std::size_t pos);
/**
* \brief Get the size of the buffer
*/
std::size_t GetSize() const;
/**
* \brief Get the remaining size of the buffer
*/
std::size_t GetRemaining() const;
/**
* \brief Read a file into the buffer
* \param fileName The name of the file to read
*/
bool ReadFile(const std::string& fileName);
/**
* \brief Write a file into the buffer
* \param fileName The name of the file to write to
*/
bool WriteFile(const std::string& fileName) const;
/**
* \brief Allocate the buffer on the heap
* \warning Don't forget to free the data !
*/
std::uint8_t* HeapAllocatedData() const {
std::uint8_t* newBuffer = new std::uint8_t[GetSize()];
std::memcpy(newBuffer, data(), GetSize());
return newBuffer;
}
/**
* \brief Operator == to compare two DataBuffer
*/
bool operator==(const DataBuffer& other) const {
return m_Buffer == other.m_Buffer;
}
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
};
/**
* \brief Operator << to write a DataBuffer to an ostream
*/
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
} // namespace td

View File

@@ -0,0 +1,25 @@
#pragma once
/**
* \file NonCopyable.h
* \brief File containing the td::NonCopyable class
*/
namespace td {
/**
* \class NonCopyable
* \brief Class used to make a class non copyable
* \note Inherit from this class privately to make a class non copyable
*/
class NonCopyable {
public:
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
protected:
NonCopyable() {}
~NonCopyable() {}
};
} // namespace td

View File

@@ -2,57 +2,60 @@
/**
* \file PacketDispatcher.h
* \brief File containing the blitz::protocol::PacketDispatcher class
* \brief File containing the td::protocol::PacketDispatcher class
*/
#include <td/common/NonCopyable.h>
#include <td/protocol/Packets.h>
#include <td/protocol/packet/Packets.h>
#include <map>
namespace td {
namespace protocol {
class PacketHandler;
/**
* \class PacketDispatcher
* \brief Class used to dispatch packets
* \class Dispatcher
* \brief Class used to dispatch things
*/
class PacketDispatcher : private NonCopyable {
template <typename T_Enum, typename T_Handler, typename T>
class Dispatcher : private NonCopyable {
private:
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
std::map<T_Enum, std::vector<T_Handler*>> m_Handlers;
public:
/**
* \brief Constructor
*/
PacketDispatcher() {}
Dispatcher() {}
/**
* \brief Dispatch a packet
* \param packet The packet to dispatch
*/
void Dispatch(const Packet& packet);
void Dispatch(const T& packet);
/**
* \brief Register a packet handler
* \param type The packet type
* \param handler The packet handler
*/
void RegisterHandler(PacketType type, PacketHandler& handler);
void RegisterHandler(T_Enum type, T_Handler& handler);
/**
* \brief Unregister a packet handler
* \param type The packet type
* \param handler The packet handler
*/
void UnregisterHandler(PacketType type, PacketHandler& handler);
void UnregisterHandler(T_Enum type, T_Handler& handler);
/**
* \brief Unregister a packet handler
* \param handler The packet handler
*/
void UnregisterHandler(PacketHandler& handler);
void UnregisterHandler(T_Handler& handler);
};
} // namespace protocol
} // namespace td
#include "Dispatcher.inl"

View File

@@ -0,0 +1,38 @@
#pragma once
namespace td {
namespace protocol {
template <typename T_Enum, typename T_Handler, typename T>
void Dispatcher<T_Enum, T_Handler, T>::Dispatch(const T& packet) {
T_Enum type = packet.GetType();
for (auto* handler : m_Handlers[type])
handler->Check(packet);
}
template <typename T_Enum, typename T_Handler, typename T>
void Dispatcher<T_Enum, T_Handler, T>::RegisterHandler(T_Enum type, T_Handler& handler) {
auto found = std::find(m_Handlers[type].begin(), m_Handlers[type].end(), &handler);
if (found == m_Handlers[type].end())
m_Handlers[type].push_back(&handler);
}
template <typename T_Enum, typename T_Handler, typename T>
void Dispatcher<T_Enum, T_Handler, T>::UnregisterHandler(T_Enum type, T_Handler& handler) {
m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), &handler), m_Handlers[type].end());
}
template <typename T_Enum, typename T_Handler, typename T>
void Dispatcher<T_Enum, T_Handler, T>::UnregisterHandler(T_Handler& handler) {
for (auto& pair : m_Handlers) {
if (pair.second.empty())
continue;
PacketType type = pair.first;
m_Handlers[type].erase(std::remove(m_Handlers[type].begin(), m_Handlers[type].end(), &handler), m_Handlers[type].end());
}
}
} // namespace protocol
} // namespace td

View File

@@ -1,34 +0,0 @@
#pragma once
/**
* \file PacketHandler.h
* \brief File containing the blitz::protocol::PacketHandler class
*/
#include <td/protocol/Packets.h>
#include <td/protocol/PacketVisitor.h>
namespace td {
namespace protocol {
class PacketDispatcher;
#define DeclarePacket(PacketName, ...) virtual void Visit(const packets::PacketName&); virtual void HandlePacket(const packets::PacketName&) {}
/**
* \class PacketHandler
* \brief Class used to handle packets
*/
class PacketHandler : public PacketVisitor {
public:
PacketHandler() {}
~PacketHandler() {}
DeclareAllPacket()
};
#undef DeclarePacket
} // namespace protocol
} // namespace td

View File

@@ -1,20 +0,0 @@
#pragma once
#include <td/protocol/Packets.h>
#include <godot_cpp/variant/packed_byte_array.hpp>
#include <memory>
namespace td {
namespace protocol {
using PacketPtr = std::unique_ptr<Packet>;
namespace PacketSerializer {
godot::PackedByteArray Serialize(const Packet& a_Packet);
std::unique_ptr<Packet> Deserialize(godot::PackedByteArray& a_Data);
}
} // namespace protocol
} // namespace td

View File

@@ -1,10 +1,14 @@
#pragma once
#include <string>
#include <td/Types.h>
namespace td {
namespace protocol {
#define LOCKSTEP_BUFFER_SIZE 10
struct LockStepCommand {};
struct LockStep {
std::uint8_t m_CommandNumber;
@@ -13,11 +17,11 @@ struct LockStep {
struct LockSteps {
std::uint16_t m_FirstFrameNumber;
std::array<LockStep, 10> m_LockSteps;
std::array<LockStep, LOCKSTEP_BUFFER_SIZE> m_LockSteps;
};
namespace data {
namespace cdata {
struct PlaceTower {
@@ -49,9 +53,12 @@ struct TeamChange {
Team m_NewTeam : 1;
};
struct PlayerJoin {
PlayerID m_ID;
std::string m_Name;
};
} // namespace data
} // namespace cdata
} // namespace protocol

View File

@@ -0,0 +1,21 @@
#pragma once
namespace td {
namespace protocol {
/**
* \def DeclareAllPacket
* \brief Avoids repetitive operations on packets
*/
#define DeclareAllCommand() \
DeclareCommand(PlaceTower) \
DeclareCommand(UpgradeTower) \
DeclareCommand(SpawnTroop) \
DeclareCommand(UseItem) \
DeclareCommand(TeamChange) \
DeclareCommand(PlayerJoin)
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,18 @@
#pragma once
/**
* \file CommandDispatcher.h
* \brief File containing the td::protocol::CommandDispatcher class
*/
#include <td/protocol/Dispatcher.h>
namespace td {
namespace protocol {
class CommandHandler;
using CommandDispatcher = Dispatcher<CommandType, CommandHandler, Command>;
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include <td/protocol/command/Commands.h>
namespace td {
namespace protocol {
namespace CommandFactory {
template <typename CommandDerived, typename = typename std::enable_if<std::is_base_of<Command, CommandDerived>::value>::type>
std::unique_ptr<CommandDerived> CreateCommand() {
return std::make_unique<CommandDerived>();
}
const std::unique_ptr<Command>& CreateReadOnlyCommand(CommandType a_Type);
} // namespace CommandFactory
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,33 @@
#pragma once
/**
* \file CommandHandler.h
* \brief File containing the td::protocol::CommandHandler class
*/
#include <td/protocol/command/CommandVisitor.h>
#include <td/protocol/command/Commands.h>
namespace td {
namespace protocol {
#define DeclareCommand(CommandName, ...) \
virtual void Visit(const commands::CommandName&); \
virtual void HandleCommand(const commands::CommandName&) {}
/**
* \class CommandHandler
* \brief Class used to handle packets
*/
class CommandHandler : public CommandVisitor {
public:
CommandHandler() {}
~CommandHandler() {}
DeclareAllCommand()
};
#undef DeclareCommand
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,21 @@
#pragma once
#include <memory>
#include <td/common/DataBuffer.h>
namespace td {
namespace protocol {
class Command;
using CommandPtr = std::unique_ptr<Command>;
namespace CommandSerializer {
DataBuffer Serialize(const Command& a_Command);
std::unique_ptr<Command> Deserialize(DataBuffer& a_Data);
} // namespace CommandSerializer
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,39 @@
#pragma once
/**
* \file CommandVisitor.h
* \brief File containing the td::protocol::CommandVisitor class
*/
#include <td/protocol/command/Commands.h>
namespace td {
namespace protocol {
#define DeclareCommand(CommandName, ...) \
/** This function is called when the packet processed by CommandVisitor::Check is a CommandName */ \
virtual void Visit(const commands::CommandName&) {}
/**
* \class CommandVisitor
* \brief This class uses double-dispatch in order to find the real type of a packet
*/
class CommandVisitor : private NonCopyable {
protected:
CommandVisitor() {}
virtual ~CommandVisitor() {}
public:
/**
* \brief Calls the right CommandVisitor::Visit method corresponding to the real type of the packet
* \param packet the Command to visit
*/
void Check(const Command& packet);
DeclareAllCommand()
};
#undef DeclareCommand
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,108 @@
#pragma once
/**
* \file Commands.h
* \brief File containing the definitions of the lockstep commands
*/
#include <td/Types.h>
#include <td/common/NonCopyable.h>
#include <td/protocol/command/CommandData.h>
#include <td/protocol/command/CommandDeclare.h>
namespace td {
namespace protocol {
class CommandVisitor;
/** A Command id is 8 bits wide */
using CommandID = std::uint8_t;
#define DeclareCommand(CommandName, ...) /** CommandName */ CommandName,
/**
* \enum CommandType
* \brief Map a Command to an id
*/
enum class CommandType : CommandID {
DeclareAllCommand()
/** The number of Commands */
COMMAND_COUNT
};
#undef DeclareCommand
class Command : private NonCopyable {
public:
/**
* \return The real type of the Command
*/
virtual CommandType GetType() const = 0;
private:
/** Use a CommandVisitor to make double-dispatch possible */
virtual void Accept(CommandVisitor& a_Visitor) const = 0;
friend class CommandVisitor;
};
namespace commands {
/**
* \class ConcreteCommand
* \brief A Command associated with an id and holding data
* \tparam PT The Command type
* \tparam Data The structure holding the data of the Command (in td::protocol::data namespace)
*/
template <CommandType CT, typename Data>
class ConcreteCommand : public Command {
public:
/** The type of the struct holding the data */
using CommandDataType = Data;
/** The structure holding the actual data */
CommandDataType m_Data;
/** Construct the Command with data of type CommandDataType */
ConcreteCommand(const CommandDataType& a_Data = {});
constexpr CommandType GetType() const override {
return CT;
};
private:
void Accept(CommandVisitor& a_Visitor) const override;
};
// define TD_INSTANCIATE_COMMANDS
// before including this file
// if you want to instantiate templates
#ifdef TD_INSTANCIATE_COMMANDS
#define DeclareCommand(CommandName, ...) \
using CommandName = ConcreteCommand<CommandType::CommandName, cdata::CommandName>; \
template class ConcreteCommand<CommandType::CommandName, cdata::CommandName>;
#else
#define DeclareCommand(CommandName, ...) /** Defines the CommandName Command */ \
using CommandName = ConcreteCommand<CommandType::CommandName, cdata::CommandName>;
#endif
DeclareAllCommand()
#undef DeclareCommand
} // namespace commands
} // namespace protocol
} // namespace td

View File

@@ -1,8 +1,6 @@
#pragma once
#include <td/common/Types.h>
#include <godot_cpp/variant/string.hpp>
#include <godot_cpp/variant/vector3.hpp>
#include <td/Types.h>
#include <vector>
namespace td {
@@ -10,13 +8,13 @@ namespace protocol {
struct PlayerInfo {
PlayerID m_PlayerId;
godot::String m_PlayerName;
std::string m_PlayerName;
};
namespace data {
namespace pdata {
struct PlayerLogin {
godot::String m_PlayerName;
std::string m_PlayerName;
};
struct UpdateHealth {
@@ -56,23 +54,23 @@ struct KeepAlive {
struct Disconnect {};
struct ChatMessage {
godot::String m_Text;
std::string m_Text;
};
struct PlayerPositionAndRotation {
PlayerID m_Player;
godot::Vector3 m_Position;
godot::Vector3 m_Rotation;
godot::Vector3 m_Velocity;
// godot::Vector3 m_Position;
// godot::Vector3 m_Rotation;
// godot::Vector3 m_Velocity;
};
struct PlayerShoot {
PlayerID m_Sender;
godot::Vector3 m_Position;
godot::Vector3 m_Rotation;
godot::Vector3 m_Velocity;
// godot::Vector3 m_Position;
// godot::Vector3 m_Rotation;
// godot::Vector3 m_Velocity;
};
} // namespace data
} // namespace pdata
} // namespace protocol
} // namespace td

View File

@@ -0,0 +1,18 @@
#pragma once
/**
* \file PacketDispatcher.h
* \brief File containing the td::protocol::PacketDispatcher class
*/
#include <td/protocol/Dispatcher.h>
namespace td {
namespace protocol {
class PacketHandler;
using PacketDispatcher = Dispatcher<PacketType, PacketHandler, Packet>;
} // namespace protocol
} // namespace td

View File

@@ -1,15 +1,15 @@
#pragma once
#include <td/protocol/Packets.h>
#include <memory>
#include <td/protocol/packet/Packets.h>
namespace td {
namespace protocol {
namespace PacketFactory {
template<typename PacketDerived, typename = typename std::enable_if<std::is_base_of<Packet, PacketDerived>::value>::type>
template <typename PacketDerived, typename = typename std::enable_if<std::is_base_of<Packet, PacketDerived>::value>::type>
std::unique_ptr<PacketDerived> CreatePacket() {
return std::make_unique<PacketDerived>();
return std::make_unique<PacketDerived>();
}
const std::unique_ptr<Packet>& CreateReadOnlyPacket(PacketType a_Type);

View File

@@ -0,0 +1,33 @@
#pragma once
/**
* \file PacketHandler.h
* \brief File containing the td::protocol::PacketHandler class
*/
#include <td/protocol/packet/PacketVisitor.h>
#include <td/protocol/packet/Packets.h>
namespace td {
namespace protocol {
#define DeclarePacket(PacketName, ...) \
virtual void Visit(const packets::PacketName&); \
virtual void HandlePacket(const packets::PacketName&) {}
/**
* \class PacketHandler
* \brief Class used to handle packets
*/
class PacketHandler : public PacketVisitor {
public:
PacketHandler() {}
~PacketHandler() {}
DeclareAllPacket()
};
#undef DeclarePacket
} // namespace protocol
} // namespace td

View File

@@ -1,6 +1,6 @@
#pragma once
#include <td/protocol/PacketVisitor.h>
#include <td/protocol/packet/PacketVisitor.h>
namespace td {
@@ -35,7 +35,6 @@ class PacketBroadcaster : public protocol::PacketVisitor {
//////////////////
/* PacketSender */
//////////////////

View File

@@ -0,0 +1,21 @@
#pragma once
#include <memory>
#include <td/common/DataBuffer.h>
namespace td {
namespace protocol {
class Packet;
using PacketPtr = std::unique_ptr<Packet>;
namespace PacketSerializer {
DataBuffer Serialize(const Packet& a_Packet);
std::unique_ptr<Packet> Deserialize(DataBuffer& a_Data);
} // namespace PacketSerializer
} // namespace protocol
} // namespace td

View File

@@ -2,16 +2,16 @@
/**
* \file PacketVisitor.h
* \brief File containing the blitz::protocol::PacketVisitor class
* \brief File containing the td::protocol::PacketVisitor class
*/
#include <td/protocol/Packets.h>
#include <td/protocol/packet/Packets.h>
namespace td {
namespace protocol {
#define DeclarePacket(PacketName, ...) \
/** This function is called when the packet processed by PacketVisitor::Check is a PacketName */ \
/** This function is called when the packet processed by PacketVisitor::Check is a PacketName */ \
virtual void Visit(const packets::PacketName&) {}
/**

View File

@@ -6,8 +6,8 @@
*/
#include <td/common/NonCopyable.h>
#include <td/protocol/PacketData.h>
#include <td/protocol/PacketDeclare.h>
#include <td/protocol/packet/PacketData.h>
#include <td/protocol/packet/PacketDeclare.h>
namespace td {
namespace protocol {
@@ -16,6 +16,7 @@ class PacketVisitor;
/** A Packet id is 8 bits wide */
using PacketID = std::uint8_t;
using PeerID = std::uint16_t;
#define DeclarePacket(PacketName, ...) /** PacketName */ PacketName,
@@ -64,7 +65,7 @@ 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 blitz::protocol::data namespace)
* \tparam Data The structure holding the data of the packet (in td::protocol::data namespace)
*/
template <PacketType PT, typename Data>
class ConcretePacket : public Packet {
@@ -90,16 +91,16 @@ class ConcretePacket : public Packet {
// define BLITZ_INSTANCIATE_PACKETS
// define TD_INSTANCIATE_PACKETS
// before including this file
// if you want to instantiate templates
#ifdef BLITZ_INSTANCIATE_PACKETS
#ifdef TD_INSTANCIATE_PACKETS
#define DeclarePacket(PacketName, ...) \
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>; \
template class ConcretePacket<PacketType::PacketName, data::PacketName>;
using PacketName = ConcretePacket<PacketType::PacketName, pdata::PacketName>; \
template class ConcretePacket<PacketType::PacketName, pdata::PacketName>;
#else
#define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>;
using PacketName = ConcretePacket<PacketType::PacketName, pdata::PacketName>;
#endif
DeclareAllPacket()