Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 29, 2009, 10:01:38 PM (15 years ago)
Author:
rgrieder
Message:

Massively improved exception-safety in GraphicsManager.
This completely resolves #312.

Location:
code/branches/core4/src/orxonox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core4/src/orxonox/GraphicsManager.cc

    r3250 r3254  
    3838#include <fstream>
    3939#include <boost/filesystem.hpp>
     40#include <boost/shared_ptr.hpp>
    4041
    4142#include <OgreCompositorManager.h>
     
    7071namespace orxonox
    7172{
     73    using boost::shared_ptr;
     74
    7275    class _OrxonoxExport OgreWindowEventListener : public Ogre::WindowEventListener
    7376    {
     
    8992        , renderWindow_(0)
    9093        , viewport_(0)
    91         , ogreWindowEventListener_(0)
     94        , ogreWindowEventListener_(new OgreWindowEventListener())
    9295    {
    9396        RegisterObject(GraphicsManager);
     
    9699        singletonRef_s = this;
    97100
    98         this->loaded_ = false;
    99 
    100101        this->setConfigValues();
    101     }
    102 
    103     void GraphicsManager::initialise()
    104     {
     102
    105103        // Ogre setup procedure
    106104        setupOgre();
    107         // load all the required plugins for Ogre
    108         loadOgrePlugins();
    109         // read resource declaration file
    110         this->declareResources();
    111         // Reads ogre config and creates the render window
    112         this->loadRenderer();
    113 
    114         // TODO: Spread this
    115         this->initialiseResources();
    116 
    117         // add console commands
    118         FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
    119         functor1->setObject(this);
    120         ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
    121         CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
    122 
    123         this->loaded_ = true;
     105
     106        try
     107        {
     108            // load all the required plugins for Ogre
     109            loadOgrePlugins();
     110            // read resource declaration file
     111            this->declareResources();
     112            // Reads ogre config and creates the render window
     113            this->loadRenderer();
     114
     115            // TODO: Spread this
     116            this->initialiseResources();
     117
     118            // add console commands
     119            FunctorMember<GraphicsManager>* functor1 = createFunctor(&GraphicsManager::printScreen);
     120            functor1->setObject(this);
     121            ccPrintScreen_ = createConsoleCommand(functor1, "printScreen");
     122            CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
     123        }
     124        catch (...)
     125        {
     126            // clean up
     127            delete this->ogreRoot_;
     128            delete this->ogreLogger_;
     129            delete this->ogreWindowEventListener_;
     130            throw;
     131        }
    124132    }
    125133
     
    130138    GraphicsManager::~GraphicsManager()
    131139    {
    132         if (this->loaded_)
    133         {
    134             delete this->ccPrintScreen_;
    135 
    136             if (this->ogreWindowEventListener_)
    137             {
    138                 // remove our WindowEventListener first to avoid bad calls after the window has been destroyed
    139                 Ogre::WindowEventUtilities::removeWindowEventListener(this->renderWindow_, this->ogreWindowEventListener_);
    140                 delete this->ogreWindowEventListener_;
    141             }
    142 
    143             // destroy render window
    144 //            Ogre::RenderSystem* renderer = this->ogreRoot_->getRenderSystem();
    145 //            renderer->destroyRenderWindow("Orxonox");
    146 
    147             // HACK! This fixes an exit crash
    148             Map::hackDestroyMap();
    149 
    150             // unload all compositors
    151             Ogre::CompositorManager::getSingleton().removeAll();
    152 
    153             // Delete OGRE main control organ
    154             delete this->ogreRoot_;
    155 
    156             // delete the ogre log and the logManager (since we have created it in the first place).
    157             this->ogreLogger_->getDefaultLog()->removeListener(this);
    158             this->ogreLogger_->destroyLog(Ogre::LogManager::getSingleton().getDefaultLog());
    159             delete this->ogreLogger_;
    160         }
     140/*
     141        delete this->ccPrintScreen_;
     142*/
     143
     144        // HACK! This fixes an exit crash
     145        Map::hackDestroyMap();
     146        // unload all compositors (this is only necessary because we don't yet destroy all resources!)
     147        Ogre::CompositorManager::getSingleton().removeAll();
     148
     149        // Delete OGRE main control organ
     150        delete this->ogreRoot_;
     151
     152        // delete the logManager (since we have created it in the first place).
     153        delete this->ogreLogger_;
     154
     155        delete this->ogreWindowEventListener_;
    161156
    162157        assert(singletonRef_s);
     
    194189    void GraphicsManager::update(const Clock& time)
    195190    {
    196         if (this->loaded_)
    197         {
    198             Ogre::FrameEvent evt;
    199             evt.timeSinceLastFrame = time.getDeltaTime();
    200             evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
    201 
    202             // don't forget to call _fireFrameStarted to OGRE to make sure
    203             // everything goes smoothly
    204             ogreRoot_->_fireFrameStarted(evt);
    205 
    206             // Pump messages in all registered RenderWindows
    207             // This calls the WindowEventListener objects.
    208             Ogre::WindowEventUtilities::messagePump();
    209             // make sure the window stays active even when not focused
    210             // (probably only necessary on windows)
    211             this->renderWindow_->setActive(true);
    212 
    213             // render
    214             ogreRoot_->_updateAllRenderTargets();
    215 
    216             // again, just to be sure OGRE works fine
    217             ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
    218         }
     191        Ogre::FrameEvent evt;
     192        evt.timeSinceLastFrame = time.getDeltaTime();
     193        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
     194
     195        // don't forget to call _fireFrameStarted to OGRE to make sure
     196        // everything goes smoothly
     197        ogreRoot_->_fireFrameStarted(evt);
     198
     199        // Pump messages in all registered RenderWindows
     200        // This calls the WindowEventListener objects.
     201        Ogre::WindowEventUtilities::messagePump();
     202        // make sure the window stays active even when not focused
     203        // (probably only necessary on windows)
     204        this->renderWindow_->setActive(true);
     205
     206        // render
     207        ogreRoot_->_updateAllRenderTargets();
     208
     209        // again, just to be sure OGRE works fine
     210        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
    219211    }
    220212
     
    248240        // create a new logManager
    249241        // Ogre::Root will detect that we've already created a Log
    250         ogreLogger_ = new Ogre::LogManager();
     242        std::auto_ptr<Ogre::LogManager> logger(new Ogre::LogManager());
    251243        COUT(4) << "Ogre LogManager created" << std::endl;
    252244
    253245        // create our own log that we can listen to
    254246        Ogre::Log *myLog;
    255         myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
     247        myLog = logger->createLog(ogreLogFilepath.string(), true, false, false);
    256248        COUT(4) << "Ogre Log created" << std::endl;
    257249
     
    272264        // Leave plugins file empty. We're going to do that part manually later
    273265        ogreRoot_ = new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string());
     266        // In case that new Root failed the logger gets destroyed because of the std::auto_ptr
     267        ogreLogger_ = logger.release();
    274268
    275269        COUT(3) << "Ogre set up done." << std::endl;
     
    348342        if (!ogreRoot_->restoreConfig())
    349343            if (!ogreRoot_->showConfigDialog())
    350                 ThrowException(InitialisationFailed, "Could not show Ogre configuration dialogue.");
     344                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
    351345
    352346        CCOUT(4) << "Creating render window" << std::endl;
     
    354348        this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
    355349
    356         this->ogreWindowEventListener_ = new OgreWindowEventListener();
    357350        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_);
    358351
  • code/branches/core4/src/orxonox/GraphicsManager.h

    r3196 r3254  
    5757
    5858        void setConfigValues();
    59         void initialise();
    6059
    6160        void update(const Clock& time);
     
    9392
    9493    private:
    95         bool                loaded_;
    96 
    9794        Ogre::Root*         ogreRoot_;                 //!< Ogre's root
    9895        Ogre::LogManager*   ogreLogger_;
    9996        Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
    10097        Ogre::Viewport*     viewport_;                 //!< default full size viewport
    101         OgreWindowEventListener* ogreWindowEventListener_;
     98        OgreWindowEventListener* ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
    10299
    103100        // config values
  • code/branches/core4/src/orxonox/gamestates/GSGraphics.cc

    r3243 r3254  
    108108        setConfigValues();
    109109
    110         // initialise graphics manager. Doesn't load the render window yet!
     110        // Load OGRE including the render window
    111111        this->graphicsManager_ = new GraphicsManager();
    112         this->graphicsManager_->initialise();
    113112
    114113        // load debug overlay
Note: See TracChangeset for help on using the changeset viewer.