first commit
This commit is contained in:
53
include/sp/protocol/command/CommandData.h
Normal file
53
include/sp/protocol/command/CommandData.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// #pragma once
|
||||
|
||||
// #include <array>
|
||||
// #include <string>
|
||||
// #include <sp/Types.h>
|
||||
|
||||
// namespace sp {
|
||||
// namespace protocol {
|
||||
|
||||
// namespace cdata {
|
||||
|
||||
|
||||
// struct PlaceTower {
|
||||
// TowerType m_Type : 4;
|
||||
// PlayerID m_Placer : 4;
|
||||
// TowerCoords m_Position;
|
||||
// };
|
||||
|
||||
// struct UpgradeTower {
|
||||
// TowerID m_Tower : 12;
|
||||
// std::uint8_t m_Upgrade : 4;
|
||||
// };
|
||||
|
||||
// struct SpawnTroop {
|
||||
// EntityType m_Type : 5;
|
||||
// std::uint8_t m_Level : 3;
|
||||
// EntityCoords m_Position;
|
||||
// PlayerID m_Sender;
|
||||
// };
|
||||
|
||||
// struct UseItem {
|
||||
// ShopItem m_Item : 4;
|
||||
// PlayerID m_User : 4;
|
||||
// EntityCoords m_Position;
|
||||
// };
|
||||
|
||||
// struct TeamChange {
|
||||
// PlayerID m_Player : 7;
|
||||
// Team m_NewTeam : 1;
|
||||
// };
|
||||
|
||||
// struct PlayerJoin {
|
||||
// PlayerID m_ID;
|
||||
// std::string m_Name;
|
||||
// };
|
||||
|
||||
// struct End {};
|
||||
|
||||
// } // namespace cdata
|
||||
|
||||
|
||||
// } // namespace protocol
|
||||
// } // namespace sp
|
||||
22
include/sp/protocol/command/CommandDeclare.h
Normal file
22
include/sp/protocol/command/CommandDeclare.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace sp {
|
||||
namespace protocol {
|
||||
|
||||
/**
|
||||
* \def DeclareAllPacket
|
||||
* \brief Avoids repetitive operations on commands
|
||||
*/
|
||||
#define DeclareAllCommand() \
|
||||
DeclareCommand(End) \
|
||||
DeclareCommand(PlaceTower) \
|
||||
DeclareCommand(PlayerJoin) \
|
||||
DeclareCommand(SpawnTroop) \
|
||||
DeclareCommand(TeamChange) \
|
||||
DeclareCommand(UpgradeTower) \
|
||||
DeclareCommand(UseItem)
|
||||
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace sp
|
||||
17
include/sp/protocol/command/CommandDispatcher.h
Normal file
17
include/sp/protocol/command/CommandDispatcher.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file CommandDispatcher.h
|
||||
* \brief File containing the sp::protocol::CommandDispatcher class
|
||||
*/
|
||||
|
||||
#include <sp/protocol/Dispatcher.h>
|
||||
#include <sp/protocol/command/Commands.h>
|
||||
|
||||
namespace sp {
|
||||
namespace protocol {
|
||||
|
||||
using CommandDispatcher = Dispatcher<CommandType, CommandVisitor, Command>;
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace sp
|
||||
19
include/sp/protocol/command/CommandFactory.h
Normal file
19
include/sp/protocol/command/CommandFactory.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sp/protocol/command/Commands.h>
|
||||
|
||||
namespace sp {
|
||||
namespace protocol {
|
||||
namespace CommandFactory {
|
||||
|
||||
template <typename CommandDerived, typename = typename std::enable_if<std::is_base_of<Command, CommandDerived>::value>::type>
|
||||
std::shared_ptr<CommandDerived> CreateCommand() {
|
||||
return std::make_shared<CommandDerived>();
|
||||
}
|
||||
|
||||
const std::shared_ptr<Command>& CreateReadOnlyCommand(CommandType a_Type);
|
||||
|
||||
} // namespace CommandFactory
|
||||
} // namespace protocol
|
||||
} // namespace sp
|
||||
21
include/sp/protocol/command/CommandSerializer.h
Normal file
21
include/sp/protocol/command/CommandSerializer.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sp/common/DataBuffer.h>
|
||||
|
||||
namespace sp {
|
||||
namespace protocol {
|
||||
|
||||
class Command;
|
||||
|
||||
using CommandPtr = std::shared_ptr<Command>;
|
||||
|
||||
namespace CommandSerializer {
|
||||
|
||||
DataBuffer Serialize(const Command& a_Command);
|
||||
|
||||
std::shared_ptr<Command> Deserialize(DataBuffer& a_Data);
|
||||
|
||||
} // namespace CommandSerializer
|
||||
} // namespace protocol
|
||||
} // namespace sp
|
||||
39
include/sp/protocol/command/CommandVisitor.h
Normal file
39
include/sp/protocol/command/CommandVisitor.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file CommandVisitor.h
|
||||
* \brief File containing the sp::protocol::CommandVisitor class
|
||||
*/
|
||||
|
||||
#include <sp/protocol/command/Commands.h>
|
||||
|
||||
namespace sp {
|
||||
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 sp
|
||||
111
include/sp/protocol/command/Commands.h
Normal file
111
include/sp/protocol/command/Commands.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file Commands.h
|
||||
* \brief File containing the definitions of the lockstep commands
|
||||
*/
|
||||
|
||||
#include <sp/Types.h>
|
||||
#include <sp/common/NonCopyable.h>
|
||||
#include <sp/protocol/command/CommandData.h>
|
||||
#include <sp/protocol/command/CommandDeclare.h>
|
||||
#include <memory>
|
||||
|
||||
namespace sp {
|
||||
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 sp::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 SP_INSTANCIATE_COMMANDS
|
||||
// before including this file
|
||||
// if you want to instantiate templates
|
||||
#ifdef SP_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
|
||||
|
||||
using LockStep = std::vector<std::shared_ptr<protocol::Command>>;
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace sp
|
||||
Reference in New Issue
Block a user