1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef I_ACTION_EXECUTOR_H
#define I_ACTION_EXECUTOR_H
#include "Action.h"
#include "Sim/Misc/GlobalSynced.h"
#include "System/Log/ILog.h"
#include <string>
class IAction
{
protected:
IAction(const Action& action)
: action(action)
{}
virtual ~IAction() {}
public:
/**
* Returns the action arguments.
*/
const std::string& GetArgs() const { return action.extra; }
const Action& GetInnerAction() const { return action; }
private:
const Action& action;
};
template<class action_t, bool synced_v>
class IActionExecutor
{
protected:
IActionExecutor(const std::string& command,
const std::string& description, bool cheatRequired = false)
: command(command)
, description(description)
, cheatRequired(cheatRequired)
{}
virtual ~IActionExecutor() {}
public:
/**
* Returns the command string that is unique for this executor.
*/
const std::string& GetCommand() const { return command; }
/**
* Returns a human readable description of the command handled by this
* executor.
* This text will eventually be shown to end-users of the engine (gamers).
*/
const std::string& GetDescription() const { return description; }
/**
* Returns whether this executor handles synced or unsynced commands.
*/
bool IsSynced() const { return synced_v; }
/**
* Returns the command string that is unique for this executor.
*/
bool IsCheatRequired() const { return cheatRequired; }
/**
* Executes one instance of an action of this type.
* Does a few checks internally, and then calls Execute(args).
*/
bool ExecuteAction(const action_t& action) const;
protected:
void SetDescription(const std::string& description) {
this->description = description;
}
/**
* Sets a bool according to the value encoded in a string.
* The conversion works like this:
* - "" -> toggle-value
* - "0" -> false
* - "1" -> true
*/
static void SetBoolArg(bool& container, const std::string& newValue);
/**
* Logs the enabled/disabled status of a sub-system of the engine.
*/
static void LogSystemStatus(const std::string& system, bool status);
private:
/**
* Executes one instance of an action of this type.
*/
virtual bool Execute(const action_t& action) const = 0;
std::string command;
std::string description;
bool cheatRequired;
};
/*
* Because this is a template enabled class,
* the implementations have to be in the same file.
*/
template<class action_t, bool synced_v>
bool IActionExecutor<action_t, synced_v>::ExecuteAction(const action_t& action) const {
//assert(action.GetAction().command == GetCommand());
if (IsCheatRequired() && !gs->cheatEnabled) {
LOG_L(L_WARNING, "Chat command /%s (%s) cannot be executed (cheats required)!",
GetCommand().c_str(),
(IsSynced() ? "synced" : "unsynced"));
return false;
} else {
return Execute(action);
}
}
template<class action_t, bool synced_v>
void IActionExecutor<action_t, synced_v>::SetBoolArg(bool& container, const std::string& newValue) {
if (newValue.empty()) {
// toggle
container = !container;
} else {
// set
const int num = atoi(newValue.c_str());
container = (num != 0);
}
}
template<class action_t, bool synced_v>
void IActionExecutor<action_t, synced_v>::LogSystemStatus(const std::string& system, bool status) {
LOG("%s is %s!", system.c_str(), (status ? "enabled" : "disabled"));
}
#endif // I_ACTION_EXECUTOR_H
|