Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 19, 2009, 5:31:02 PM (15 years ago)
Author:
rgrieder
Message:

Merged all remaining revisions from core4 back to the trunk.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/core/input/InputManager.cc

    r3301 r3327  
    3030@file
    3131@brief
    32     Implementation of the InputManager that captures all the input from OIS
    33     and redirects it to handlers.
    34  */
     32    Implementation of the InputManager and a static variable from the InputHandler.
     33*/
    3534
    3635#include "InputManager.h"
    3736
     37#include <cassert>
    3838#include <climits>
    39 #include <cassert>
    4039#include <ois/OISException.h>
    4140#include <ois/OISInputManager.h>
    42 
    43 #include "util/Convert.h"
     41#include <boost/foreach.hpp>
     42
    4443#include "util/Exception.h"
    4544#include "util/ScopeGuard.h"
     
    4948#include "core/ConsoleCommand.h"
    5049#include "core/CommandLine.h"
     50#include "core/Functor.h"
    5151
    5252#include "InputBuffer.h"
    5353#include "KeyDetector.h"
    54 #include "InputState.h"
    55 #include "SimpleInputState.h"
    56 #include "ExtendedInputState.h"
    57 #include "JoyStickDeviceNumberListener.h"
    58 
    59 // HACK (include this as last, X11 seems to define some macros...)
    60 #ifdef ORXONOX_PLATFORM_LINUX
    61 #  include <ois/linux/LinuxMouse.h>
    62 #endif
     54#include "JoyStick.h"
     55#include "JoyStickQuantityListener.h"
     56#include "Mouse.h"
     57#include "Keyboard.h"
    6358
    6459namespace orxonox
    6560{
    66     SetConsoleCommand(InputManager, calibrate, true);
    67     SetConsoleCommand(InputManager, reload, false);
    68 #ifdef ORXONOX_PLATFORM_LINUX
    69     SetConsoleCommand(InputManager, grabMouse, true);
    70     SetConsoleCommand(InputManager, ungrabMouse, true);
    71 #endif
    7261    SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
    7362
    74     EmptyHandler InputManager::EMPTY_HANDLER;
     63    // Abuse of this source file for the InputHandler
     64    InputHandler InputHandler::EMPTY;
     65
    7566    InputManager* InputManager::singletonRef_s = 0;
    7667
    77     using namespace InputDevice;
    78 
    79     /**
    80     @brief
    81         Defines the |= operator for easier use.
    82     */
    83     inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval,
    84                                                       InputManager::InputManagerState rval)
    85     {
    86         return (lval = (InputManager::InputManagerState)(lval | rval));
    87     }
    88 
    89     /**
    90     @brief
    91         Defines the &= operator for easier use.
    92     */
    93     inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval)
    94     {
    95         return (lval = (InputManager::InputManagerState)(lval & rval));
     68    //! Defines the |= operator for easier use.
     69    inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
     70    {
     71        return (lval = (InputManager::State)(lval | rval));
     72    }
     73
     74    //! Defines the &= operator for easier use.
     75    inline InputManager::State operator&=(InputManager::State& lval, int rval)
     76    {
     77        return (lval = (InputManager::State)(lval & rval));
    9678    }
    9779
     
    10082    // ##########                                        ##########
    10183    // ############################################################
    102 
    103     /**
    104     @brief
    105         Constructor only sets member fields to initial zero values
    106         and registers the class in the class hierarchy.
    107     */
    108     InputManager::InputManager()
    109         : inputSystem_(0)
    110         , keyboard_(0)
    111         , mouse_(0)
    112         , joySticksSize_(0)
    113         , devicesNum_(0)
     84    InputManager::InputManager(size_t windowHnd)
     85        : internalState_(Bad)
     86        , oisInputManager_(0)
     87        , devices_(2)
    11488        , windowHnd_(0)
    115         , internalState_(Uninitialised)
    116         , stateEmpty_(0)
     89        , emptyState_(0)
    11790        , keyDetector_(0)
    118         , calibratorCallbackBuffer_(0)
    119         , keyboardModifiers_(0)
     91        , calibratorCallbackHandler_(0)
    12092    {
    12193        RegisterRootObject(InputManager);
     
    12496        singletonRef_s = this;
    12597
    126         setConfigValues();
    127     }
    128 
    129     /**
    130     @brief
    131         Sets the configurable values.
    132     */
     98        CCOUT(4) << "Constructing..." << std::endl;
     99
     100        this->setConfigValues();
     101
     102        this->loadDevices(windowHnd);
     103
     104        // Lowest priority empty InputState
     105        emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
     106        emptyState_->setHandler(&InputHandler::EMPTY);
     107        activeStates_[emptyState_->getPriority()] = emptyState_;
     108
     109        // KeyDetector to evaluate a pressed key's name
     110        InputState* detector = createInputState("detector", false, false, InputStatePriority::Detector);
     111        // Create a callback to avoid buttonHeld events after the key has been detected
     112        FunctorMember<InputManager>* bufferFunctor = createFunctor(&InputManager::clearBuffers);
     113        bufferFunctor->setObject(this);
     114        detector->setLeaveFunctor(bufferFunctor);
     115        keyDetector_ = new KeyDetector();
     116        detector->setHandler(keyDetector_);
     117
     118        // Joy stick calibration helper callback
     119        InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
     120        calibrator->setHandler(&InputHandler::EMPTY);
     121        calibratorCallbackHandler_ = new InputBuffer();
     122        calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true);
     123        calibrator->setKeyHandler(calibratorCallbackHandler_);
     124
     125        this->updateActiveStates();
     126
     127        {
     128            // calibrate console command
     129            FunctorMember<InputManager>* functor = createFunctor(&InputManager::calibrate);
     130            functor->setObject(this);
     131            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "calibrate"), true);
     132        }
     133        {
     134            // reload console command
     135            FunctorMember<InputManager>* functor = createFunctor(&InputManager::reload);
     136            functor->setObject(this);
     137            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "reload"), false);
     138        }
     139
     140        internalState_ = Nothing;
     141        CCOUT(4) << "Construction complete." << std::endl;
     142    }
     143
    133144    void InputManager::setConfigValues()
    134145    {
    135         SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
    136             .description("Ini filename for the the joy stick calibration data.")
    137             .callback(this, &InputManager::_calibrationFileCallback);
    138     }
    139 
    140     /**
    141     @brief
    142         Callback for the joy stick calibration config file. @see setConfigValues.
    143     */
    144     void InputManager::_calibrationFileCallback()
    145     {
    146         ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
    147146    }
    148147
     
    150149    @brief
    151150        Creates the OIS::InputMananger, the keyboard, the mouse and
    152         the joysticks and assigns the key bindings.
     151        the joys ticks. If either of the first two fail, this method throws an exception.
    153152    @param windowHnd
    154153        The window handle of the render window
     
    157156    @param windowHeight
    158157        The height of the render window
    159     @param joyStickSupport
    160         Whether or not to load the joy sticks as well
    161158    */
    162     void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
    163     {
    164         CCOUT(3) << "Initialising Input System..." << std::endl;
    165 
    166         if (!(internalState_ & OISReady))
    167         {
    168             CCOUT(4) << "Initialising OIS components..." << std::endl;
    169 
    170             // store handle internally so we can reload OIS
    171             windowHnd_ = windowHnd;
    172 
    173             OIS::ParamList paramList;
    174             std::ostringstream windowHndStr;
    175 
    176             // Fill parameter list
    177             windowHndStr << static_cast<unsigned int>(windowHnd);
    178             paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
     159    void InputManager::loadDevices(size_t windowHnd)
     160    {
     161        CCOUT(3) << "Loading input devices..." << std::endl;
     162
     163        // When loading the devices they should not already be loaded
     164        assert(internalState_ & Bad);
     165        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
     166        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
     167        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
     168
     169        // store handle internally so we can reload OIS
     170        windowHnd_ = windowHnd;
     171
     172        OIS::ParamList paramList;
     173        std::ostringstream windowHndStr;
     174
     175        // Fill parameter list
     176        windowHndStr << static_cast<unsigned int>(windowHnd);
     177        paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
    179178#if defined(ORXONOX_PLATFORM_WINDOWS)
    180             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
    181             //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
    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")));
     179        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
     180        //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
     181        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
     182        //paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
    184183#elif defined(ORXONOX_PLATFORM_LINUX)
    185             paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
    186             paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
    187             paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
    188             bool kbNoGrab;
    189             CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
    190             if (kbNoGrab)
    191                 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
     184        paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
     185        paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "true"));
     186        paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "true"));
     187        bool kbNoGrab;
     188        CommandLine::getValue("keyboard_no_grab", &kbNoGrab);
     189        if (kbNoGrab)
     190            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
     191        else
     192            paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
     193#endif
     194
     195        try
     196        {
     197            oisInputManager_ = OIS::InputManager::createInputSystem(paramList);
     198            // Exception-safety
     199            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
     200            CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl;
     201
     202            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
     203                devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_);
    192204            else
    193                 paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("true")));
    194 #endif
    195 
     205                ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
     206
     207            // Successful initialisation
     208            guard.Dismiss();
     209        }
     210        catch (std::exception& ex)
     211        {
     212            oisInputManager_ = NULL;
     213            internalState_ |= Bad;
     214            ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
     215        }
     216
     217        // TODO: Remove the two parameters
     218        this->loadMouse();
     219        this->loadJoySticks();
     220
     221        // Reorder states in case some joy sticks were added/removed
     222        this->updateActiveStates();
     223
     224        CCOUT(3) << "Input devices loaded." << std::endl;
     225    }
     226
     227    //! Creates a new orxonox::Mouse
     228    void InputManager::loadMouse()
     229    {
     230        if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0)
     231        {
    196232            try
    197233            {
    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             }
    212 
    213             _initialiseMouse();
    214 
    215             if (joyStickSupport)
    216                 _initialiseJoySticks();
    217             // Do this anyway to also inform when a joystick was detached.
    218             _configureJoySticks();
    219 
    220             // Set mouse/joystick region
    221             if (mouse_)
    222                 setWindowExtents(windowWidth, windowHeight);
    223 
    224             // clear all buffers
    225             _clearBuffers();
    226 
    227             internalState_ |= OISReady;
    228 
    229             CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
     234                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_);
     235            }
     236            catch (const OIS::Exception& ex)
     237            {
     238                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.eText << std::endl
     239                         << "Proceeding without mouse support." << std::endl;
     240            }
    230241        }
    231242        else
    232         {
    233             CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl;
    234         }
    235 
    236         if (!(internalState_ & InternalsReady))
    237         {
    238             CCOUT(4) << "Initialising InputStates components..." << std::endl;
    239 
    240             // Lowest priority empty InputState
    241             stateEmpty_ = createInputState<SimpleInputState>("empty", false, false, InputStatePriority::Empty);
    242             stateEmpty_->setHandler(&EMPTY_HANDLER);
    243             activeStates_[stateEmpty_->getPriority()] = stateEmpty_;
    244 
    245             // KeyDetector to evaluate a pressed key's name
    246             SimpleInputState* detector = createInputState<SimpleInputState>("detector", false, false, InputStatePriority::Detector);
    247             keyDetector_ = new KeyDetector();
    248             detector->setHandler(keyDetector_);
    249 
    250             // Joy stick calibration helper callback
    251             SimpleInputState* calibrator = createInputState<SimpleInputState>("calibrator", false, false, InputStatePriority::Calibrator);
    252             calibrator->setHandler(&EMPTY_HANDLER);
    253             calibratorCallbackBuffer_ = new InputBuffer();
    254             calibratorCallbackBuffer_->registerListener(this, &InputManager::_completeCalibration, '\r', true);
    255             calibrator->setKeyHandler(calibratorCallbackBuffer_);
    256 
    257             internalState_ |= InternalsReady;
    258 
    259             CCOUT(4) << "Initialising InputStates complete." << std::endl;
    260         }
    261 
    262         _updateActiveStates();
    263 
    264         CCOUT(3) << "Initialising complete." << std::endl;
     243            CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
     244    }
     245
     246    //! Creates as many joy sticks as are available.
     247    void InputManager::loadJoySticks()
     248    {
     249        for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++)
     250        {
     251            try
     252            {
     253                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_));
     254            }
     255            catch (std::exception ex)
     256            {
     257                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
     258            }
     259        }
     260
     261        // inform all JoyStick Device Number Listeners
     262        std::vector<JoyStick*> joyStickList;
     263        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
     264            joyStickList.push_back(static_cast<JoyStick*>(devices_[i]));
     265        JoyStickQuantityListener::changeJoyStickQuantity(joyStickList);
     266    }
     267
     268    void InputManager::setKeyDetectorCallback(const std::string& command)
     269    {
     270        this->keyDetector_->setCallbackCommand(command);
     271    }
     272
     273    // ############################################################
     274    // #####                    Destruction                   #####
     275    // ##########                                        ##########
     276    // ############################################################
     277
     278    InputManager::~InputManager()
     279    {
     280        CCOUT(4) << "Destroying..." << std::endl;
     281
     282        // Destroy calibrator helper handler and state
     283        delete keyDetector_;
     284        this->destroyState("calibrator");
     285        // Destroy KeyDetector and state
     286        delete calibratorCallbackHandler_;
     287        this->destroyState("detector");
     288        // destroy the empty InputState
     289        this->destroyStateInternal(this->emptyState_);
     290
     291        // destroy all user InputStates
     292        while (statesByName_.size() > 0)
     293            this->destroyStateInternal((*statesByName_.rbegin()).second);
     294
     295        if (!(internalState_ & Bad))
     296            this->destroyDevices();
     297
     298        CCOUT(4) << "Destruction complete." << std::endl;
     299        singletonRef_s = 0;
    265300    }
    266301
    267302    /**
    268303    @brief
    269         Creates a keyboard and sets the event handler.
    270     @return
    271         False if keyboard stays uninitialised, true otherwise.
     304        Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager)
     305    @throw
     306        Method does not throw
    272307    */
    273     void InputManager::_initialiseKeyboard()
    274     {
    275         if (keyboard_ != 0)
    276         {
    277             CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
    278             return;
    279         }
    280         if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
    281         {
    282             keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
    283             // register our listener in OIS.
    284             keyboard_->setEventCallback(this);
    285             // note: OIS will not detect keys that have already been down when the keyboard was created.
    286             CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
    287         }
    288         else
    289         {
    290             ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
    291         }
    292     }
    293 
    294     /**
    295     @brief
    296         Creates a mouse and sets the event handler.
    297     @return
    298         False if mouse stays uninitialised, true otherwise.
    299     */
    300     void InputManager::_initialiseMouse()
    301     {
    302         if (mouse_ != 0)
    303         {
    304             CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
    305             return;
    306         }
     308    void InputManager::destroyDevices()
     309    {
     310        CCOUT(3) << "Destroying devices..." << std::endl;
     311
     312        BOOST_FOREACH(InputDevice*& device, devices_)
     313        {
     314            if (device == NULL)
     315                continue;
     316            std::string className = device->getClassName();
     317            try
     318            {
     319                delete device;
     320                device = 0;
     321                CCOUT(4) << className << " destroyed." << std::endl;
     322            }
     323            catch (...)
     324            {
     325                CCOUT(1) << className << " destruction failed! Potential resource leak!" << std::endl;
     326            }
     327        }
     328        devices_.resize(InputDeviceEnumerator::FirstJoyStick);
     329
     330        assert(oisInputManager_ != NULL);
    307331        try
    308332        {
    309             if (inputSystem_->getNumberOfDevices(OIS::OISMouse) > 0)
    310             {
    311                 mouse_ = static_cast<OIS::Mouse*>(inputSystem_->createInputObject(OIS::OISMouse, true));
    312                 // register our listener in OIS.
    313                 mouse_->setEventCallback(this);
    314                 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
    315             }
    316             else
    317             {
    318                 CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
    319             }
    320         }
    321         catch (OIS::Exception ex)
    322         {
    323             CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS mouse\n"
    324                 << "OIS error message: \"" << ex.eText << "\"\n Proceeding without mouse support." << std::endl;
    325             mouse_ = 0;
    326         }
    327     }
    328 
    329     /**
    330     @brief
    331         Creates all joy sticks and sets the event handler.
    332     @return
    333         False joy stick stay uninitialised, true otherwise.
    334     */
    335     void InputManager::_initialiseJoySticks()
    336     {
    337         if (joySticksSize_ > 0)
    338         {
    339             CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
    340             return;
    341         }
    342         if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
    343         {
    344             for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
    345             {
    346                 try
    347                 {
    348                     OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
    349                         (inputSystem_->createInputObject(OIS::OISJoyStick, true));
    350                     CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
    351                     joySticks_.push_back(stig);
    352                     // register our listener in OIS.
    353                     stig->setEventCallback(this);
    354                 }
    355                 catch (OIS::Exception ex)
    356                 {
    357                     CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n"
    358                         << "OIS error message: \"" << ex.eText << "\"" << std::endl;
    359                 }
    360             }
    361         }
    362     }
    363 
    364     /**
    365     @brief
    366         Helper function that loads the config value vector of one coefficient
    367     */
    368     void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
    369     {
    370         list.resize(size);
    371         unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
    372         if (configValueVectorSize > size)
    373             configValueVectorSize = size;
    374 
    375         for (unsigned int i = 0; i < configValueVectorSize; ++i)
    376         {
    377             list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
    378                 ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
    379         }
    380 
    381         // fill the rest with default values
    382         for (unsigned int i = configValueVectorSize; i < size; ++i)
    383         {
    384             list[i] = defaultValue;
    385         }
    386     }
    387 
    388     /**
    389     @brief
    390         Sets the size of all the different lists that are dependent on the number
    391         of joy stick devices created and loads the joy stick calibration.
    392     @remarks
    393         No matter whether there are a mouse and/or keyboard, they will always
    394         occupy 2 places in the device number dependent lists.
    395     */
    396     void InputManager::_configureJoySticks()
    397     {
    398         joySticksSize_ = joySticks_.size();
    399         devicesNum_    = 2 + joySticksSize_;
    400         joyStickIDs_         .resize(joySticksSize_);
    401         joyStickButtonsDown_ .resize(joySticksSize_);
    402         povStates_           .resize(joySticksSize_);
    403         sliderStates_        .resize(joySticksSize_);
    404         joyStickMinValues_   .resize(joySticksSize_);
    405         joyStickMaxValues_   .resize(joySticksSize_);
    406         joyStickMiddleValues_.resize(joySticksSize_);
    407         joyStickCalibrations_.resize(joySticksSize_);
    408 
    409         for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
    410         {
    411             // Generate some sort of execution unique id per joy stick
    412             std::string id = "JoyStick_";
    413             id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Button))  + "_";
    414             id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis))    + "_";
    415             id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Slider))  + "_";
    416             id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_POV))     + "_";
    417             id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Vector3)) + "_";
    418             id += joySticks_[iJoyStick]->vendor();
    419             for (unsigned int i = 0; i < iJoyStick; ++i)
    420             {
    421                 if (id == joyStickIDs_[i])
    422                 {
    423                     // Two joysticks are probably equal --> add the index as well
    424                     id += "_" + multi_cast<std::string>(iJoyStick);
    425                 }
    426             }
    427             joyStickIDs_[iJoyStick] = id;
    428 
    429             size_t axes = sliderAxes + (size_t)this->joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis);
    430             loadCalibration(joyStickMinValues_[iJoyStick], id, "MinValue", axes, -32768);
    431             loadCalibration(joyStickMaxValues_[iJoyStick], id, "MaxValue", axes,  32768);
    432             loadCalibration(joyStickMiddleValues_[iJoyStick], id, "MiddleValue", axes,      0);
    433         }
    434 
    435         _evaluateCalibration();
    436 
    437         // state management
    438         activeStatesTriggered_.resize(devicesNum_);
    439 
    440         // inform all states
    441         for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
    442             it != inputStatesByName_.end(); ++it)
    443         {
    444             it->second->setNumOfJoySticks(joySticksSize_);
    445         }
    446 
    447         // inform all JoyStick Device Number Listeners
    448         for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
    449             it->JoyStickDeviceNumberChanged(joySticksSize_);
    450 
    451     }
    452 
    453     void InputManager::_evaluateCalibration()
    454     {
    455         for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
    456         {
    457             for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); i++)
    458             {
    459                 this->joyStickCalibrations_[iJoyStick].middleValue[i] = this->joyStickMiddleValues_[iJoyStick][i];
    460                 this->joyStickCalibrations_[iJoyStick].negativeCoeff[i] = - 1.0f / (this->joyStickMinValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
    461                 this->joyStickCalibrations_[iJoyStick].positiveCoeff[i] =   1.0f / (this->joyStickMaxValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
    462             }
    463         }
    464     }
    465 
    466     void InputManager::_startCalibration()
    467     {
    468         for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
    469         {
    470             // Set initial values
    471             for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); ++i)
    472                 this->joyStickMinValues_[iJoyStick][i] = INT_MAX;
    473             for (unsigned int i = 0; i < this->joyStickMaxValues_[iJoyStick].size(); ++i)
    474                 this->joyStickMaxValues_[iJoyStick][i] = INT_MIN;
    475             for (unsigned int i = 0; i < this->joyStickMiddleValues_[iJoyStick].size(); ++i)
    476                 this->joyStickMiddleValues_[iJoyStick][i] = 0;
    477         }
    478 
    479         getInstance().internalState_ |= Calibrating;
    480         getInstance().requestEnterState("calibrator");
    481     }
    482 
    483     void InputManager::_completeCalibration()
    484     {
    485         for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
    486         {
    487             // Get the middle positions now
    488             unsigned int iAxis = 0;
    489             for (unsigned int i = 0; i < sliderAxes/2; ++i)
    490             {
    491                 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abX;
    492                 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abY;
    493             }
    494             // Note: joyStickMiddleValues_[iJoyStick] was already correctly resized in _configureJoySticks()
    495             assert(joySticks_[iJoyStick]->getJoyStickState().mAxes.size() == joyStickMiddleValues_[iJoyStick].size() - sliderAxes);
    496             for (unsigned int i = 0; i < joyStickMiddleValues_[iJoyStick].size() - sliderAxes; ++i)
    497             {
    498                 this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mAxes[i].abs;
    499             }
    500 
    501             for (unsigned int i = 0; i < joyStickMinValues_[iJoyStick].size(); ++i)
    502             {
    503                 // Minimum values
    504                 if (joyStickMinValues_[iJoyStick][i] == INT_MAX)
    505                     joyStickMinValues_[iJoyStick][i] = -32768;
    506                 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    507                     this->joyStickIDs_[iJoyStick], "MinValue", i, multi_cast<std::string>(joyStickMinValues_[iJoyStick][i]), false);
    508 
    509                 // Maximum values
    510                 if (joyStickMaxValues_[iJoyStick][i] == INT_MIN)
    511                     joyStickMaxValues_[iJoyStick][i] = 32767;
    512                 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    513                     this->joyStickIDs_[iJoyStick], "MaxValue", i, multi_cast<std::string>(joyStickMaxValues_[iJoyStick][i]), false);
    514 
    515                 // Middle values
    516                 ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    517                     this->joyStickIDs_[iJoyStick], "MiddleValue", i, multi_cast<std::string>(joyStickMiddleValues_[iJoyStick][i]), false);
    518             }
    519         }
    520 
    521         _evaluateCalibration();
    522 
    523         // restore old input state
    524         requestLeaveState("calibrator");
    525         internalState_ &= ~Calibrating;
    526     }
    527 
    528     // ############################################################
    529     // #####                    Destruction                   #####
    530     // ##########                                        ##########
    531     // ############################################################
    532 
    533     /**
    534     @brief
    535         Destroys all the created input devices and states.
    536     */
    537     InputManager::~InputManager()
    538     {
    539         if (internalState_ != Uninitialised)
    540         {
    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 
    568             try
    569             {
    570                 OIS::InputManager::destroyInputSystem(inputSystem_);
    571             }
    572             catch (...)
    573             {
    574                 CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
    575             }
    576         }
    577 
    578         singletonRef_s = 0;
    579     }
    580 
    581     /**
    582     @brief
    583         Destroys the keyboard and sets it to 0.
    584     */
    585     void InputManager::_destroyKeyboard()
    586     {
    587         assert(inputSystem_);
    588         try
    589         {
    590             if (keyboard_)
    591                 inputSystem_->destroyInputObject(keyboard_);
    592             keyboard_ = 0;
    593             CCOUT(4) << "Keyboard destroyed." << std::endl;
     333            OIS::InputManager::destroyInputSystem(oisInputManager_);
    594334        }
    595335        catch (...)
    596336        {
    597             CCOUT(1) << "Keyboard destruction failed! Potential resource leak!" << std::endl;
    598         }
    599     }
    600 
    601     /**
    602     @brief
    603         Destroys the mouse and sets it to 0.
    604     */
    605     void InputManager::_destroyMouse()
    606     {
    607         assert(inputSystem_);
    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         }
    619     }
    620 
    621     /**
    622     @brief
    623         Destroys all the joy sticks and resizes the lists to 0.
    624     */
    625     void InputManager::_destroyJoySticks()
    626     {
    627         if (joySticksSize_ > 0)
    628         {
    629             assert(inputSystem_);
    630             for (unsigned int i = 0; i < joySticksSize_; 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             }
    642 
    643             joySticks_.clear();
    644             // don't use _configureNumberOfJoySticks(), might mess with registered handler if
    645             // downgrading from 2 to 1 joystick
    646             //_configureNumberOfJoySticks();
    647             joySticksSize_ = 0;
    648         }
    649         CCOUT(4) << "Joy sticks destroyed." << std::endl;
    650     }
    651 
    652     /**
    653     @brief
    654         Removes and destroys an InputState.
    655     @return
    656         True if state was removed immediately, false if postponed.
    657     */
    658     void InputManager::_destroyState(InputState* state)
    659     {
    660         assert(state && !(this->internalState_ & Ticking));
    661         std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
    662         if (it != this->activeStates_.end())
    663         {
    664             this->activeStates_.erase(it);
    665             _updateActiveStates();
    666         }
    667         inputStatesByName_.erase(state->getName());
    668         delete state;
    669     }
    670 
    671     void InputManager::_clearBuffers()
    672     {
    673         keysDown_.clear();
    674         keyboardModifiers_ = 0;
    675         mouseButtonsDown_.clear();
    676         for (unsigned int i = 0; i < joySticksSize_; ++i)
    677         {
    678             joyStickButtonsDown_[i].clear();
    679             for (int j = 0; j < 4; ++j)
    680             {
    681                 sliderStates_[i].sliderStates[j].x = 0;
    682                 sliderStates_[i].sliderStates[j].y = 0;
    683                 povStates_[i][j] = 0;
    684             }
    685         }
    686     }
    687 
     337            CCOUT(1) << "OIS::InputManager destruction failed! Potential resource leak!" << std::endl;
     338        }
     339        oisInputManager_ = NULL;
     340
     341        internalState_ |= Bad;
     342        CCOUT(3) << "Destroyed devices." << std::endl;
     343    }
    688344
    689345    // ############################################################
     
    692348    // ############################################################
    693349
    694     /**
    695     @brief
    696         Public interface. Only reloads immediately if the call stack doesn't
    697         include the update() method.
    698     @param joyStickSupport
    699         Whether or not to initialise joy sticks as well.
    700     */
    701     void InputManager::reloadInputSystem(bool joyStickSupport)
     350    void InputManager::reload()
    702351    {
    703352        if (internalState_ & Ticking)
    704353        {
    705354            // We cannot destroy OIS right now, because reload was probably
    706             // caused by a user clicking on a GUI item. The backtrace would then
     355            // caused by a user clicking on a GUI item. The stack trace would then
    707356            // include an OIS method. So it would be a very bad thing to destroy it..
    708357            internalState_ |= ReloadRequest;
    709             // Misuse of internalState_: We can easily store the joyStickSupport bool.
    710             // use Uninitialised as 0 value in order to make use of the overloaded |= operator
    711             internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
    712         }
    713         else if (internalState_ & OISReady)
    714         {
    715             _reload(joyStickSupport);
    716         }
     358        }
     359        else if (internalState_ & Calibrating)
     360            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
    717361        else
    718         {
    719             CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or"
    720                      << "joy sticks are currently calibrating." << std::endl;
    721         }
    722     }
    723 
    724     /**
    725     @brief
    726         Internal reload method. Destroys the OIS devices and loads them again.
    727     */
    728     void InputManager::_reload(bool joyStickSupport)
    729     {
    730         try
    731         {
    732             CCOUT(3) << "Reloading ..." << std::endl;
    733 
    734             // Save mouse clipping size
    735             int mouseWidth  = mouse_->getMouseState().width;
    736             int mouseHeight = mouse_->getMouseState().height;
    737 
    738             internalState_ &= ~OISReady;
    739 
    740             // destroy the devices
    741             _destroyKeyboard();
    742             _destroyMouse();
    743             _destroyJoySticks();
    744 
    745             OIS::InputManager::destroyInputSystem(inputSystem_);
    746             inputSystem_ = 0;
    747 
    748             // clear all buffers containing input information
    749             _clearBuffers();
    750 
    751             initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport);
    752 
    753             CCOUT(3) << "Reloading done." << std::endl;
    754         }
    755         catch (OIS::Exception& ex)
    756         {
    757             CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl;
    758         }
     362            reloadInternal();
     363    }
     364
     365    //! Internal reload method. Destroys the OIS devices and loads them again.
     366    void InputManager::reloadInternal()
     367    {
     368        CCOUT(3) << "Reloading ..." << std::endl;
     369
     370        this->destroyDevices();
     371        this->loadDevices(windowHnd_);
     372
     373        internalState_ &= ~Bad;
     374        internalState_ &= ~ReloadRequest;
     375        CCOUT(3) << "Reloading complete." << std::endl;
    759376    }
    760377
     
    764381    // ############################################################
    765382
    766     /**
    767     @brief
    768         Updates the states and the InputState situation.
    769     @param time
    770         Clock holding the current time.
    771     */
    772383    void InputManager::update(const Clock& time)
    773384    {
    774         if (internalState_ == Uninitialised)
    775             return;
     385        if (internalState_ & Bad)
     386            ThrowException(General, "InputManager was not correctly reloaded.");
     387
    776388        else if (internalState_ & ReloadRequest)
    777         {
    778             _reload(internalState_ & JoyStickSupport);
    779             internalState_ &= ~ReloadRequest;
    780             internalState_ &= ~JoyStickSupport;
    781         }
     389            reloadInternal();
    782390
    783391        // check for states to leave
     
    787395                it != stateLeaveRequests_.end(); ++it)
    788396            {
    789                 (*it)->onLeave();
     397                (*it)->left();
    790398                // just to be sure that the state actually is registered
    791                 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
     399                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
    792400
    793401                activeStates_.erase((*it)->getPriority());
    794402                if ((*it)->getPriority() < InputStatePriority::HighPriority)
    795403                    (*it)->setPriority(0);
    796                 _updateActiveStates();
     404                updateActiveStates();
    797405            }
    798406            stateLeaveRequests_.clear();
     
    806414            {
    807415                // just to be sure that the state actually is registered
    808                 assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
     416                assert(statesByName_.find((*it)->getName()) != statesByName_.end());
    809417
    810418                if ((*it)->getPriority() == 0)
    811419                {
    812420                    // Get smallest possible priority between 1 and maxStateStackSize_s
    813 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
    814421                    for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
    815422                        rit != activeStates_.rend(); ++rit)
    816 #else
    817                     for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();
    818                         rit != activeStates_.rend(); ++rit)
    819 #endif
    820423                    {
    821424                        if (rit->first < InputStatePriority::HighPriority)
     
    830433                }
    831434                activeStates_[(*it)->getPriority()] = (*it);
    832                 _updateActiveStates();
    833                 (*it)->onEnter();
     435                updateActiveStates();
     436                (*it)->entered();
    834437            }
    835438            stateEnterRequests_.clear();
     
    842445                it != stateDestroyRequests_.end(); ++it)
    843446            {
    844                 _destroyState((*it));
     447                destroyStateInternal((*it));
    845448            }
    846449            stateDestroyRequests_.clear();
    847450        }
    848451
    849         // check whether a state has changed its EMPTY_HANDLER situation
     452        // check whether a state has changed its EMPTY situation
    850453        bool bUpdateRequired = false;
    851454        for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
    852455        {
    853             if (it->second->handlersChanged())
    854             {
    855                 it->second->resetHandlersChanged();
     456            if (it->second->hasExpired())
     457            {
     458                it->second->resetExpiration();
    856459                bUpdateRequired = true;
    857460            }
    858461        }
    859462        if (bUpdateRequired)
    860             _updateActiveStates();
     463            updateActiveStates();
    861464
    862465        // mark that we now start capturing and distributing input
    863466        internalState_ |= Ticking;
    864467
    865         // Capture all the input. This calls the event handlers in InputManager.
    866         if (keyboard_)
    867             keyboard_->capture();
    868         if (mouse_)
    869             mouse_->capture();
    870         for (unsigned  int i = 0; i < joySticksSize_; i++)
    871             joySticks_[i]->capture();
    872 
    873         if (!(internalState_ & Calibrating))
    874         {
    875             // call all the handlers for the held key events
    876             for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
    877             {
    878                 KeyEvent kEvt(keysDown_[iKey], keyboardModifiers_);
    879 
    880                 for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
    881                     activeStatesTriggered_[Keyboard][iState]->keyHeld(kEvt);
    882             }
    883 
    884             // call all the handlers for the held mouse button events
    885             for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
    886             {
    887                 for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
    888                     activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
    889             }
    890 
    891             // call all the handlers for the held joy stick button events
    892             for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
    893                 for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
    894                 {
    895                     for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
    896                         activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
    897                 }
    898 
    899             // update the handlers for each active handler
    900             for (unsigned int i = 0; i < devicesNum_; ++i)
    901             {
    902                 for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
    903                     activeStatesTriggered_[i][iState]->updateInput(time.getDeltaTime(), i);
    904             }
    905 
    906             // update the handler with a general tick afterwards
    907             for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
    908                 activeStatesTicked_[i]->updateInput(time.getDeltaTime());
    909         }
     468        // Capture all the input and handle it
     469        BOOST_FOREACH(InputDevice* device, devices_)
     470            if (device != NULL)
     471                device->update(time);
     472
     473        // Update the states
     474        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
     475            activeStatesTicked_[i]->update(time.getDeltaTime());
    910476
    911477        internalState_ &= ~Ticking;
     
    917483        Also, a list of all active states (no duplicates!) is compiled for the general update().
    918484    */
    919     void InputManager::_updateActiveStates()
    920     {
    921         for (unsigned int i = 0; i < devicesNum_; ++i)
    922         {
     485    void InputManager::updateActiveStates()
     486    {
     487        // temporary resize
     488        for (unsigned int i = 0; i < devices_.size(); ++i)
     489        {
     490            if (devices_[i] == NULL)
     491                continue;
     492            std::vector<InputState*>& states = devices_[i]->getStateListRef();
    923493            bool occupied = false;
    924             activeStatesTriggered_[i].clear();
    925 #if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
     494            states.clear();
    926495            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
    927496            {
    928 #else
    929             for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
    930             {
    931 #endif
    932497                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
    933498                {
    934                     activeStatesTriggered_[i].push_back(rit->second);
     499                    states.push_back(rit->second);
    935500                    if (!rit->second->bTransparent_)
    936501                        occupied = true;
     
    942507        // Using a std::set to avoid duplicates
    943508        std::set<InputState*> tempSet;
    944         for (unsigned int i = 0; i < devicesNum_; ++i)
    945             for (unsigned int iState = 0; iState < activeStatesTriggered_[i].size(); ++iState)
    946                 tempSet.insert(activeStatesTriggered_[i][iState]);
     509        for (unsigned int i = 0; i < devices_.size(); ++i)
     510            if (devices_[i] != NULL)
     511                for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
     512                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
    947513
    948514        // copy the content of the std::set back to the actual vector
     
    950516        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
    951517            activeStatesTicked_.push_back(*it);
    952 
    953         this->mouseButtonsDown_.clear();
    954     }
    955 
    956     /**
    957     @brief
    958         Clears all buffers that store what keys/buttons are being pressed at the moment.
    959     */
     518    }
     519
    960520    void InputManager::clearBuffers()
    961521    {
    962         this->keysDown_.clear();
    963         this->mouseButtonsDown_.clear();
    964         for (unsigned int i = 0; i < this->joySticksSize_; ++i)
    965             this->joyStickButtonsDown_[i].clear();
    966     }
    967 
    968 
    969     // ############################################################
    970     // #####                    OIS events                    #####
     522        BOOST_FOREACH(InputDevice* device, devices_)
     523            if (device != NULL)
     524                device->clearBuffers();
     525    }
     526
     527    void InputManager::calibrate()
     528    {
     529        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
     530                << "When done, put the axex in the middle position and press enter." << std::endl;
     531
     532        BOOST_FOREACH(InputDevice* device, devices_)
     533            if (device != NULL)
     534                device->startCalibration();
     535
     536        internalState_ |= Calibrating;
     537        enterState("calibrator");
     538    }
     539
     540    //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well!
     541    void InputManager::stopCalibration()
     542    {
     543        BOOST_FOREACH(InputDevice* device, devices_)
     544            if (device != NULL)
     545                device->stopCalibration();
     546
     547        // restore old input state
     548        leaveState("calibrator");
     549        internalState_ &= ~Calibrating;
     550        // Clear buffers to prevent button hold events
     551        this->clearBuffers();
     552
     553        COUT(0) << "Calibration has been stored." << std::endl;
     554    }
     555
     556    //! Gets called by WindowEventListener upon focus change --> clear buffers
     557    void InputManager::windowFocusChanged()
     558    {
     559        this->clearBuffers();
     560    }
     561
     562    // ############################################################
     563    // #####                    Iput States                   #####
    971564    // ##########                                        ##########
    972565    // ############################################################
    973566
    974     // ###### Key Events ######
    975 
    976     /**
    977     @brief
    978         Event handler for the keyPressed Event.
    979     @param e
    980         Event information
    981     */
    982     bool InputManager::keyPressed(const OIS::KeyEvent &e)
    983     {
    984         // check whether the key already is in the list (can happen when focus was lost)
    985         unsigned int iKey = 0;
    986         while (iKey < keysDown_.size() && keysDown_[iKey].key != (KeyCode::ByEnum)e.key)
    987             iKey++;
    988         if (iKey == keysDown_.size())
    989             keysDown_.push_back(Key(e));
    990         else
    991         {
    992             // This happens when XAutoRepeat is set under linux. The KeyPressed event gets then sent
    993             // continuously.
    994             return true;
    995         }
    996 
    997         // update modifiers
    998         if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
    999             keyboardModifiers_ |= KeyboardModifier::Alt;   // alt key
    1000         if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
    1001             keyboardModifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
    1002         if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
    1003             keyboardModifiers_ |= KeyboardModifier::Shift; // shift key
    1004 
    1005         KeyEvent kEvt(e, keyboardModifiers_);
    1006         for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
    1007             activeStatesTriggered_[Keyboard][iState]->keyPressed(kEvt);
    1008 
    1009         return true;
    1010     }
    1011 
    1012     /**
    1013     @brief
    1014         Event handler for the keyReleased Event.
    1015     @param e
    1016         Event information
    1017     */
    1018     bool InputManager::keyReleased(const OIS::KeyEvent &e)
    1019     {
    1020         // remove the key from the keysDown_ list
    1021         for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
    1022         {
    1023             if (keysDown_[iKey].key == (KeyCode::ByEnum)e.key)
    1024             {
    1025                 keysDown_.erase(keysDown_.begin() + iKey);
    1026                 break;
    1027             }
    1028         }
    1029 
    1030         // update modifiers
    1031         if(e.key == OIS::KC_RMENU    || e.key == OIS::KC_LMENU)
    1032             keyboardModifiers_ &= ~KeyboardModifier::Alt;   // alt key
    1033         if(e.key == OIS::KC_RCONTROL || e.key == OIS::KC_LCONTROL)
    1034             keyboardModifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
    1035         if(e.key == OIS::KC_RSHIFT   || e.key == OIS::KC_LSHIFT)
    1036             keyboardModifiers_ &= ~KeyboardModifier::Shift; // shift key
    1037 
    1038         KeyEvent kEvt(e, keyboardModifiers_);
    1039         for (unsigned int iState = 0; iState < activeStatesTriggered_[Keyboard].size(); ++iState)
    1040             activeStatesTriggered_[Keyboard][iState]->keyReleased(kEvt);
    1041 
    1042         return true;
    1043     }
    1044 
    1045 
    1046     // ###### Mouse Events ######
    1047 
    1048     /**
    1049     @brief
    1050         Event handler for the mouseMoved Event.
    1051     @param e
    1052         Event information
    1053     */
    1054     bool InputManager::mouseMoved(const OIS::MouseEvent &e)
    1055     {
    1056         // check for actual moved event
    1057         if (e.state.X.rel != 0 || e.state.Y.rel != 0)
    1058         {
    1059             IntVector2 abs(e.state.X.abs, e.state.Y.abs);
    1060             IntVector2 rel(e.state.X.rel, e.state.Y.rel);
    1061             IntVector2 clippingSize(e.state.width, e.state.height);
    1062             for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
    1063                 activeStatesTriggered_[Mouse][iState]->mouseMoved(abs, rel, clippingSize);
    1064         }
    1065 
    1066         // check for mouse scrolled event
    1067         if (e.state.Z.rel != 0)
    1068         {
    1069             for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
    1070                 activeStatesTriggered_[Mouse][iState]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
    1071         }
    1072 
    1073         return true;
    1074     }
    1075 
    1076     /**
    1077     @brief
    1078         Event handler for the mousePressed Event.
    1079     @param e
    1080         Event information
    1081     @param id
    1082         The ID of the mouse button
    1083     */
    1084     bool InputManager::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
    1085     {
    1086         // check whether the button already is in the list (can happen when focus was lost)
    1087         unsigned int iButton = 0;
    1088         while (iButton < mouseButtonsDown_.size() && mouseButtonsDown_[iButton] != (MouseButtonCode::ByEnum)id)
    1089             iButton++;
    1090         if (iButton == mouseButtonsDown_.size())
    1091             mouseButtonsDown_.push_back((MouseButtonCode::ByEnum)id);
    1092 
    1093         for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
    1094             activeStatesTriggered_[Mouse][iState]->mouseButtonPressed((MouseButtonCode::ByEnum)id);
    1095 
    1096         return true;
    1097     }
    1098 
    1099     /**
    1100     @brief
    1101         Event handler for the mouseReleased Event.
    1102     @param e
    1103         Event information
    1104     @param id
    1105         The ID of the mouse button
    1106     */
    1107     bool InputManager::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
    1108     {
    1109         // remove the button from the keysDown_ list
    1110         for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
    1111         {
    1112             if (mouseButtonsDown_[iButton] == (MouseButtonCode::ByEnum)id)
    1113             {
    1114                 mouseButtonsDown_.erase(mouseButtonsDown_.begin() + iButton);
    1115                 break;
    1116             }
    1117         }
    1118 
    1119         for (unsigned int iState = 0; iState < activeStatesTriggered_[Mouse].size(); ++iState)
    1120             activeStatesTriggered_[Mouse][iState]->mouseButtonReleased((MouseButtonCode::ByEnum)id);
    1121 
    1122         return true;
    1123     }
    1124 
    1125 
    1126     // ###### Joy Stick Events ######
    1127 
    1128     /**
    1129     @brief
    1130         Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent
    1131     */
    1132     inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
    1133     {
    1134         // use the device to identify which one called the method
    1135         OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    1136         unsigned int iJoyStick = 0;
    1137         while (joySticks_[iJoyStick] != joyStick)
    1138             iJoyStick++;
    1139         // assert: Unknown joystick fired an event.
    1140         assert(iJoyStick != joySticksSize_);
    1141         return iJoyStick;
    1142     }
    1143 
    1144     bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
    1145     {
    1146         unsigned int iJoyStick = _getJoystick(arg);
    1147 
    1148         // check whether the button already is in the list (can happen when focus was lost)
    1149         std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    1150         unsigned int iButton = 0;
    1151         while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
    1152             iButton++;
    1153         if (iButton == buttonsDown.size())
    1154             buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
    1155 
    1156         for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
    1157             activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
    1158 
    1159         return true;
    1160     }
    1161 
    1162     bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
    1163     {
    1164         unsigned int iJoyStick = _getJoystick(arg);
    1165 
    1166         // remove the button from the joyStickButtonsDown_ list
    1167         std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    1168         for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
    1169         {
    1170             if (buttonsDown[iButton] == button)
    1171             {
    1172                 buttonsDown.erase(buttonsDown.begin() + iButton);
    1173                 break;
    1174             }
    1175         }
    1176 
    1177         for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
    1178             activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
    1179 
    1180         return true;
    1181     }
    1182 
    1183     /**
    1184     @brief
    1185         Calls the states for a particular axis with our enumeration.
    1186         Used by OIS sliders and OIS axes.
    1187     */
    1188     void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
    1189     {
    1190         if (internalState_ & Calibrating)
    1191         {
    1192             if (value < joyStickMinValues_[iJoyStick][axis])
    1193                 joyStickMinValues_[iJoyStick][axis] = value;
    1194             if (value > joyStickMaxValues_[iJoyStick][axis])
    1195                 joyStickMaxValues_[iJoyStick][axis] = value;
    1196         }
    1197         else
    1198         {
    1199             float fValue = static_cast<float>(value - joyStickCalibrations_[iJoyStick].middleValue[axis]);
    1200             if (fValue > 0.0f)
    1201                 fValue *= joyStickCalibrations_[iJoyStick].positiveCoeff[axis];
    1202             else
    1203                 fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
    1204 
    1205             for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
    1206                 activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
    1207         }
    1208     }
    1209 
    1210     bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
    1211     {
    1212         unsigned int iJoyStick = _getJoystick(arg);
    1213 
    1214         // keep in mind that the first 8 axes are reserved for the sliders
    1215         _fireAxis(iJoyStick, axis + sliderAxes, arg.state.mAxes[axis].abs);
    1216 
    1217         return true;
    1218     }
    1219 
    1220     bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
    1221     {
    1222         unsigned int iJoyStick = _getJoystick(arg);
    1223 
    1224         if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
    1225             _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
    1226         else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
    1227             _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
    1228 
    1229         return true;
    1230     }
    1231 
    1232     bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
    1233     {
    1234         unsigned int iJoyStick = _getJoystick(arg);
    1235 
    1236         // translate the POV into 8 simple buttons
    1237 
    1238         int lastState = povStates_[iJoyStick][id];
    1239         if (lastState & OIS::Pov::North)
    1240             buttonReleased(arg, 32 + id * 4 + 0);
    1241         if (lastState & OIS::Pov::South)
    1242             buttonReleased(arg, 32 + id * 4 + 1);
    1243         if (lastState & OIS::Pov::East)
    1244             buttonReleased(arg, 32 + id * 4 + 2);
    1245         if (lastState & OIS::Pov::West)
    1246             buttonReleased(arg, 32 + id * 4 + 3);
    1247 
    1248         povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
    1249 
    1250         int currentState = povStates_[iJoyStick][id];
    1251         if (currentState & OIS::Pov::North)
    1252             buttonPressed(arg, 32 + id * 4 + 0);
    1253         if (currentState & OIS::Pov::South)
    1254             buttonPressed(arg, 32 + id * 4 + 1);
    1255         if (currentState & OIS::Pov::East)
    1256             buttonPressed(arg, 32 + id * 4 + 2);
    1257         if (currentState & OIS::Pov::West)
    1258             buttonPressed(arg, 32 + id * 4 + 3);
    1259 
    1260         return true;
    1261     }
    1262 
    1263 
    1264     // ############################################################
    1265     // #####         Other Public Interface Methods           #####
    1266     // ##########                                        ##########
    1267     // ############################################################
    1268 
    1269     /**
    1270     @brief
    1271         Adjusts the mouse window metrics.
    1272         This method has to be called every time the size of the window changes.
    1273     @param width
    1274         The new width of the render window
    1275     @param^height
    1276         The new height of the render window
    1277     */
    1278     void InputManager::setWindowExtents(const int width, const int height)
    1279     {
    1280         if (mouse_)
    1281         {
    1282             // Set mouse region (if window resizes, we should alter this to reflect as well)
    1283             mouse_->getMouseState().width  = width;
    1284             mouse_->getMouseState().height = height;
    1285         }
    1286     }
    1287 
    1288     /**
    1289     @brief
    1290         Sets the the name of the command used by the KeyDetector as callback.
    1291     @param command
    1292         Command name as string
    1293     */
    1294     void InputManager::setKeyDetectorCallback(const std::string& command)
    1295     {
    1296         this->keyDetector_->setCallbackCommand(command);
    1297     }
    1298 
    1299     // ###### InputStates ######
    1300 
    1301     /**
    1302     @brief
    1303         Adds a new key handler.
    1304     @param handler
    1305         Pointer to the handler object.
    1306     @param name
    1307         Unique name of the handler.
    1308     @param priority
    1309         Determines which InputState gets the input. Higher is better.
    1310         Use 0 to handle it implicitely by the order of activation.
    1311         Otherwise numbers larger than maxStateStackSize_s have to be used!
    1312     @return
    1313         True if added, false if name or priority already existed.
    1314     */
    1315     bool InputManager::_configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority)
     567    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
    1316568    {
    1317569        if (name == "")
    1318             return false;
    1319         if (!state)
    1320             return false;
    1321         if (inputStatesByName_.find(name) == inputStatesByName_.end())
     570            return 0;
     571        if (statesByName_.find(name) == statesByName_.end())
    1322572        {
    1323573            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
    1324574            {
    1325575                // Make sure we don't add two high priority states with the same priority
    1326                 for (std::map<std::string, InputState*>::const_iterator it = this->inputStatesByName_.begin();
    1327                     it != this->inputStatesByName_.end(); ++it)
     576                for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin();
     577                    it != this->statesByName_.end(); ++it)
    1328578                {
    1329579                    if (it->second->getPriority() == priority)
    1330580                    {
    1331581                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
    1332                             << priority << "' != 0." << std::endl;
    1333                         return false;
     582                            << static_cast<int>(priority) << "' != 0." << std::endl;
     583                        return 0;
    1334584                    }
    1335585                }
    1336586            }
    1337             inputStatesByName_[name] = state;
    1338             state->setNumOfJoySticks(numberOfJoySticks());
    1339             state->setName(name);
    1340             state->bAlwaysGetsInput_ = bAlwaysGetsInput;
    1341             state->bTransparent_ = bTransparent;
    1342             if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
    1343                 state->setPriority(priority);
    1344             return true;
     587            InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority);
     588            statesByName_[name] = state;
     589
     590            return state;
    1345591        }
    1346592        else
    1347593        {
    1348594            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
    1349             return false;
    1350         }
    1351     }
    1352 
    1353     /**
    1354     @brief
    1355         Removes and destroys an input state internally.
    1356     @param name
    1357         Name of the handler.
    1358     @return
    1359         True if removal was successful, false if name was not found.
    1360     @remarks
    1361         You can't remove the internal states "empty", "calibrator" and "detector".
    1362         The removal process is being postponed if InputManager::update() is currently running.
    1363     */
    1364     bool InputManager::requestDestroyState(const std::string& name)
    1365     {
    1366         if (name == "empty")
    1367         {
    1368             COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
    1369             return false;
    1370         }
    1371         std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
    1372         if (it != inputStatesByName_.end())
    1373         {
    1374             if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
    1375             {
    1376                 // The state is still active. We have to postpone
    1377                 stateLeaveRequests_.insert(it->second);
    1378                 stateDestroyRequests_.insert(it->second);
    1379             }
    1380             else if (this->internalState_ & Ticking)
    1381             {
    1382                 // cannot remove state while ticking
    1383                 stateDestroyRequests_.insert(it->second);
    1384             }
    1385             else
    1386                 _destroyState(it->second);
    1387 
    1388             return true;
    1389         }
    1390         return false;
    1391     }
    1392 
    1393     /**
    1394     @brief
    1395         Returns the pointer to the requested InputState.
    1396     @param name
    1397         Unique name of the state.
    1398     @return
    1399         Pointer to the instance, 0 if name was not found.
    1400     */
     595            return 0;
     596        }
     597    }
     598
    1401599    InputState* InputManager::getState(const std::string& name)
    1402600    {
    1403         std::map<std::string, InputState*>::iterator it = inputStatesByName_.find(name);
    1404         if (it != inputStatesByName_.end())
     601        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
     602        if (it != statesByName_.end())
    1405603            return it->second;
    1406604        else
     
    1408606    }
    1409607
    1410     /**
    1411     @brief
    1412         Returns the current input state (there might be others active too!)
    1413     @return
    1414         The current highest prioritised active input state.
    1415     */
    1416     InputState* InputManager::getCurrentState()
    1417     {
    1418         return (*activeStates_.rbegin()).second;
    1419     }
    1420 
    1421     /**
    1422     @brief
    1423         Activates a specific input state.
    1424         It might not be really activated if the priority is too low!
    1425     @param name
    1426         Unique name of the state.
    1427     @return
    1428         False if name was not found, true otherwise.
    1429     */
    1430     bool InputManager::requestEnterState(const std::string& name)
     608    bool InputManager::enterState(const std::string& name)
    1431609    {
    1432610        // get pointer from the map with all stored handlers
    1433         std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
    1434         if (it != inputStatesByName_.end())
     611        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
     612        if (it != statesByName_.end())
    1435613        {
    1436614            // exists
     
    1450628    }
    1451629
    1452     /**
    1453     @brief
    1454         Deactivates a specific input state.
    1455     @param name
    1456         Unique name of the state.
    1457     @return
    1458         False if name was not found, true otherwise.
    1459     */
    1460     bool InputManager::requestLeaveState(const std::string& name)
     630    bool InputManager::leaveState(const std::string& name)
    1461631    {
    1462632        if (name == "empty")
     
    1466636        }
    1467637        // get pointer from the map with all stored handlers
    1468         std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.find(name);
    1469         if (it != inputStatesByName_.end())
     638        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
     639        if (it != statesByName_.end())
    1470640        {
    1471641            // exists
     
    1480650    }
    1481651
    1482 
    1483     // ############################################################
    1484     // #####                Console Commands                  #####
    1485     // ##########                                        ##########
    1486     // ############################################################
    1487 
    1488     /**
    1489     @brief
    1490         Starts joy stick calibration.
    1491     */
    1492     void InputManager::calibrate()
    1493     {
    1494         COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
    1495                 << "When done, put the axex in the middle position and press enter." << std::endl;
    1496 
    1497         getInstance()._startCalibration();
    1498     }
    1499 
    1500     /**
    1501     @brief
    1502         Reloads the input system
    1503     */
    1504     void InputManager::reload(bool joyStickSupport)
    1505     {
    1506         getInstance().reloadInputSystem(joyStickSupport);
    1507     }
    1508 
    1509 
    1510     // ############################################################
    1511     // #####                   ugly hacks                     #####
    1512     // ##########                                        ##########
    1513     // ############################################################
    1514 
    1515 #ifdef ORXONOX_PLATFORM_LINUX
    1516     void InputManager::grabMouse()
    1517     {
    1518         OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_);
    1519         assert(linuxMouse);
    1520         linuxMouse->grab(true);
    1521     }
    1522 
    1523     void InputManager::ungrabMouse()
    1524     {
    1525         OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(singletonRef_s->mouse_);
    1526         assert(linuxMouse);
    1527         linuxMouse->grab(false);
    1528     }
    1529 #endif
     652    bool InputManager::destroyState(const std::string& name)
     653    {
     654        if (name == "empty")
     655        {
     656            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
     657            return false;
     658        }
     659        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
     660        if (it != statesByName_.end())
     661        {
     662            if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
     663            {
     664                // The state is still active. We have to postpone
     665                stateLeaveRequests_.insert(it->second);
     666                stateDestroyRequests_.insert(it->second);
     667            }
     668            else if (this->internalState_ & Ticking)
     669            {
     670                // cannot remove state while ticking
     671                stateDestroyRequests_.insert(it->second);
     672            }
     673            else
     674                destroyStateInternal(it->second);
     675
     676            return true;
     677        }
     678        return false;
     679    }
     680
     681    //! Destroys an InputState internally.
     682    void InputManager::destroyStateInternal(InputState* state)
     683    {
     684        assert(state && !(this->internalState_ & Ticking));
     685        std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
     686        if (it != this->activeStates_.end())
     687        {
     688            this->activeStates_.erase(it);
     689            updateActiveStates();
     690        }
     691        statesByName_.erase(state->getName());
     692        delete state;
     693    }
    1530694}
Note: See TracChangeset for help on using the changeset viewer.