Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 28, 2009, 1:44:23 PM (15 years ago)
Author:
rgrieder
Message:

Improved exception-safety in the InputManager.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core4/src/core/input/InputManager.cc

    r3196 r3237  
    4343#include "util/Convert.h"
    4444#include "util/Exception.h"
    45 #include "util/Debug.h"
     45#include "util/ScopeGuard.h"
    4646#include "core/Clock.h"
    4747#include "core/CoreIncludes.h"
     
    177177            windowHndStr << (unsigned int)windowHnd_;
    178178            paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
     179#if defined(ORXONOX_PLATFORM_WINDOWS)
    179180            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
    180181            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
    181 #if defined ORXONOX_PLATFORM_LINUX
     182            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
     183            //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
     184#elif defined(ORXONOX_PLATFORM_LINUX)
    182185            paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
    183186            paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
     
    191194#endif
    192195
    193             inputSystem_ = OIS::InputManager::createInputSystem(paramList);
    194             CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
    195 
    196             _initialiseKeyboard();
     196            try
     197            {
     198                inputSystem_ = OIS::InputManager::createInputSystem(paramList);
     199                // Exception-safety
     200                Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, inputSystem_);
     201                CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
     202
     203                _initialiseKeyboard();
     204
     205                // Nothing below should throw anymore, dismiss the guard
     206                guard.Dismiss();
     207            }
     208            catch (OIS::Exception& ex)
     209            {
     210                ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
     211            }
    197212
    198213            _initialiseMouse();
     
    200215            if (joyStickSupport)
    201216                _initialiseJoySticks();
    202             // Do this anyway to also inform everything when a joystick was detached.
     217            // Do this anyway to also inform when a joystick was detached.
    203218            _configureJoySticks();
    204219
     
    273288        else
    274289        {
    275             ThrowException(InitialisationFailed, "No keyboard found!");
     290            ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
    276291        }
    277292    }
     
    301316            else
    302317            {
    303                 CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
     318                CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
    304319            }
    305320        }
     
    307322        {
    308323            CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
    309                 << "OIS error message: \"" << ex.eText << "\"" << std::endl;
     324                << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl;
    310325            mouse_ = 0;
    311326        }
     
    345360            }
    346361        }
    347         else
    348         {
    349             //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
    350         }
    351362    }
    352363
     
    528539        if (internalState_ != Uninitialised)
    529540        {
     541            CCOUT(3) << "Destroying ..." << std::endl;
     542
     543            // kick all active states 'nicely'
     544            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
     545                rit != activeStates_.rend(); ++rit)
     546            {
     547                (*rit).second->onLeave();
     548            }
     549
     550            // Destroy calibrator helper handler and state
     551            delete keyDetector_;
     552            requestDestroyState("calibrator");
     553            // Destroy KeyDetector and state
     554            delete calibratorCallbackBuffer_;
     555            requestDestroyState("detector");
     556            // destroy the empty InputState
     557            _destroyState(this->stateEmpty_);
     558
     559            // destroy all user InputStates
     560            while (inputStatesByName_.size() > 0)
     561                _destroyState((*inputStatesByName_.rbegin()).second);
     562
     563            // destroy the devices
     564            _destroyKeyboard();
     565            _destroyMouse();
     566            _destroyJoySticks();
     567
    530568            try
    531569            {
    532                 CCOUT(3) << "Destroying ..." << std::endl;
    533 
    534                 // kick all active states 'nicely'
    535                 for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
    536                     rit != activeStates_.rend(); ++rit)
    537                 {
    538                     (*rit).second->onLeave();
    539                 }
    540 
    541                 // Destroy calibrator helper handler and state
    542                 delete keyDetector_;
    543                 requestDestroyState("calibrator");
    544                 // Destroy KeyDetector and state
    545                 delete calibratorCallbackBuffer_;
    546                 requestDestroyState("detector");
    547                 // destroy the empty InputState
    548                 _destroyState(this->stateEmpty_);
    549 
    550                 // destroy all user InputStates
    551                 while (inputStatesByName_.size() > 0)
    552                     _destroyState((*inputStatesByName_.rbegin()).second);
    553 
    554                 // destroy the devices
    555                 _destroyKeyboard();
    556                 _destroyMouse();
    557                 _destroyJoySticks();
    558 
    559570                OIS::InputManager::destroyInputSystem(inputSystem_);
    560 
    561                 CCOUT(3) << "Destroying done." << std::endl;
    562             }
    563             catch (OIS::Exception& ex)
    564             {
    565                 CCOUT(1) << "An exception has occured while destroying:\n" << ex.what()
    566                          << "This could lead to a possible memory/resource leak!" << std::endl;
     571            }
     572            catch (...)
     573            {
     574                CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
    567575            }
    568576        }
     
    578586    {
    579587        assert(inputSystem_);
    580         if (keyboard_)
    581             inputSystem_->destroyInputObject(keyboard_);
    582         keyboard_ = 0;
    583         CCOUT(4) << "Keyboard destroyed." << std::endl;
     588        try
     589        {
     590            if (keyboard_)
     591                inputSystem_->destroyInputObject(keyboard_);
     592            keyboard_ = 0;
     593            CCOUT(4) << "Keyboard destroyed." << std::endl;
     594        }
     595        catch (...)
     596        {
     597            CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl;
     598        }
    584599    }
    585600
     
    591606    {
    592607        assert(inputSystem_);
    593         if (mouse_)
    594             inputSystem_->destroyInputObject(mouse_);
    595         mouse_ = 0;
    596         CCOUT(4) << "Mouse destroyed." << std::endl;
     608        try
     609        {
     610            if (mouse_)
     611                inputSystem_->destroyInputObject(mouse_);
     612            mouse_ = 0;
     613            CCOUT(4) << "Mouse destroyed." << std::endl;
     614        }
     615        catch (...)
     616        {
     617            CCOUT(1) << "Mouse destruction failed! Potential resource leak!" << std::endl;
     618        }
    597619    }
    598620
     
    607629            assert(inputSystem_);
    608630            for (unsigned int i = 0; i < joySticksSize_; i++)
    609                 if (joySticks_[i] != 0)
    610                     inputSystem_->destroyInputObject(joySticks_[i]);
     631            {
     632                try
     633                {
     634                    if (joySticks_[i] != 0)
     635                        inputSystem_->destroyInputObject(joySticks_[i]);
     636                }
     637                catch (...)
     638                {
     639                    CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
     640                }
     641            }
    611642
    612643            joySticks_.clear();
Note: See TracChangeset for help on using the changeset viewer.