Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/orxonox/gui/GUIManager.cc @ 2687

Last change on this file since 2687 was 2344, checked in by rgrieder, 16 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: 11.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/**
30    @file
31    @brief
32        Implementation of the GUIManager class.
33*/
34
35#include "OrxonoxStableHeaders.h"
36#include "GUIManager.h"
37
38#include <OgreRenderWindow.h>
39#include <OgreRoot.h>
40#include <CEGUI.h>
41#include "ceguilua/CEGUILua.h"
42#include "util/Exception.h"
43#include "core/input/InputManager.h"
44#include "core/input/SimpleInputState.h"
45#include "core/tolua/tolua_bind.h"
46#include "core/ConsoleCommand.h"
47#include "core/Core.h"
48#include "tolua/tolua_bind.h"
49#include "OgreCEGUIRenderer.h"
50
51#include "lua/lua.hpp"
52
53namespace orxonox
54{
55    SetConsoleCommandShortcut(GUIManager, showGUI_s).keybindMode(KeybindMode::OnPress);
56
57    GUIManager* GUIManager::singletonRef_s = 0;
58
59    GUIManager::GUIManager()
60        //: emptySceneManager_(0)
61        : backgroundSceneManager_(0)
62        //, emptyCamera_(0)
63        , backgroundCamera_(0)
64        //, viewport_(0)
65        , renderWindow_(0)
66        , guiRenderer_(0)
67        , resourceProvider_(0)
68        , scriptModule_(0)
69        , guiSystem_(0)
70        , state_(Uninitialised)
71    {
72        assert(singletonRef_s == 0);
73        singletonRef_s = this;
74    }
75
76    GUIManager::~GUIManager()
77    {
78        if (backgroundCamera_)
79            backgroundSceneManager_->destroyCamera(backgroundCamera_);
80
81        if (backgroundSceneManager_)
82        {
83            // We have to make sure the SceneManager is not anymore referenced.
84            // For the case that the target SceneManager was yet another one, it
85            // wouldn't matter anyway since this is the destructor.
86            guiRenderer_->setTargetSceneManager(0);
87            Ogre::Root::getSingleton().destroySceneManager(backgroundSceneManager_);
88        }
89
90        InputManager::getInstance().requestDestroyState("gui");
91
92        if (guiSystem_)
93            delete guiSystem_;
94
95        if (scriptModule_)
96        {
97            // destroy our own tolua interfaces
98                lua_pushnil(luaState_);
99                lua_setglobal(luaState_, "Orxonox");
100                lua_pushnil(luaState_);
101                lua_setglobal(luaState_, "Core");
102            // TODO: deleting the script module fails an assertation.
103            // However there is not much we can do about it since it occurs too when
104            // we don't open Core or Orxonox. Might be a CEGUI issue.
105            // The memory leak is not a problem anyway..
106            delete scriptModule_;
107        }
108
109        if (guiRenderer_)
110            delete guiRenderer_;
111
112        singletonRef_s = 0;
113    }
114
115    bool GUIManager::initialise(Ogre::RenderWindow* renderWindow)
116    {
117        using namespace CEGUI;
118        if (state_ == Uninitialised)
119        {
120            COUT(3) << "Initialising CEGUI." << std::endl;
121
122            try
123            {
124                // save the render window
125                renderWindow_ = renderWindow;
126
127                // Full screen viewport with Z order = 0 (top most). Don't yet feed a camera (so nothing gets rendered)
128                //this->viewport_ = renderWindow_->addViewport(0, 3);
129                //this->viewport_->setOverlaysEnabled(false);
130                //this->viewport_->setShadowsEnabled(false);
131                //this->viewport_->setSkiesEnabled(false);
132                //this->viewport_->setClearEveryFrame(false);
133
134                // Note: No SceneManager specified yet
135                this->guiRenderer_ = new OgreCEGUIRenderer(renderWindow_, Ogre::RENDER_QUEUE_MAIN, true, 3000);
136                this->resourceProvider_ = guiRenderer_->createResourceProvider();
137                this->resourceProvider_->setDefaultResourceGroup("GUI");
138
139                // setup scripting
140                this->scriptModule_ = new LuaScriptModule();
141                this->luaState_ = this->scriptModule_->getLuaState();
142
143                // create the CEGUI system singleton
144                this->guiSystem_ = new System(this->guiRenderer_, this->resourceProvider_, 0, this->scriptModule_);
145
146                // set the log level according to ours (translate by subtracting 1)
147                Logger::getSingleton().setLoggingLevel(
148                    (LoggingLevel)(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
149
150                // do this after 'new CEGUI::Sytem' because that creates the lua state in the first place
151                tolua_Core_open(this->scriptModule_->getLuaState());
152                tolua_Orxonox_open(this->scriptModule_->getLuaState());
153
154                // register us as input handler
155                SimpleInputState* state = InputManager::getInstance().createInputState<SimpleInputState>("gui", 30);
156                state->setHandler(this);
157                state->setJoyStickHandler(&InputManager::EMPTY_HANDLER);
158
159                // load the background scene
160                loadScenes();
161                //CEGUI::KeyEventArgs e;
162                //e.codepoint
163            }
164            catch (CEGUI::Exception& ex)
165            {
166#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
167                throw GeneralException(ex.getMessage().c_str());
168#else
169                throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
170                    ex.getFileName().c_str(), ex.getName().c_str());
171#endif
172            }
173
174            state_ = Ready;
175        }
176
177        return true;
178    }
179
180    void GUIManager::loadScenes()
181    {
182        // first of all, we need to have our own SceneManager for the GUI. The reason
183        // is that we might have multiple viewports when in play mode (e.g. the view of
184        // a camera fixed at the back of the ship). That forces us to create our own
185        // full screen viewport that is on top of all the others, but doesn't clear the
186        // port before rendering, so everything from the GUI gets on top eventually.
187        // But in order to realise that, we also need a SceneManager with an empty scene,
188        // because the SceneManager is responsible for the render queue.
189        //this->emptySceneManager_ = Ogre::Root::getSingleton()
190        //    .createSceneManager(Ogre::ST_GENERIC, "GUI/EmptySceneManager");
191
192        // we also need a camera or we won't see anything at all.
193        // The camera settings don't matter at all for an empty scene since the GUI
194        // gets rendered on top of the screen rather than into the scene.
195        //this->emptyCamera_ = this->emptySceneManager_->createCamera("GUI/EmptyCamera");
196
197        // Create another SceneManager that enables to display some 3D
198        // scene in the background of the main menu.
199        this->backgroundSceneManager_ = Ogre::Root::getSingleton()
200            .createSceneManager(Ogre::ST_GENERIC, "GUI/BackgroundSceneManager");
201        this->backgroundCamera_ = backgroundSceneManager_->createCamera("GUI/BackgroundCamera");
202
203        // TODO: create something 3D
204        try
205        {
206            this->scriptModule_->executeScriptFile("loadGUI.lua", "GUI");
207        }
208        catch (CEGUI::Exception& ex)
209        {
210#if CEGUI_VERSION_MINOR < 6
211            throw GeneralException(ex.getMessage().c_str());
212#else
213            throw GeneralException(ex.getMessage().c_str(), ex.getLine(),
214                ex.getFileName().c_str(), ex.getName().c_str());
215#endif
216        }
217    }
218
219    void GUIManager::showGUI(const std::string& name, Ogre::SceneManager* sceneManager)// bool showBackground)
220    {
221        if (state_ != Uninitialised)
222        {
223            if (state_ == OnDisplay)
224                hideGUI();
225
226            COUT(3) << "Loading GUI " << name << std::endl;
227            try
228            {
229                if (!sceneManager)
230                {
231                    // currently, only an image is loaded. We could do 3D, see loadBackground.
232                    //this->viewport_->setClearEveryFrame(true);
233                    this->guiRenderer_->setTargetSceneManager(this->backgroundSceneManager_);
234                    //this->viewport_->setCamera(this->backgroundCamera_);
235
236                    lua_pushboolean(this->scriptModule_->getLuaState(), true);
237                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
238                }
239                else
240                {
241                    //this->viewport_->setClearEveryFrame(false);
242                    this->guiRenderer_->setTargetSceneManager(sceneManager);
243                    //this->viewport_->setCamera(this->emptyCamera_);
244
245                    lua_pushboolean(this->scriptModule_->getLuaState(), false);
246                    lua_setglobal(this->scriptModule_->getLuaState(), "showBackground");
247                }
248
249                this->scriptModule_->executeScriptGlobal("showMainMenu");
250
251                InputManager::getInstance().requestEnterState("gui");
252
253                this->state_ = OnDisplay;
254            }
255            catch (CEGUI::Exception& ex)
256            {
257                COUT(2) << "Error while executing lua script. Message:\n" << ex.getMessage() << std::endl;
258            }
259            catch (...)
260            {
261                COUT(2) << "Could show a menu due to unknown reasons." << std::endl;
262            }
263        }
264        else
265        {
266            COUT(2) << "Warning: GUI Manager not yet initialised, cannot load a GUI" << std::endl;
267        }
268    }
269
270    void GUIManager::hideGUI()
271    {
272        if (this->state_ != OnDisplay)
273            return;
274        //this->viewport_->setCamera(0);
275        this->guiRenderer_->setTargetSceneManager(0);
276        this->state_ = Ready;
277        InputManager::getInstance().requestLeaveState("gui");
278    }
279
280    void GUIManager::mouseButtonPressed(MouseButtonCode::ByEnum id)
281    {
282        try
283        {
284            guiSystem_->injectMouseButtonDown(convertButton(id));
285        }
286        catch (CEGUI::ScriptException& ex)
287        {
288            // We simply ignore the exception and proceed
289            COUT(1) << ex.getMessage() << std::endl;
290        }
291    }
292
293    void GUIManager::mouseButtonReleased(MouseButtonCode::ByEnum id)
294    {
295        try
296        {
297            guiSystem_->injectMouseButtonUp(convertButton(id));
298        }
299        catch (CEGUI::ScriptException& ex)
300        {
301            // We simply ignore the exception and proceed
302            COUT(1) << ex.getMessage() << std::endl;
303        }
304    }
305
306
307    inline CEGUI::MouseButton GUIManager::convertButton(MouseButtonCode::ByEnum button)
308    {
309        switch (button)
310        {
311        case MouseButtonCode::Left:
312            return CEGUI::LeftButton;
313
314        case MouseButtonCode::Right:
315            return CEGUI::RightButton;
316
317        case MouseButtonCode::Middle:
318            return CEGUI::MiddleButton;
319
320        case MouseButtonCode::Button3:
321            return CEGUI::X1Button;
322
323        case MouseButtonCode::Button4:
324            return CEGUI::X2Button;
325
326        default:
327            return CEGUI::NoButton;
328        }
329    }
330}
Note: See TracBrowser for help on using the repository browser.