gros push encore
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ build/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|
||||||
|
.vscode
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <fpm/fpm.hpp>
|
#include <fpm/fixed.hpp>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@@ -63,4 +63,6 @@ struct EntityCoords {
|
|||||||
fpm::fixed_16_16 y;
|
fpm::fixed_16_16 y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using PeerID = std::uint16_t;
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
286
include/td/common/DataBuffer.h
Normal file
286
include/td/common/DataBuffer.h
Normal 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
|
||||||
25
include/td/common/NonCopyable.h
Normal file
25
include/td/common/NonCopyable.h
Normal 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
|
||||||
@@ -2,57 +2,60 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \file PacketDispatcher.h
|
* \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/common/NonCopyable.h>
|
||||||
#include <td/protocol/Packets.h>
|
#include <td/protocol/packet/Packets.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
|
|
||||||
class PacketHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class PacketDispatcher
|
* \class Dispatcher
|
||||||
* \brief Class used to dispatch packets
|
* \brief Class used to dispatch things
|
||||||
*/
|
*/
|
||||||
class PacketDispatcher : private NonCopyable {
|
template <typename T_Enum, typename T_Handler, typename T>
|
||||||
|
class Dispatcher : private NonCopyable {
|
||||||
private:
|
private:
|
||||||
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
|
std::map<T_Enum, std::vector<T_Handler*>> m_Handlers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \brief Constructor
|
* \brief Constructor
|
||||||
*/
|
*/
|
||||||
PacketDispatcher() {}
|
Dispatcher() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Dispatch a packet
|
* \brief Dispatch a packet
|
||||||
* \param packet The packet to dispatch
|
* \param packet The packet to dispatch
|
||||||
*/
|
*/
|
||||||
void Dispatch(const Packet& packet);
|
void Dispatch(const T& packet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Register a packet handler
|
* \brief Register a packet handler
|
||||||
* \param type The packet type
|
* \param type The packet type
|
||||||
* \param handler The packet handler
|
* \param handler The packet handler
|
||||||
*/
|
*/
|
||||||
void RegisterHandler(PacketType type, PacketHandler& handler);
|
void RegisterHandler(T_Enum type, T_Handler& handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Unregister a packet handler
|
* \brief Unregister a packet handler
|
||||||
* \param type The packet type
|
* \param type The packet type
|
||||||
* \param handler The packet handler
|
* \param handler The packet handler
|
||||||
*/
|
*/
|
||||||
void UnregisterHandler(PacketType type, PacketHandler& handler);
|
void UnregisterHandler(T_Enum type, T_Handler& handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Unregister a packet handler
|
* \brief Unregister a packet handler
|
||||||
* \param handler The packet handler
|
* \param handler The packet handler
|
||||||
*/
|
*/
|
||||||
void UnregisterHandler(PacketHandler& handler);
|
void UnregisterHandler(T_Handler& handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|
||||||
|
#include "Dispatcher.inl"
|
||||||
38
include/td/protocol/Dispatcher.inl
Normal file
38
include/td/protocol/Dispatcher.inl
Normal 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
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <td/Types.h>
|
#include <td/Types.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
|
|
||||||
|
#define LOCKSTEP_BUFFER_SIZE 10
|
||||||
|
|
||||||
|
struct LockStepCommand {};
|
||||||
|
|
||||||
struct LockStep {
|
struct LockStep {
|
||||||
std::uint8_t m_CommandNumber;
|
std::uint8_t m_CommandNumber;
|
||||||
@@ -13,11 +17,11 @@ struct LockStep {
|
|||||||
|
|
||||||
struct LockSteps {
|
struct LockSteps {
|
||||||
std::uint16_t m_FirstFrameNumber;
|
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 {
|
struct PlaceTower {
|
||||||
@@ -49,9 +53,12 @@ struct TeamChange {
|
|||||||
Team m_NewTeam : 1;
|
Team m_NewTeam : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlayerJoin {
|
||||||
|
PlayerID m_ID;
|
||||||
|
std::string m_Name;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cdata
|
||||||
} // namespace data
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
|
|||||||
21
include/td/protocol/command/CommandDeclare.h
Normal file
21
include/td/protocol/command/CommandDeclare.h
Normal 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
|
||||||
18
include/td/protocol/command/CommandDispatcher.h
Normal file
18
include/td/protocol/command/CommandDispatcher.h
Normal 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
|
||||||
19
include/td/protocol/command/CommandFactory.h
Normal file
19
include/td/protocol/command/CommandFactory.h
Normal 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
|
||||||
33
include/td/protocol/command/CommandHandler.h
Normal file
33
include/td/protocol/command/CommandHandler.h
Normal 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
|
||||||
21
include/td/protocol/command/CommandSerializer.h
Normal file
21
include/td/protocol/command/CommandSerializer.h
Normal 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
|
||||||
39
include/td/protocol/command/CommandVisitor.h
Normal file
39
include/td/protocol/command/CommandVisitor.h
Normal 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
|
||||||
108
include/td/protocol/command/Commands.h
Normal file
108
include/td/protocol/command/Commands.h
Normal 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
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/common/Types.h>
|
#include <td/Types.h>
|
||||||
#include <godot_cpp/variant/string.hpp>
|
|
||||||
#include <godot_cpp/variant/vector3.hpp>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
@@ -10,13 +8,13 @@ namespace protocol {
|
|||||||
|
|
||||||
struct PlayerInfo {
|
struct PlayerInfo {
|
||||||
PlayerID m_PlayerId;
|
PlayerID m_PlayerId;
|
||||||
godot::String m_PlayerName;
|
std::string m_PlayerName;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace data {
|
namespace pdata {
|
||||||
|
|
||||||
struct PlayerLogin {
|
struct PlayerLogin {
|
||||||
godot::String m_PlayerName;
|
std::string m_PlayerName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UpdateHealth {
|
struct UpdateHealth {
|
||||||
@@ -56,23 +54,23 @@ struct KeepAlive {
|
|||||||
struct Disconnect {};
|
struct Disconnect {};
|
||||||
|
|
||||||
struct ChatMessage {
|
struct ChatMessage {
|
||||||
godot::String m_Text;
|
std::string m_Text;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerPositionAndRotation {
|
struct PlayerPositionAndRotation {
|
||||||
PlayerID m_Player;
|
PlayerID m_Player;
|
||||||
godot::Vector3 m_Position;
|
// godot::Vector3 m_Position;
|
||||||
godot::Vector3 m_Rotation;
|
// godot::Vector3 m_Rotation;
|
||||||
godot::Vector3 m_Velocity;
|
// godot::Vector3 m_Velocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerShoot {
|
struct PlayerShoot {
|
||||||
PlayerID m_Sender;
|
PlayerID m_Sender;
|
||||||
godot::Vector3 m_Position;
|
// godot::Vector3 m_Position;
|
||||||
godot::Vector3 m_Rotation;
|
// godot::Vector3 m_Rotation;
|
||||||
godot::Vector3 m_Velocity;
|
// godot::Vector3 m_Velocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace data
|
} // namespace pdata
|
||||||
} // namespace protocol
|
} // namespace protocol
|
||||||
} // namespace td
|
} // namespace td
|
||||||
18
include/td/protocol/packet/PacketDispatcher.h
Normal file
18
include/td/protocol/packet/PacketDispatcher.h
Normal 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
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/protocol/Packets.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <td/protocol/packet/Packets.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
33
include/td/protocol/packet/PacketHandler.h
Normal file
33
include/td/protocol/packet/PacketHandler.h
Normal 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
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/protocol/PacketVisitor.h>
|
#include <td/protocol/packet/PacketVisitor.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@@ -35,7 +35,6 @@ class PacketBroadcaster : public protocol::PacketVisitor {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
/* PacketSender */
|
/* PacketSender */
|
||||||
//////////////////
|
//////////////////
|
||||||
21
include/td/protocol/packet/PacketSerializer.h
Normal file
21
include/td/protocol/packet/PacketSerializer.h
Normal 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
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \file PacketVisitor.h
|
* \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 td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <td/common/NonCopyable.h>
|
#include <td/common/NonCopyable.h>
|
||||||
#include <td/protocol/PacketData.h>
|
#include <td/protocol/packet/PacketData.h>
|
||||||
#include <td/protocol/PacketDeclare.h>
|
#include <td/protocol/packet/PacketDeclare.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
@@ -16,6 +16,7 @@ class PacketVisitor;
|
|||||||
|
|
||||||
/** A Packet id is 8 bits wide */
|
/** A Packet id is 8 bits wide */
|
||||||
using PacketID = std::uint8_t;
|
using PacketID = std::uint8_t;
|
||||||
|
using PeerID = std::uint16_t;
|
||||||
|
|
||||||
#define DeclarePacket(PacketName, ...) /** PacketName */ PacketName,
|
#define DeclarePacket(PacketName, ...) /** PacketName */ PacketName,
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ namespace packets {
|
|||||||
* \class ConcretePacket
|
* \class ConcretePacket
|
||||||
* \brief A Packet associated with an id and holding data
|
* \brief A Packet associated with an id and holding data
|
||||||
* \tparam PT The packet type
|
* \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>
|
template <PacketType PT, typename Data>
|
||||||
class ConcretePacket : public Packet {
|
class ConcretePacket : public Packet {
|
||||||
@@ -90,16 +91,16 @@ class ConcretePacket : public Packet {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// define BLITZ_INSTANCIATE_PACKETS
|
// define TD_INSTANCIATE_PACKETS
|
||||||
// before including this file
|
// before including this file
|
||||||
// if you want to instantiate templates
|
// if you want to instantiate templates
|
||||||
#ifdef BLITZ_INSTANCIATE_PACKETS
|
#ifdef TD_INSTANCIATE_PACKETS
|
||||||
#define DeclarePacket(PacketName, ...) \
|
#define DeclarePacket(PacketName, ...) \
|
||||||
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>; \
|
using PacketName = ConcretePacket<PacketType::PacketName, pdata::PacketName>; \
|
||||||
template class ConcretePacket<PacketType::PacketName, data::PacketName>;
|
template class ConcretePacket<PacketType::PacketName, pdata::PacketName>;
|
||||||
#else
|
#else
|
||||||
#define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \
|
#define DeclarePacket(PacketName, ...) /** Defines the PacketName packet */ \
|
||||||
using PacketName = ConcretePacket<PacketType::PacketName, data::PacketName>;
|
using PacketName = ConcretePacket<PacketType::PacketName, pdata::PacketName>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeclareAllPacket()
|
DeclareAllPacket()
|
||||||
19
src/main.cpp
19
src/main.cpp
@@ -1,6 +1,23 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
// #include <td/protocol/packet/PacketVisitor.h>
|
||||||
|
#include <td/protocol/command/CommandDispatcher.h>
|
||||||
|
#include <td/protocol/command/CommandFactory.h>
|
||||||
|
#include <td/protocol/command/CommandHandler.h>
|
||||||
|
#include <td/protocol/command/CommandSerializer.h>
|
||||||
|
#include <td/protocol/command/CommandVisitor.h>
|
||||||
|
|
||||||
|
class Test : public td::protocol::CommandVisitor {};
|
||||||
|
|
||||||
|
class Test2 : public td::protocol::CommandHandler {};
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
std::cout << "hello world!" << std::endl;
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/td/protocol/command/Commands.cpp
Normal file
18
src/td/protocol/command/Commands.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#define TD_INSTANCIATE_COMMANDS
|
||||||
|
#include <td/protocol/command/Commands.h>
|
||||||
|
|
||||||
|
#include <td/protocol/command/CommandVisitor.h>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
namespace protocol {
|
||||||
|
|
||||||
|
template <CommandType CT, typename Data>
|
||||||
|
commands::ConcreteCommand<CT, Data>::ConcreteCommand(const CommandDataType& a_Data) : m_Data(a_Data) {}
|
||||||
|
|
||||||
|
template <CommandType CT, typename Data>
|
||||||
|
void commands::ConcreteCommand<CT, Data>::Accept(CommandVisitor& a_Visitor) const {
|
||||||
|
a_Visitor.Visit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace td
|
||||||
Reference in New Issue
Block a user