Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/CommandExecutor.h @ 1001

Last change on this file since 1001 was 1001, checked in by landauf, 16 years ago

ok, be aware, here comes a big one. people with weak nerves should probably better look away or take some serious drugs.
this update includes partial and explicit class template specialization, partial and explicit specialized template function overloading, template meta programming and a simple typecast.
yeah right, a typecast. but let me explain the whole story from the beginning.

it all started with a simple problem: i had a double in a MultiType and wanted a float, but i always got 0. what was the problem? the conversion 'MultiType to anyting' was handled by the Converter class in util/Convert.h and the Converter was specialized for strings, multitypes, vectors and so on, but not for int, float, bool, …
so i've first wanted to implement a typecast as default, but this was a bad idea because it doesn't work for almost every generic type.
implementing an explicit specialization for every possible pair of primitives (did you ever happened to use an unsigned short? or a long double? no? ignorants :D) would have been a simple but ugly solution.
but there were other problems: if there's a rule to convert a string into anything and another rule to convert anything into an int - what happens if you want to convert a string into an int? compiler error! …ambiguous partial template specialization.
so i've spent days and nights to find a solution. this is my 5th try or so and i'm still really unsure if it works, but it's the first version i want to commit to have at least a backup.
if you're interested in looking at the code you better wait until i've cleaned up the whole thing, it's a real mess. and i want to do further tests, but now i'm tired. good night ;)

File size: 9.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#ifndef _CommandExecutor_H__
29#define _CommandExecutor_H__
30
31#include <string>
32#include <map>
33#include <list>
34
35#include "util/SubString.h"
36#include "util/MultiTypeMath.h"
37#include "CorePrereqs.h"
38
39#define COMMAND_EXECUTOR_CURSOR "$"
40
41namespace orxonox
42{
43    enum CommandState
44    {
45        CS_Uninitialized,
46        CS_Empty,
47        CS_FunctionClass_Or_Shortcut_Or_Keyword,
48        CS_Shortcut_Params,
49        CS_Shortcut_Finished,
50        CS_Function,
51        CS_Function_Params,
52        CS_Function_Finished,
53        CS_ConfigValueClass,
54        CS_ConfigValue,
55        CS_ConfigValueType,
56        CS_ConfigValueFinished,
57        CS_KeybindKey,
58        CS_KeybindCommand,
59        CS_KeybindFinished,
60        CS_Error
61    };
62
63    void exec(const std::string& filename);
64    std::string echo(const std::string& text);
65
66    void write(const std::string& filename, const std::string& text);
67    void append(const std::string& filename, const std::string& text);
68    std::string read(const std::string& filename);
69
70    enum KeybindMode {}; // temporary
71
72    ///////////////////////
73    // CommandEvaluation //
74    ///////////////////////
75    class _CoreExport CommandEvaluation
76    {
77        friend class CommandExecutor;
78
79        public:
80            CommandEvaluation();
81
82            KeybindMode getKeybindMode();
83            bool isValid() const;
84
85            inline void setAdditionalParameter(const std::string& param)
86                { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }
87            inline std::string getAdditionalParameter() const
88                { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
89
90            void setEvaluatedParameter(unsigned int index, MultiTypeMath param);
91            MultiTypeMath getEvaluatedParameter(unsigned int index) const;
92
93            void evaluateParams();
94
95            MultiTypeMath getReturnvalue() const;
96
97        private:
98            std::string processedCommand_;
99            SubString tokens_;
100            std::string additionalParameter_;
101
102            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctionClasses_;
103            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleShortcuts_;
104            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_;
105            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValueClasses_;
106            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValues_;
107            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleKeys_;
108
109            Identifier* functionclass_;
110            Identifier* configvalueclass_;
111            ExecutorStatic* shortcut_;
112            ExecutorStatic* function_;
113            ConfigValueContainer* configvalue_;
114            ConfigValueContainer* key_;
115
116            std::string errorMessage_;
117            CommandState state_;
118
119            bool bEvaluatedParams_;
120            MultiTypeMath param_[5];
121            ExecutorStatic* evaluatedExecutor_;
122    };
123
124    /////////////////////
125    // CommandExecutor //
126    /////////////////////
127    class _CoreExport CommandExecutor
128    {
129        public:
130            static bool execute(const std::string& command);
131            static bool execute(const CommandEvaluation& evaluation);
132
133            static std::string complete(const std::string& command);
134            static std::string complete(const CommandEvaluation& evaluation);
135
136            static std::string hint(const std::string& command);
137            static std::string hint(const CommandEvaluation& evaluation);
138
139            static CommandEvaluation evaluate(const std::string& command);
140
141            static Executor& addConsoleCommandShortcut(ExecutorStatic* executor);
142            static ExecutorStatic* getConsoleCommandShortcut(const std::string& name);
143            static ExecutorStatic* getLowercaseConsoleCommandShortcut(const std::string& name);
144
145            /** @brief Returns the map that stores all console commands. @return The const_iterator */
146            static inline const std::map<std::string, ExecutorStatic*>& getConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_; }
147            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
148            static inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_.begin(); }
149            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
150            static inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_.end(); }
151
152            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
153            static inline const std::map<std::string, ExecutorStatic*>& getLowercaseConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_; }
154            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
155            static inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.begin(); }
156            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
157            static inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end(); }
158
159        private:
160            CommandExecutor() {}
161            CommandExecutor(const CommandExecutor& other) {}
162            ~CommandExecutor() {}
163
164            static CommandExecutor& getInstance();
165            static CommandEvaluation& getEvaluation();
166
167            static void parse(const std::string& command, bool bInitialize = true);
168            static void initialize(const std::string& command);
169
170            static bool argumentsGiven(unsigned int num);
171            static unsigned int argumentsGiven();
172
173            static std::string getToken(unsigned int index);
174
175            static bool enoughParametersGiven(unsigned int head, Executor* executor);
176
177            static void createListOfPossibleShortcuts(const std::string& fragment);
178            static void createListOfPossibleFunctionClasses(const std::string& fragment);
179            static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier);
180            static void createListOfPossibleConfigValueClasses(const std::string& fragment);
181            static void createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier);
182            static void createListOfPossibleKeys(const std::string& fragment);
183
184            static bool compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second);
185
186            static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);
187            static std::string dump(const ExecutorStatic* executor);
188            static std::string dump(const ConfigValueContainer* container);
189
190            static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);
191
192            static Identifier* getIdentifierOfPossibleFunctionClass(const std::string& name);
193            static ExecutorStatic* getExecutorOfPossibleShortcut(const std::string& name);
194            static ExecutorStatic* getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier);
195            static Identifier* getIdentifierOfPossibleConfigValueClass(const std::string& name);
196            static ConfigValueContainer* getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier);
197            static ConfigValueContainer* getContainerOfPossibleKey(const std::string& name);
198
199            CommandEvaluation evaluation_;
200
201            std::map<std::string, ExecutorStatic*> consoleCommandShortcuts_;
202            std::map<std::string, ExecutorStatic*> consoleCommandShortcuts_LC_;
203    };
204}
205
206#endif /* _CommandExecutor_H__ */
Note: See TracBrowser for help on using the repository browser.