[Orxonox-commit 724] r3254 - in branches/core4/src/orxonox: . gamestates

rgrieder at orxonox.net rgrieder at orxonox.net
Mon Jun 29 22:01:38 CEST 2009


Author: rgrieder
Date: 2009-06-29 22:01:38 +0200 (Mon, 29 Jun 2009)
New Revision: 3254

Modified:
   branches/core4/src/orxonox/GraphicsManager.cc
   branches/core4/src/orxonox/GraphicsManager.h
   branches/core4/src/orxonox/gamestates/GSGraphics.cc
Log:
Massively improved exception-safety in GraphicsManager.
This completely resolves #312.

Modified: branches/core4/src/orxonox/GraphicsManager.cc
===================================================================
--- branches/core4/src/orxonox/GraphicsManager.cc	2009-06-29 20:00:40 UTC (rev 3253)
+++ branches/core4/src/orxonox/GraphicsManager.cc	2009-06-29 20:01:38 UTC (rev 3254)
@@ -37,6 +37,7 @@
 
 #include <fstream>
 #include <boost/filesystem.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <OgreCompositorManager.h>
 #include <OgreConfigFile.h>
@@ -69,6 +70,8 @@
 
 namespace orxonox
 {
+    using boost::shared_ptr;
+
     class _OrxonoxExport OgreWindowEventListener : public Ogre::WindowEventListener
     {
         void windowResized     (Ogre::RenderWindow* rw);
@@ -88,39 +91,44 @@
         , ogreLogger_(0)
         , renderWindow_(0)
         , viewport_(0)
-        , ogreWindowEventListener_(0)
+        , ogreWindowEventListener_(new OgreWindowEventListener())
     {
         RegisterObject(GraphicsManager);
 
         assert(singletonRef_s == 0);
         singletonRef_s = this;
 
-        this->loaded_ = false;
-
         this->setConfigValues();
-    }
 
-    void GraphicsManager::initialise()
-    {
         // Ogre setup procedure
         setupOgre();
-        // load all the required plugins for Ogre
-        loadOgrePlugins();
-        // read resource declaration file
-        this->declareResources();
-        // Reads ogre config and creates the render window
-        this->loadRenderer();
 
-        // TODO: Spread this
-        this->initialiseResources();
+        try
+        {
+            // load all the required plugins for Ogre
+            loadOgrePlugins();
+            // read resource declaration file
+            this->declareResources();
+            // Reads ogre config and creates the render window
+            this->loadRenderer();
 
-        // add console commands
-        FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
-        functor1->setObject(this);
-        ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
-        CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+            // TODO: Spread this
+            this->initialiseResources();
 
-        this->loaded_ = true;
+            // add console commands
+            FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
+            functor1->setObject(this);
+            ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
+            CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+        }
+        catch (...)
+        {
+            // clean up
+            delete this->ogreRoot_;
+            delete this->ogreLogger_;
+            delete this->ogreWindowEventListener_;
+            throw;
+        }
     }
 
     /**
@@ -129,36 +137,23 @@
     */
     GraphicsManager::~GraphicsManager()
     {
-        if (this->loaded_)
-        {
-            delete this->ccPrintScreen_;
+/*
+        delete this->ccPrintScreen_;
+*/
 
-            if (this->ogreWindowEventListener_)
-            {
-                // remove our WindowEventListener first to avoid bad calls after the window has been destroyed
-                Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this->ogreWindowEventListener_);
-                delete this->ogreWindowEventListener_;
-            }
+        // HACK! This fixes an exit crash
+        Map::hackDestroyMap();
+        // unload all compositors (this is only necessary because we don't yet destroy all resources!)
+        Ogre::CompositorManager::getSingleton().removeAll();
 
-            // destroy render window
-//            Ogre::RenderSystem* renderer = this->ogreRoot_->getRenderSystem();
-//            renderer->destroyRenderWindow("Orxonox");
+        // Delete OGRE main control organ
+        delete this->ogreRoot_;
 
-            // HACK! This fixes an exit crash
-            Map::hackDestroyMap();
+        // delete the logManager (since we have created it in the first place).
+        delete this->ogreLogger_;
 
-            // unload all compositors
-            Ogre::CompositorManager::getSingleton().removeAll();
+        delete this->ogreWindowEventListener_;
 
-            // Delete OGRE main control organ
-            delete this->ogreRoot_;
-
-            // delete the ogre log and the logManager (since we have created it in the first place).
-            this->ogreLogger_->getDefaultLog()->removeListener(this);
-            this->ogreLogger_->destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
-            delete this->ogreLogger_;
-        }
-
         assert(singletonRef_s);
         singletonRef_s = 0;
     }
@@ -193,29 +188,26 @@
 
     void GraphicsManager::update(const Clock& time)
     {
-        if (this->loaded_)
-        {
-            Ogre::FrameEvent evt;
-            evt.timeSinceLastFrame = time.getDeltaTime();
-            evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
+        Ogre::FrameEvent evt;
+        evt.timeSinceLastFrame = time.getDeltaTime();
+        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
 
-            // don't forget to call _fireFrameStarted to OGRE to make sure
-            // everything goes smoothly
-            ogreRoot_->_fireFrameStarted(evt);
+        // don't forget to call _fireFrameStarted to OGRE to make sure
+        // everything goes smoothly
+        ogreRoot_->_fireFrameStarted(evt);
 
-            // Pump messages in all registered RenderWindows
-            // This calls the WindowEventListener objects.
-            Ogre::WindowEventUtilities::messagePump();
-            // make sure the window stays active even when not focused
-            // (probably only necessary on windows)
-            this->renderWindow_->setActive(true);
+        // Pump messages in all registered RenderWindows
+        // This calls the WindowEventListener objects.
+        Ogre::WindowEventUtilities::messagePump();
+        // make sure the window stays active even when not focused
+        // (probably only necessary on windows)
+        this->renderWindow_->setActive(true);
 
-            // render
-            ogreRoot_->_updateAllRenderTargets();
+        // render
+        ogreRoot_->_updateAllRenderTargets();
 
-            // again, just to be sure OGRE works fine
-            ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
-        }
+        // again, just to be sure OGRE works fine
+        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
     }
 
     void GraphicsManager::setCamera(Ogre::Camera* camera)
@@ -247,12 +239,12 @@
 
         // create a new logManager
         // Ogre::Root will detect that we've already created a Log
-        ogreLogger_ = new Ogre::LogManager();
+        std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
         COUT(4) << "Ogre LogManager created" << std::endl;
 
         // create our own log that we can listen to
         Ogre::Log *myLog;
-        myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
+        myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
         COUT(4) << "Ogre Log created" << std::endl;
 
         myLog->setLogDetail(Ogre::LL_BOREME);
@@ -271,6 +263,8 @@
 
         // Leave plugins file empty. We're going to do that part manually later
         ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
+        // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
+        ogreLogger_ = logger.release();
 
         COUT(3) << "Ogre set up done." << std::endl;
     }
