Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/RootGameState.cc @ 1984

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

Added some more Ogre shutdown code. Does not yet work properly if you wish to reload GSGraphics.

  • Property svn:eol-style set to native
File size: 7.2 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#include "RootGameState.h"
30
31#include "util/String.h"
32#include "util/SubString.h"
33#include "util/Debug.h"
34#include "util/Exception.h"
35#include "Core.h"
36#include "Clock.h"
37#include "CommandLine.h"
38
39namespace orxonox
40{
41    SetCommandLineArgument(state, "gui").setShortcut("s");
42
43    RootGameState::RootGameState(const std::string& name)
44        : GameState<GameStateBase>(name)
45        , stateRequest_("")
46    {
47    }
48
49    RootGameState::~RootGameState()
50    {
51    }
52
53    /**
54    @brief
55        Internal method that actually makes the state transition. Since it is internal,
56        the method can assume certain things to be granted (like 'this' is always active).
57    */
58    void RootGameState::makeTransition(GameStateBase* source, GameStateBase* destination)
59    {
60        if (source != 0)
61        {
62            // transition was not initiated by root itself
63            this->activeChild_ = 0;
64        }
65
66        if (destination == this)
67        {
68            // this marks the end of the game.
69            return;
70        }
71
72        // Check for 'destination' in the children map first
73        std::map<GameStateBase*, GameStateBase*>::const_iterator it
74            = this->grandchildrenToChildren_.find(destination);
75        if (it != this->grandchildrenToChildren_.end())
76        {
77            OrxAssert(dynamic_cast<GameStateBase*>(it->second) != 0,
78                "There was a mix with RootGameState and GameState, could not cast.");
79            GameStateBase* child = static_cast<GameStateBase*>(it->second);
80            // child state. Don't use 'state', might be a grandchild!
81            this->activeChild_ = child;
82            child->makeTransition(this, destination);
83        }
84        else
85        {
86            // root doesn't have a parent..
87            OrxAssert(false, "GameState '" + destination->getName() + "' not found in children list of Root.");
88        }
89    }
90
91    void RootGameState::gotoState(const std::string& name)
92    {
93        GameStateBase* request = getState(name);
94        if (request)
95        {
96            GameStateBase* current = getCurrentState();
97            if (current)
98            {
99                current->makeTransition(0, request);
100            }
101            else
102            {
103                // Root is not yet active. This is a violation.
104                ThrowException(GameState, "Activate Root before requesting a state.");
105            }
106        }
107        else
108        {
109            COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
110        }
111    }
112
113    /**
114    @brief
115        Makes a state transition according to the state tree. You can choose any state
116        in the tree to do the call. The function finds the current state on its own.
117    @param state
118        The state to be entered, has to exist in the tree.
119    */
120    void RootGameState::requestState(const std::string& name)
121    {
122        this->stateRequest_ = name;
123    }
124
125    /**
126    @brief
127        Starts the game. The little 'while' denotes the main loop.
128        Whenever the root state is selected, the game ends.
129    @param name
130        State to start with (usually main menu or specified by command line)
131    */
132    void RootGameState::start(int argc, char** argv)
133    {
134#ifdef NDEBUG
135        try
136        {
137#endif
138            // start global orxonox time
139            Clock clock;
140
141            // create the Core settings to configure the output level
142            Core::getInstance();
143
144            parseArguments(argc, argv);
145
146            this->activate();
147
148            // get initial state from command line
149            std::string initialState;
150            CommandLine::getValue<std::string>("state", &initialState);
151            gotoState(initialState);
152
153            while (this->activeChild_)
154            {
155                clock.capture();
156
157                this->tick(clock);
158
159                if (this->stateRequest_ != "")
160                    gotoState(stateRequest_);
161            }
162
163            this->deactivate();
164#ifdef NDEBUG
165        }
166        // Note: These are all unhandled exceptions that should not have made its way here!
167        // almost complete game catch block to display the messages appropriately.
168        catch (std::exception& ex)
169        {
170            COUT(1) << ex.what() << std::endl;
171            COUT(1) << "Program aborted." << std::endl;
172            abort();
173        }
174        // anything that doesn't inherit from std::exception
175        catch (...)
176        {
177            COUT(1) << "An unidentifiable exception has occured. Program aborted." << std::endl;
178            abort();
179        }
180#endif
181    }
182
183    /**
184    @brief
185        Parses both command line and start.ini for CommandLineArguments.
186    */
187    void RootGameState::parseArguments(int argc, char** argv)
188    {
189        // parse command line first
190        std::vector<std::string> args;
191        for (int i = 1; i < argc; ++i)
192            args.push_back(argv[i]);
193
194        try
195        {
196            orxonox::CommandLine::parse(args);
197        }
198        catch (orxonox::ArgumentException& ex)
199        {
200            COUT(1) << ex.what() << std::endl;
201            COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl;
202        }
203
204        // look for additional arguments in start.ini
205        std::ifstream file;
206        file.open("start.ini");
207        args.clear();
208        if (file)
209        {
210            while (!file.eof())
211            {
212                std::string line;
213                std::getline(file, line);
214                line = removeTrailingWhitespaces(line);
215                //if (!(line[0] == '#' || line[0] == '%'))
216                //{
217                SubString tokens(line, " ", " ", false, 92, false, 34, false, 40, 41, false, '#');
218                for (unsigned i = 0; i < tokens.size(); ++i)
219                    if (tokens[i][0] != '#')
220                        args.push_back(tokens[i]);
221                //args.insert(args.end(), tokens.getAllStrings().begin(), tokens.getAllStrings().end());
222                //}
223            }
224            file.close();
225        }
226
227        try
228        {
229            orxonox::CommandLine::parse(args);
230        }
231        catch (orxonox::ArgumentException& ex)
232        {
233            COUT(1) << "An Exception occured while parsing start.ini" << std::endl;
234            COUT(1) << ex.what() << std::endl;
235            COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl;
236        }
237    }
238}
Note: See TracBrowser for help on using the repository browser.