/*! * @file shell_command.h * Definition of a on-screen-shell */ #ifndef _SHELL_COMMAND_H #define _SHELL_COMMAND_H #include "base_object.h" #include "helper_functions.h" #include "substring.h" #include "functor_list.h" #include #define SHELL_COMMAND_MAX_SIZE //!< The maximum size of a Shell Command // FORWARD DECLARATION template class tList; /** * an easy to use Macro to create a Command * @param command the name of the command (without "" around the string) * @param class the name of the class to apply this command to (without the "" around the string) * @param function the function to call * * MEANING: * ShellCommandBase* someUniqueVarName = * ShellCommand::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall); * * In the Shell you would call this Command using: * $ ClassName [ObjectName] commandNameInShell [parameters] */ #define SHELL_COMMAND(command, class, function) \ ShellCommandBase* shell_command_##class##_##command = ShellCommand::registerCommand(#command, #class, &class::function) //////////////// // BASE CLASS // //////////////// class ShellCommandBase; //! A class to hold all Classes that have (once) registered Commands. class ShellCommandClass : public BaseObject { friend class ShellCommandBase; public: static const tList* getCommandClassList() { return ShellCommandClass::commandClassList; }; static ShellCommandClass* getCommandClass(const char* className); static void unregisterAllCommands(); private: ShellCommandClass(const char* className); ~ShellCommandClass(); static const ShellCommandClass* isRegistered(const char* className); static void initCommandClassList(); private: const char* className; //!< The Name of the Class. This should match the ClassName of the Commands Class. long classID; //!< The classID of this Class tList* commandList; //!< A list of Commands from this Class static tList* commandClassList; //!< A list of Classes }; //! a baseClass for all possible ShellCommands class ShellCommandBase : public BaseObject { friend class ShellCommandClass; public: static bool execute (const char* executionString); ShellCommandBase* describe(const char* description); /** @returns the CommandList of the Shell */ static void unregisterCommand(const char* commandName, const char* className); static void debug(); protected: ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...); ~ShellCommandBase(); static bool isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...); static const char* paramToString(long parameter); void debugDyn(); private: /** executes a Command @param object the object to apply this to @param parameters the parameters the command takes */ virtual void executeCommand (BaseObject* object, const char* parameters) = NULL; protected: void* functionPointer; //!< The pointeer to the function of the Class (or static pointer if ClassID == CL_NULL ) unsigned int paramCount; //!< the count of parameters. unsigned int* parameters; //!< Parameters the function of this Command takes. char* defaultStrings[FUNCTOR_MAX_ARGUMENTS];//!< A list of default Strings stored. int defaultInts[FUNCTOR_MAX_ARGUMENTS]; //!< A list of default Ints stored. float defaultFloats[FUNCTOR_MAX_ARGUMENTS]; //!< A list of default Floats stored. bool defaultBools[FUNCTOR_MAX_ARGUMENTS]; //!< A list of default Bools stored. private: ShellCommandClass* shellClass; //!< A Pointer to the Shell-Class this Command belongs to. const char* description; //!< A description for this commnand. (initially NULL). Assigned with (create)->describe("blablabla"); }; /////////////////////////////////////////////////// /////////////////////////////////////////////////// /////////////////////// // MACRO DEFINITIONS // /////////////////////// //! where to chek for default BOOL values #define l_BOOL_DEFGRAB(i) this->defaultBools[i] //! where to chek for default INT values #define l_INT_DEFGRAB(i) this->defaultInts[i] //! where to chek for default UINT values #define l_UINT_DEFGRAB(i) (unsigned int)this->defaultInts[i] //! where to chek for default LONG values #define l_LONG_DEFGRAB(i) (long)this->defaultInts[i] //! where to chek for default FLOAT values #define l_FLOAT_DEFGRAB(i) this->defaultFloats[i] //! where to chek for default STRING values #define l_STRING_DEFGRAB(i) this->defaultStrings[i] ////////////////////////// // COMMAND REGISTRATION // ////////////////////////// //! registers a command without any parameters #define ShellCommandRegister0() \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)()) \ { \ if (isRegistered(commandName, className, 0)== true) \ return NULL; \ return new ShellCommand(commandName, className, function); \ } //! registers a command with 1 parameter #define ShellCommandRegister1(t1) \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE), t1##_TYPE d1 = t1##_DEFAULT) \ { \ if (isRegistered(commandName, className, 1, t1##_PARAM)== true) \ return NULL; \ return new ShellCommand(commandName, className, function, d1); \ } //! registers a command with 2 parameters #define ShellCommandRegister2(t1,t2) \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT) \ { \ if (isRegistered(commandName, className, 2, t1##_PARAM, t2##_PARAM)== true) \ return NULL; \ return new ShellCommand(commandName, className, function, d1, d2); \ } //! registers a command with 3 parameters #define ShellCommandRegister3(t1,t2,t3) \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT) \ { \ if (isRegistered(commandName, className, 3, t1##_PARAM, t2##_PARAM, t3##_PARAM)== true) \ return NULL; \ return new ShellCommand(commandName, className, function, d1, d2, d3); \ } //! registers a command with 4 parameters #define ShellCommandRegister4(t1,t2,t3,t4) \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT, t4##_TYPE d4 = t4##_DEFAULT) \ { \ if (isRegistered(commandName, className, 4, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM)== true) \ return NULL; \ return new ShellCommand(commandName, className, function, d1, d2, d3, d4); \ } //! registers a command with 5 parameters #define ShellCommandRegister5(t1,t2,t3,t4,t5) \ static ShellCommand* registerCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT, t4##_TYPE d4 = t4##_DEFAULT, t5##_TYPE d5 = t5##_DEFAULT) \ { \ if (isRegistered(commandName, className, 5, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM, t5##_PARAM)== true) \ return NULL; \ return new ShellCommand(commandName, className, function, d1, d2, d3, d4, d5); \ } ////////////////// // CONSTRUCTORS // ///////////////// //! creates a command that takes no parameters #define ShellCommandConstructor0() \ void (T::*functionPointer_0)(); \ ShellCommand(const char* commandName, const char* className, void (T::*function)()) \ : ShellCommandBase(commandName, className, 0) \ { \ this->functionPointer_0 = function; \ } //! creates a command that takes one parameter #define ShellCommandConstructor1(t1) \ void (T::*functionPointer_1_##t1)(t1##_TYPE); \ ShellCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE), t1##_TYPE d1) \ : ShellCommandBase(commandName, className, 1, t1##_PARAM, d1) \ { \ this->functionPointer_1_##t1 = function; \ } //! creates a command that takes two parameters #define ShellCommandConstructor2(t1,t2) \ void (T::*functionPointer_2_##t1##_##t2)(t1##_TYPE, t2##_TYPE); \ ShellCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE), t1##_TYPE d1, t2##_TYPE d2) \ : ShellCommandBase(commandName, className, 2, t1##_PARAM, d1, t2##_PARAM, d2) \ { \ this->functionPointer_2_##t1##_##t2 = function; \ } //! creates a command that takes three parameter #define ShellCommandConstructor3(t1,t2,t3) \ void (T::*functionPointer_3_##t1##_##t2##_##t3)(t1##_TYPE, t2##_TYPE, t3##_TYPE); \ ShellCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3) \ : ShellCommandBase(commandName, className, 3, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3) \ { \ this->functionPointer_3_##t1##_##t2##_##t3 = function; \ } //! creates a command that takes four parameter #define ShellCommandConstructor4(t1,t2,t3,t4) \ void (T::*functionPointer_4_##t1##_##t2##_##t3##_##t4)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE); \ ShellCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3, t4##_TYPE d4) \ : ShellCommandBase(commandName, className, 4, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3, t4##_PARAM, d4) \ { \ this->functionPointer_4_##t1##_##t2##_##t3##_##t4 = function; \ } //! creates a command that takes five parameter #define ShellCommandConstructor5(t1,t2,t3,t4,t5) \ void (T::*functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE); \ ShellCommand(const char* commandName, const char* className, void (T::*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3, t4##_TYPE d4, t5##_TYPE d5) \ : ShellCommandBase(commandName, className, 5, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3, t4##_PARAM, d4, t5##_PARAM, d5) \ { \ this->functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5 = function; \ } /////////////// // EXECUTION // /////////////// //! execute-macro for functions with no parameters #define ShellCommandExecute0() \ if (this->paramCount == 0) \ (dynamic_cast(object)->*functionPointer_0)() //! execute-macro for functions with one parameter #define ShellCommandExecute1(t1) \ else if (this->paramCount == 1 && this->parameters[0] == t1##_PARAM) \ (dynamic_cast(object)->*functionPointer_1_##t1)(t1##_FUNC(parameters, t1##_DEFGRAB(0))) //! execute-macro for functions with two parameters #define ShellCommandExecute2(t1,t2) \ else if (this->paramCount == 2 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM) \ (dynamic_cast(object)->*functionPointer_2_##t1##_##t2)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1))) //! execute-macro for functions with three parameters #define ShellCommandExecute3(t1,t2,t3) \ else if (this->paramCount == 3 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM) \ (dynamic_cast(object)->*functionPointer_3_##t1##_##t2##_##t3)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2))) //! execute-macro for functions with four parameters #define ShellCommandExecute4(t1,t2,t3,t4) \ else if (this->paramCount == 4 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM && this->parameters[3] == t4##_PARAM) \ (dynamic_cast(object)->*functionPointer_4_##t1##_##t2##_##t3##_##t4)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3))) //! execute-macro for functions with five parameters #define ShellCommandExecute5(t1,t2,t3,t4,t5) \ else if (this->paramCount == 5 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM && this->parameters[3] == t4##_PARAM && this->parameters[4] == t5##_PARAM) \ (dynamic_cast(object)->*functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3)), t5##_FUNC(sub.getString(4), t5##_DEFGRAB(4))) //! keeps information about a ShellCommand template class ShellCommand : public ShellCommandBase { public: #ifdef FUNCTOR_LIST #undef FUNCTOR_LIST #endif //! FUNCTOR_LIST is the List of command-registerers #define FUNCTOR_LIST(x) ShellCommandRegister ## x #include "functor_list.h" #undef FUNCTOR_LIST private: //! FUNCTOR_LIST is the List of CommandConstructors #define FUNCTOR_LIST(x) ShellCommandConstructor ## x #include "functor_list.h" #undef FUNCTOR_LIST virtual void executeCommand (BaseObject* object, const char* parameters) { // if (parameters != NULL) SubString sub(parameters); //! FUNCTOR_LIST is the List of Executive Functions #define FUNCTOR_LIST(x) ShellCommandExecute ## x #include "functor_list.h" #undef FUNCTOR_LIST } }; #endif /* _SHELL_COMMAND_H */