@@ -347,13 +341,12 @@
 
         if (!ogreRoot_->restoreConfig())
             if (!ogreRoot_->showConfigDialog())
-                ThrowException(InitialisationFailed, "Could not show Ogre configuration dialogue.");
+                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
 
         CCOUT(4) << "Creating render window" << std::endl;
 
         this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
 
-        this->ogreWindowEventListener_ = new OgreWindowEventListener();
         Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
 
         Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);

Modified: branches/core4/src/orxonox/GraphicsManager.h
===================================================================
--- branches/core4/src/orxonox/GraphicsManager.h	2009-06-29 20:00:40 UTC (rev 3253)
+++ branches/core4/src/orxonox/GraphicsManager.h	2009-06-29 20:01:38 UTC (rev 3254)
@@ -56,7 +56,6 @@
         ~GraphicsManager();
 
         void setConfigValues();
-        void initialise();
 
         void update(const Clock& time);
 
@@ -92,13 +91,11 @@
         void printScreen();
 
     private:
-        bool                loaded_;
-
         Ogre::Root*         ogreRoot_;                 //!< Ogre's root
         Ogre::LogManager*   ogreLogger_;
         Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
         Ogre::Viewport*     viewport_;                 //!< default full size viewport
-        OgreWindowEventListener* ogreWindowEventListener_;
+        OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
 
         // config values
         unsigned int        detailLevelParticle_;      //!< Detail level of particle effects (0: off, 1: low, 2: normal, 3: high)

Modified: branches/core4/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- branches/core4/src/orxonox/gamestates/GSGraphics.cc	2009-06-29 20:00:40 UTC (rev 3253)
+++ branches/core4/src/orxonox/gamestates/GSGraphics.cc	2009-06-29 20:01:38 UTC (rev 3254)
@@ -107,9 +107,8 @@
 
         setConfigValues();
 
-        // initialise graphics manager. Doesn't load the render window yet!
+        // Load OGRE including the render window
         this->graphicsManager_ = new GraphicsManager();
-        this->graphicsManager_->initialise();
 
         // load debug overlay
         COUT(3) << "Loading Debug Overlay..." << std::endl;




More information about the Orxonox-commit mailing list