Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/orxonox/gamestates/GSLevel.cc @ 2344

Last change on this file since 2344 was 2344, checked in by rgrieder, 15 years ago

Completed destruction of static elements like XMLPort, Identifier, etc.
Of initially about 250 memory leaks (not in the actual meaning but the memory was never freed anyway) only 1 remains in TinyCpp.

  • Core class is now a normal Singleton that gets created and destroyed in main.
  • The same goes for Language, LuaBind, SignalHandler and PlayerManager.
  • Added a new std::set to the CommandExecutor so that the external ConsoleCommands can get destroyed too.
  • Code for destroying CommandLineArguments
  • Added destruction code for ConstructionCallbacks in Identifier
  • Moved internal identifier map (the one with the typeid(.) names) in a static function in Identifier. This was necessary in order to destroy ALL Identifiers with the static destruction function. Before it was possible to create an Identifier with having a class instance (that would call RegisterObject) for instance by simply accessing it via getIdentifier.
  • Removed a big memory leak in Button (forgot to destroy the ConfigValueContainers)
  • Added destruction code for InputBufferListenerTuples in InputBuffer destructor.
  • Added destruction code for load and save executors in both XMLPortParam and XMLPortObject
  • Added destruction code for ConsoleCommands in GSRoot, GSGraphics and GSLevel (temporary solution anyway)
  • Deleting the CEGUILua script module seems to work properly now, one memory leak less (GUIManager.cc)
  • Added global destruction calls in Main.cc
  • Property svn:eol-style set to native
