[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