Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/core/CommandLine.h @ 1663

Last change on this file since 1663 was 1663, checked in by rgrieder, 16 years ago

Added CommandLine class.
You can now call SetCommandLineArgument like SetConsoleCommand and hereby define a new command line argument. They are passed in main() and then they can be accessed by commandLine::getCommandLineArgument().

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _CommandLine_H__
30#define _CommandLine_H__
31
32#include "CorePrereqs.h"
33#include <map>
34#include "util/Convert.h"
35#include "Debug.h"
36#include "Exception.h"
37
38
39#define SetCommandLineArgument(name, defaultValue) \
40    BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
41    = orxonox::CommandLine::addCommandLineArgument(#name, defaultValue)
42
43namespace orxonox
44{
45    class _CoreExport BaseCommandLineArgument
46    {
47        friend class CommandLine;
48
49    public:
50        bool hasDefaultValue() const { return bHasDefaultValue_; }
51        const std::string& getName() const { return name_; }
52        const std::string& getShortcut() const { return shortcut_; }
53        BaseCommandLineArgument& setShortcut(const std::string& shortcut)
54        { this->shortcut_ = shortcut; return *this; }
55
56    protected:
57        BaseCommandLineArgument(const std::string& name)
58            : name_(name)
59            , bHasDefaultValue_(true)
60        { }
61
62        BaseCommandLineArgument(const BaseCommandLineArgument& instance);
63        virtual ~BaseCommandLineArgument() { }
64
65        virtual void parse(const std::string& value) = 0;
66
67        bool bHasDefaultValue_;
68
69    private:
70        std::string name_;
71        std::string shortcut_;
72    };
73
74
75    template <class T>
76    class CommandLineArgument : public BaseCommandLineArgument
77    {
78        friend class CommandLine;
79
80    public:
81        T getValue() const { return value_; }
82        T getDefaultValue() const { return defaultValue_; }
83
84    private:
85        CommandLineArgument(const std::string& name, const T& defaultValue)
86            : BaseCommandLineArgument(name)
87            , value_(defaultValue)
88            , defaultValue_(defaultValue)
89        { }
90
91        virtual void parse(const std::string& value);
92
93        T value_;
94        T defaultValue_;
95    };
96
97    template <class T>
98    void CommandLineArgument<T>::parse(const std::string& value)
99    {
100        if (convertValue(&this->value_, value))
101        {
102            this->bHasDefaultValue_ = false;
103        }
104        else
105        {
106            ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
107        }
108    }
109
110
111    class _CoreExport CommandLine
112    {
113    public:
114
115        static void parse(int argc, char** argv) { _getInstance()._parse(argc, argv); }
116
117        template <class T>
118        static const CommandLineArgument<T>* getCommandLineArgument(const std::string& name);
119        template <class T>
120        static BaseCommandLineArgument& addCommandLineArgument(const std::string& name,
121            const T& defaultValue);
122
123    private:
124        CommandLine() : bFirstTimeParse_(true) { }
125        CommandLine(const CommandLine& instance);
126        ~CommandLine();
127
128        static CommandLine& _getInstance();
129
130        void _parse(int argc, char** argv);
131        void checkFullArgument(const std::string& name, const std::string& value);
132        void checkShortcut(const std::string& shortcut, const std::string& value);
133
134        bool bFirstTimeParse_;
135
136        std::map<std::string, BaseCommandLineArgument*> cmdLineArgs_;
137        std::map<std::string, BaseCommandLineArgument*> cmdLineArgsShortcut_;
138    };
139
140
141    template <class T>
142    const CommandLineArgument<T>* CommandLine::getCommandLineArgument(const std::string& name)
143    {
144        std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
145        if (it == _getInstance().cmdLineArgs_.end())
146        {
147            ThrowException(Argument, "Could find command line argument '" + name + "'.");
148        }
149        else
150        {
151            CommandLineArgument<T>* arg = dynamic_cast<CommandLineArgument<T>* >(it->second);
152            if (arg == 0)
153            {
154                ThrowException(Argument, "Could not convert command line argument value to requested type. " \
155                    "You should use exactly the same type as predefined.");
156            }
157            else
158            {
159                return arg;
160            }
161        }
162    }
163
164    template <class T>
165    BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name,
166                                             const T& defaultValue)
167    {
168        std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
169        OrxAssert(it == _getInstance().cmdLineArgs_.end(),
170            "Cannot add a command line argument with name '" + name + "' twice.");
171
172        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument<T>(name, defaultValue));
173    }
174}
175
176#endif /* _CommandLine_H__ */
Note: See TracBrowser for help on using the repository browser.