File size: 9.7 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 *      Fabian 'x3n' Landau
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "GSLevel.h"
31
32#include "core/input/InputManager.h"
33#include "core/input/SimpleInputState.h"
34#include "core/input/KeyBinder.h"
35#include "core/Loader.h"
36#include "core/XMLFile.h"
37#include "core/CommandExecutor.h"
38#include "core/ConsoleCommand.h"
39#include "core/CommandLine.h"
40#include "core/ConfigValueIncludes.h"
41#include "core/CoreIncludes.h"
42#include "core/Core.h"
43//#include "objects/Backlight.h"
44#include "objects/Tickable.h"
45#include "objects/Radar.h"
46//#include "tools/ParticleInterface.h"
47#include "CameraManager.h"
48#include "LevelManager.h"
49#include "PlayerManager.h"
50#include "Settings.h"
51
52namespace orxonox
53{
54    SetCommandLineArgument(level, "sample3.oxw").shortcut("l");
55
56    GSLevel::GSLevel()
57//        : GameState<GSGraphics>(name)
58        : timeFactor_(1.0f)
59        , keyBinder_(0)
60        , inputState_(0)
61        , radar_(0)
62        , startFile_(0)
63        , cameraManager_(0)
64        , levelManager_(0)
65    {
66        RegisterObject(GSLevel);
67        setConfigValues();
68    }
69
70    GSLevel::~GSLevel()
71    {
72    }
73
74    void GSLevel::setConfigValues()
75    {
76        SetConfigValue(keyDetectorCallbackCode_, "KeybindBindingStringKeyName=");
77        SetConfigValue(defaultKeybindings_, "def_keybindings.ini")
78            .description("Filename of default keybindings.");
79    }
80
81    void GSLevel::enter(Ogre::Viewport* viewport)
82    {
83        if (Core::showsGraphics())
84        {
85            inputState_ = InputManager::getInstance().createInputState<SimpleInputState>("game", 20);
86            keyBinder_ = new KeyBinder();
87            keyBinder_->loadBindings("keybindings.ini", defaultKeybindings_);
88            inputState_->setHandler(keyBinder_);
89
90            // create the global CameraManager
91            assert(viewport);
92            this->cameraManager_ = new CameraManager(viewport);
93
94            // Start the Radar
95            this->radar_ = new Radar();
96        }
97
98        if (Core::isMaster())
99        {
100            // create the global LevelManager
101            this->levelManager_ = new LevelManager();
102            this->playerManager_ = new PlayerManager();
103
104            // reset game speed to normal
105            timeFactor_ = 1.0f;
106
107            this->loadLevel();
108        }
109
110        if (Core::showsGraphics())
111        {
112            // TODO: insert slomo console command with
113            // .accessLevel(AccessLevel::Offline).defaultValue(0, 1.0).axisParamIndex(0).isAxisRelative(false);
114
115            // keybind console command
116            FunctorMember<GSLevel>* functor1 = createFunctor(&GSLevel::keybind);
117            functor1->setObject(this);
118            ccKeybind_ = createConsoleCommand(functor1, "keybind");
119            CommandExecutor::addConsoleCommandShortcut(ccKeybind_);
120            FunctorMember<GSLevel>* functor2 = createFunctor(&GSLevel::tkeybind);
121            functor2->setObject(this);
122            ccTkeybind_ = createConsoleCommand(functor2, "tkeybind");
123            CommandExecutor::addConsoleCommandShortcut(ccTkeybind_);
124            // set our console command as callback for the key detector
125            InputManager::getInstance().setKeyDetectorCallback(std::string("keybind ") + keyDetectorCallbackCode_);
126
127            // level is loaded: we can start capturing the input
128            InputManager::getInstance().requestEnterState("game");
129        }
130
131        if (Core::isMaster())
132        {
133            // time factor console command
134            FunctorMember<GSLevel>* functor = createFunctor(&GSLevel::setTimeFactor);
135            functor->setObject(this);
136            ccSetTimeFactor_ = createConsoleCommand(functor, "setTimeFactor");
137            CommandExecutor::addConsoleCommandShortcut(ccSetTimeFactor_).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);;
138        }
139    }
140
141    void GSLevel::leave()
142    {
143        // destroy console commands
144        delete this->ccKeybind_;
145        delete this->ccSetTimeFactor_;
146        delete this->ccTkeybind_;
147
148        // this call will delete every BaseObject!
149        // But currently this will call methods of objects that exist no more
150        // The only 'memory leak' is the ParticleSpawer. They would be deleted here
151        // and call a sceneNode method that has already been destroy by the corresponding space ship.
152        //Loader::close();
153
154        if (Core::showsGraphics())
155            InputManager::getInstance().requestLeaveState("game");
156
157        if (Core::isMaster())
158            this->unloadLevel();
159
160        if (this->radar_)
161            delete this->radar_;
162
163        if (this->cameraManager_)
164            delete this->cameraManager_;
165
166        if (this->levelManager_)
167            delete this->levelManager_;
168
169        if (this->playerManager_)
170            delete this->playerManager_;
171
172        if (Core::showsGraphics())
173        {
174            inputState_->setHandler(0);
175            InputManager::getInstance().requestDestroyState("game");
176            if (this->keyBinder_)
177                delete this->keyBinder_;
178        }
179    }
180
181    void GSLevel::ticked(const Clock& time)
182    {
183        // Commented by 1337: Temporarily moved to GSGraphics.
184        //// Call the scene objects
185        //for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
186        //    it->tick(time.getDeltaTime() * this->timeFactor_);
187    }
188
189    /**
190    @brief
191        Changes the speed of Orxonox
192    */
193    void GSLevel::setTimeFactor(float factor)
194    {
195/*
196        float change = factor / this->timeFactor_;
197*/
198        this->timeFactor_ = factor;
199/*
200        for (ObjectList<ParticleInterface>::iterator it = ObjectList<ParticleInterface>::begin(); it; ++it)
201            it->setSpeedFactor(it->getSpeedFactor() * change);
202
203        for (ObjectList<Backlight>::iterator it = ObjectList<Backlight>::begin(); it; ++it)
204            it->setTimeFactor(timeFactor_);
205*/
206    }
207
208    void GSLevel::loadLevel()
209    {
210        // call the loader
211        COUT(0) << "Loading level..." << std::endl;
212        std::string levelName;
213        CommandLine::getValue("level", &levelName);
214        startFile_ = new XMLFile(Settings::getDataPath() + std::string("levels/") + levelName);
215        Loader::open(startFile_);
216    }
217
218    void GSLevel::unloadLevel()
219    {
220        //////////////////////////////////////////////////////////////////////////////////////////
221        // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO // TODO //
222        //////////////////////////////////////////////////////////////////////////////////////////
223        // Loader::unload(startFile_); // TODO: REACTIVATE THIS IF LOADER::UNLOAD WORKS PROPERLY /
224        //////////////////////////////////////////////////////////////////////////////////////////
225
226        delete this->startFile_;
227    }
228
229    void GSLevel::keybind(const std::string &command)
230    {
231        this->keybindInternal(command, false);
232    }
233
234    void GSLevel::tkeybind(const std::string &command)
235    {
236        this->keybindInternal(command, true);
237    }
238
239    /**
240    @brief
241        Assigns a command string to a key/button/axis. The name is determined via KeyDetector.
242    @param command
243        Command string that can be executed by the CommandExecutor
244        OR: Internal string "KeybindBindingStringKeyName=" used for the second call to identify
245        the key/button/axis that has been activated. This is configured above in enter().
246    */
247    void GSLevel::keybindInternal(const std::string& command, bool bTemporary)
248    {
249        if (Core::showsGraphics())
250        {
251            static std::string bindingString = "";
252            static bool bTemporarySaved = false;
253            static bool bound = true;
254            // note: We use a long name to make 'sure' that the user doesn't use it accidentally.
255            // Howerver there will be no real issue if it happens anyway.
256            if (command.find(keyDetectorCallbackCode_) != 0)
257            {
258                if (bound)
259                {
260                    COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
261                    InputManager::getInstance().requestEnterState("detector");
262                    bindingString = command;
263                    bTemporarySaved = bTemporary;
264                    bound = false;
265                }
266                //else:  We're still in a keybind command. ignore this call.
267            }
268            else
269            {
270                if (!bound)
271                {
272                    // user has pressed the key
273                    std::string name = command.substr(this->keyDetectorCallbackCode_.size());
274                    COUT(0) << "Binding string \"" << bindingString << "\" on key '" << name << "'" << std::endl;
275                    this->keyBinder_->setBinding(bindingString, name, bTemporarySaved);
276                    InputManager::getInstance().requestLeaveState("detector");
277                    bound = true;
278                }
279                // else: A key was pressed within the same tick, ignore it.
280            }
281        }
282    }
283}
Note: See TracBrowser for help on using the repository browser.