From 77317df56c3b93367a0e15b870ae5cb9746b29f1 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Mon, 7 Oct 2024 19:48:36 +0200 Subject: [PATCH] gros push encore --- .gitignore | 1 + include/td/Types.h | 4 +- include/td/common/DataBuffer.h | 286 ++++++++++++++++++ include/td/common/NonCopyable.h | 25 ++ .../{PacketDispatcher.h => Dispatcher.h} | 29 +- include/td/protocol/Dispatcher.inl | 38 +++ include/td/protocol/PacketHandler.h | 34 --- include/td/protocol/PacketSerializer.h | 20 -- include/td/protocol/command/CommandData.h | 15 +- include/td/protocol/command/CommandDeclare.h | 21 ++ .../td/protocol/command/CommandDispatcher.h | 18 ++ include/td/protocol/command/CommandFactory.h | 19 ++ include/td/protocol/command/CommandHandler.h | 33 ++ .../td/protocol/command/CommandSerializer.h | 21 ++ include/td/protocol/command/CommandVisitor.h | 39 +++ include/td/protocol/command/Commands.h | 108 +++++++ include/td/protocol/{ => packet}/PacketData.h | 26 +- .../td/protocol/{ => packet}/PacketDeclare.h | 0 include/td/protocol/packet/PacketDispatcher.h | 18 ++ .../td/protocol/{ => packet}/PacketFactory.h | 6 +- include/td/protocol/packet/PacketHandler.h | 33 ++ .../td/protocol/{ => packet}/PacketSender.h | 3 +- include/td/protocol/packet/PacketSerializer.h | 21 ++ .../td/protocol/{ => packet}/PacketVisitor.h | 6 +- include/td/protocol/{ => packet}/Packets.h | 17 +- src/main.cpp | 21 +- src/td/protocol/command/Commands.cpp | 18 ++ xmake.lua | 2 +- 28 files changed, 777 insertions(+), 105 deletions(-) create mode 100644 include/td/common/DataBuffer.h create mode 100644 include/td/common/NonCopyable.h rename include/td/protocol/{PacketDispatcher.h => Dispatcher.h} (54%) create mode 100644 include/td/protocol/Dispatcher.inl delete mode 100644 include/td/protocol/PacketHandler.h delete mode 100644 include/td/protocol/PacketSerializer.h create mode 100644 include/td/protocol/command/CommandDeclare.h create mode 100644 include/td/protocol/command/CommandDispatcher.h create mode 100644 include/td/protocol/command/CommandFactory.h create mode 100644 include/td/protocol/command/CommandHandler.h create mode 100644 include/td/protocol/command/CommandSerializer.h create mode 100644 include/td/protocol/command/CommandVisitor.h create mode 100644 include/td/protocol/command/Commands.h rename include/td/protocol/{ => packet}/PacketData.h (65%) rename include/td/protocol/{ => packet}/PacketDeclare.h (100%) create mode 100644 include/td/protocol/packet/PacketDispatcher.h rename include/td/protocol/{ => packet}/PacketFactory.h (58%) create mode 100644 include/td/protocol/packet/PacketHandler.h rename include/td/protocol/{ => packet}/PacketSender.h (95%) create mode 100644 include/td/protocol/packet/PacketSerializer.h rename include/td/protocol/{ => packet}/PacketVisitor.h (82%) rename include/td/protocol/{ => packet}/Packets.h (80%) create mode 100644 src/td/protocol/command/Commands.cpp diff --git a/.gitignore b/.gitignore index 1521057..fb11540 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ build/ .DS_Store +.vscode \ No newline at end of file diff --git a/include/td/Types.h b/include/td/Types.h index 2b66115..4a2c6d0 100644 --- a/include/td/Types.h +++ b/include/td/Types.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace td { @@ -63,4 +63,6 @@ struct EntityCoords { fpm::fixed_16_16 y; }; +using PeerID = std::uint16_t; + } // namespace td diff --git a/include/td/common/DataBuffer.h b/include/td/common/DataBuffer.h new file mode 100644 index 0000000..b2fcc89 --- /dev/null +++ b/include/td/common/DataBuffer.h @@ -0,0 +1,286 @@ +#pragma once + +/** + * \file DataBuffer.h + * \brief File containing the td::DataBuffer class + */ + +#include +#include +#include +#include +#include +#include + +namespace td { + +/** + * \class DataBuffer + * \brief Class used to manipulate memory + */ +class DataBuffer { + private: + typedef std::vector 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 + 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 + 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 + DataBuffer& operator>>(T& data) { + assert(m_ReadOffset + sizeof(T) <= GetSize()); + data = *(reinterpret_cast(&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(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(m_Buffer.data()) + m_ReadOffset) + 1; // including null character + str.resize(stringSize); + std::copy(m_Buffer.begin() + static_cast(m_ReadOffset), + m_Buffer.begin() + static_cast(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(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(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(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 diff --git a/include/td/common/NonCopyable.h b/include/td/common/NonCopyable.h new file mode 100644 index 0000000..43cc2f7 --- /dev/null +++ b/include/td/common/NonCopyable.h @@ -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 diff --git a/include/td/protocol/PacketDispatcher.h b/include/td/protocol/Dispatcher.h similarity index 54% rename from include/td/protocol/PacketDispatcher.h rename to include/td/protocol/Dispatcher.h index 225b777..037ce03 100644 --- a/include/td/protocol/PacketDispatcher.h +++ b/include/td/protocol/Dispatcher.h @@ -2,57 +2,60 @@ /** * \file PacketDispatcher.h - * \brief File containing the blitz::protocol::PacketDispatcher class + * \brief File containing the td::protocol::PacketDispatcher class */ #include -#include +#include #include 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 +class Dispatcher : private NonCopyable { private: - std::map> m_Handlers; + std::map> 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" \ No newline at end of file diff --git a/include/td/protocol/Dispatcher.inl b/include/td/protocol/Dispatcher.inl new file mode 100644 index 0000000..d807f9b --- /dev/null +++ b/include/td/protocol/Dispatcher.inl @@ -0,0 +1,38 @@ +#pragma once + +namespace td { +namespace protocol { + +template +void Dispatcher::Dispatch(const T& packet) { + T_Enum type = packet.GetType(); + for (auto* handler : m_Handlers[type]) + handler->Check(packet); +} + +template +void Dispatcher::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 +void Dispatcher::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 +void Dispatcher::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 diff --git a/include/td/protocol/PacketHandler.h b/include/td/protocol/PacketHandler.h deleted file mode 100644 index f98680a..0000000 --- a/include/td/protocol/PacketHandler.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -/** - * \file PacketHandler.h - * \brief File containing the blitz::protocol::PacketHandler class - */ - -#include -#include - -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 \ No newline at end of file diff --git a/include/td/protocol/PacketSerializer.h b/include/td/protocol/PacketSerializer.h deleted file mode 100644 index 5172af7..0000000 --- a/include/td/protocol/PacketSerializer.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace td { -namespace protocol { - -using PacketPtr = std::unique_ptr; - -namespace PacketSerializer { - -godot::PackedByteArray Serialize(const Packet& a_Packet); - -std::unique_ptr Deserialize(godot::PackedByteArray& a_Data); - -} -} // namespace protocol -} // namespace td diff --git a/include/td/protocol/command/CommandData.h b/include/td/protocol/command/CommandData.h index e26511a..f385112 100644 --- a/include/td/protocol/command/CommandData.h +++ b/include/td/protocol/command/CommandData.h @@ -1,10 +1,14 @@ #pragma once +#include #include 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 m_LockSteps; + std::array 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 diff --git a/include/td/protocol/command/CommandDeclare.h b/include/td/protocol/command/CommandDeclare.h new file mode 100644 index 0000000..4cf6fde --- /dev/null +++ b/include/td/protocol/command/CommandDeclare.h @@ -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 \ No newline at end of file diff --git a/include/td/protocol/command/CommandDispatcher.h b/include/td/protocol/command/CommandDispatcher.h new file mode 100644 index 0000000..ca3534f --- /dev/null +++ b/include/td/protocol/command/CommandDispatcher.h @@ -0,0 +1,18 @@ +#pragma once + +/** + * \file CommandDispatcher.h + * \brief File containing the td::protocol::CommandDispatcher class + */ + +#include + +namespace td { +namespace protocol { + +class CommandHandler; + +using CommandDispatcher = Dispatcher; + +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/command/CommandFactory.h b/include/td/protocol/command/CommandFactory.h new file mode 100644 index 0000000..e758b2c --- /dev/null +++ b/include/td/protocol/command/CommandFactory.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace td { +namespace protocol { +namespace CommandFactory { + +template ::value>::type> +std::unique_ptr CreateCommand() { + return std::make_unique(); +} + +const std::unique_ptr& CreateReadOnlyCommand(CommandType a_Type); + +} // namespace CommandFactory +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/command/CommandHandler.h b/include/td/protocol/command/CommandHandler.h new file mode 100644 index 0000000..8d8e09d --- /dev/null +++ b/include/td/protocol/command/CommandHandler.h @@ -0,0 +1,33 @@ +#pragma once + +/** + * \file CommandHandler.h + * \brief File containing the td::protocol::CommandHandler class + */ + +#include +#include + +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 \ No newline at end of file diff --git a/include/td/protocol/command/CommandSerializer.h b/include/td/protocol/command/CommandSerializer.h new file mode 100644 index 0000000..5b9b6e6 --- /dev/null +++ b/include/td/protocol/command/CommandSerializer.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace td { +namespace protocol { + +class Command; + +using CommandPtr = std::unique_ptr; + +namespace CommandSerializer { + +DataBuffer Serialize(const Command& a_Command); + +std::unique_ptr Deserialize(DataBuffer& a_Data); + +} // namespace CommandSerializer +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/command/CommandVisitor.h b/include/td/protocol/command/CommandVisitor.h new file mode 100644 index 0000000..987ffd3 --- /dev/null +++ b/include/td/protocol/command/CommandVisitor.h @@ -0,0 +1,39 @@ +#pragma once + +/** + * \file CommandVisitor.h + * \brief File containing the td::protocol::CommandVisitor class + */ + +#include + +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 diff --git a/include/td/protocol/command/Commands.h b/include/td/protocol/command/Commands.h new file mode 100644 index 0000000..65495d2 --- /dev/null +++ b/include/td/protocol/command/Commands.h @@ -0,0 +1,108 @@ +#pragma once + +/** + * \file Commands.h + * \brief File containing the definitions of the lockstep commands + */ + +#include +#include +#include +#include + +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 +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; \ + template class ConcreteCommand; +#else +#define DeclareCommand(CommandName, ...) /** Defines the CommandName Command */ \ + using CommandName = ConcreteCommand; +#endif + +DeclareAllCommand() + +#undef DeclareCommand + +} // namespace commands + +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/PacketData.h b/include/td/protocol/packet/PacketData.h similarity index 65% rename from include/td/protocol/PacketData.h rename to include/td/protocol/packet/PacketData.h index 98c28f8..8f86352 100644 --- a/include/td/protocol/PacketData.h +++ b/include/td/protocol/packet/PacketData.h @@ -1,8 +1,6 @@ #pragma once -#include -#include -#include +#include #include 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 diff --git a/include/td/protocol/PacketDeclare.h b/include/td/protocol/packet/PacketDeclare.h similarity index 100% rename from include/td/protocol/PacketDeclare.h rename to include/td/protocol/packet/PacketDeclare.h diff --git a/include/td/protocol/packet/PacketDispatcher.h b/include/td/protocol/packet/PacketDispatcher.h new file mode 100644 index 0000000..627e8f4 --- /dev/null +++ b/include/td/protocol/packet/PacketDispatcher.h @@ -0,0 +1,18 @@ +#pragma once + +/** + * \file PacketDispatcher.h + * \brief File containing the td::protocol::PacketDispatcher class + */ + +#include + +namespace td { +namespace protocol { + +class PacketHandler; + +using PacketDispatcher = Dispatcher; + +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/PacketFactory.h b/include/td/protocol/packet/PacketFactory.h similarity index 58% rename from include/td/protocol/PacketFactory.h rename to include/td/protocol/packet/PacketFactory.h index 5b65c8d..0f346ad 100644 --- a/include/td/protocol/PacketFactory.h +++ b/include/td/protocol/packet/PacketFactory.h @@ -1,15 +1,15 @@ #pragma once -#include #include +#include namespace td { namespace protocol { namespace PacketFactory { -template::value>::type> +template ::value>::type> std::unique_ptr CreatePacket() { - return std::make_unique(); + return std::make_unique(); } const std::unique_ptr& CreateReadOnlyPacket(PacketType a_Type); diff --git a/include/td/protocol/packet/PacketHandler.h b/include/td/protocol/packet/PacketHandler.h new file mode 100644 index 0000000..8c3b671 --- /dev/null +++ b/include/td/protocol/packet/PacketHandler.h @@ -0,0 +1,33 @@ +#pragma once + +/** + * \file PacketHandler.h + * \brief File containing the td::protocol::PacketHandler class + */ + +#include +#include + +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 \ No newline at end of file diff --git a/include/td/protocol/PacketSender.h b/include/td/protocol/packet/PacketSender.h similarity index 95% rename from include/td/protocol/PacketSender.h rename to include/td/protocol/packet/PacketSender.h index e190dd8..e25c85d 100644 --- a/include/td/protocol/PacketSender.h +++ b/include/td/protocol/packet/PacketSender.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace td { @@ -35,7 +35,6 @@ class PacketBroadcaster : public protocol::PacketVisitor { - ////////////////// /* PacketSender */ ////////////////// diff --git a/include/td/protocol/packet/PacketSerializer.h b/include/td/protocol/packet/PacketSerializer.h new file mode 100644 index 0000000..fd71ca2 --- /dev/null +++ b/include/td/protocol/packet/PacketSerializer.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace td { +namespace protocol { + +class Packet; + +using PacketPtr = std::unique_ptr; + +namespace PacketSerializer { + +DataBuffer Serialize(const Packet& a_Packet); + +std::unique_ptr Deserialize(DataBuffer& a_Data); + +} // namespace PacketSerializer +} // namespace protocol +} // namespace td diff --git a/include/td/protocol/PacketVisitor.h b/include/td/protocol/packet/PacketVisitor.h similarity index 82% rename from include/td/protocol/PacketVisitor.h rename to include/td/protocol/packet/PacketVisitor.h index 60dbd1b..d2a6799 100644 --- a/include/td/protocol/PacketVisitor.h +++ b/include/td/protocol/packet/PacketVisitor.h @@ -2,16 +2,16 @@ /** * \file PacketVisitor.h - * \brief File containing the blitz::protocol::PacketVisitor class + * \brief File containing the td::protocol::PacketVisitor class */ -#include +#include 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&) {} /** diff --git a/include/td/protocol/Packets.h b/include/td/protocol/packet/Packets.h similarity index 80% rename from include/td/protocol/Packets.h rename to include/td/protocol/packet/Packets.h index b039ffd..24599fe 100644 --- a/include/td/protocol/Packets.h +++ b/include/td/protocol/packet/Packets.h @@ -6,8 +6,8 @@ */ #include -#include -#include +#include +#include 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 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; \ - template class ConcretePacket; + using PacketName = ConcretePacket; \ + template class ConcretePacket; #else #define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \ - using PacketName = ConcretePacket; + using PacketName = ConcretePacket; #endif DeclareAllPacket() diff --git a/src/main.cpp b/src/main.cpp index 7c775d2..c27958c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,23 @@ #include +// #include +#include +#include +#include +#include +#include + +class Test : public td::protocol::CommandVisitor {}; + +class Test2 : public td::protocol::CommandHandler {}; int main(int argc, char** argv) { - std::cout << "hello world!" << std::endl; - return 0; + // Test visitor; + // td::protocol::packets::ChatMessage chat{{"coucou"}}; + // visitor.Check(chat); + + + td::protocol::commands::UpgradeTower com{{1, 2}}; + std::cout << (unsigned)com.GetType() << std::endl; + td::protocol::CommandDispatcher disptacher; + return 0; } diff --git a/src/td/protocol/command/Commands.cpp b/src/td/protocol/command/Commands.cpp new file mode 100644 index 0000000..09f575e --- /dev/null +++ b/src/td/protocol/command/Commands.cpp @@ -0,0 +1,18 @@ +#define TD_INSTANCIATE_COMMANDS +#include + +#include + +namespace td { +namespace protocol { + +template +commands::ConcreteCommand::ConcreteCommand(const CommandDataType& a_Data) : m_Data(a_Data) {} + +template +void commands::ConcreteCommand::Accept(CommandVisitor& a_Visitor) const { + a_Visitor.Visit(*this); +} + +} // namespace protocol +} // namespace td \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 258e5a7..18651fe 100644 --- a/xmake.lua +++ b/xmake.lua @@ -5,7 +5,7 @@ add_requires("fpm") target("Tower-Defense2") add_includedirs("include") set_kind("binary") - add_files("src/*.cpp") + add_files("src/**.cpp") add_packages("fpm") --