109 lines
2.5 KiB
C++
109 lines
2.5 KiB
C++
#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
|