Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 10, 2008, 9:43:50 PM (16 years ago)
Author:
rgrieder
Message:

added reloading support for the InputManager. This could be useful when using a GUI and you want to load a joyStick that has just been plugged in.

Location:
code/branches/gui/src/core/input
Files:
2 edited

Legend:

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

    r1653 r1656  
    4545#include "core/ConfigValueIncludes.h"
    4646#include "core/Debug.h"
     47#include "core/Exception.h"
    4748#include "core/CommandExecutor.h"
    4849#include "core/ConsoleCommand.h"
     
    6768    using namespace InputDevice;
    6869
     70    /**
     71    @brief
     72        Defines the |= operator for easier use.
     73    */
     74    inline InputManager::InputManagerState operator|=(InputManager::InputManagerState& lval,
     75                                                      InputManager::InputManagerState rval)
     76    {
     77        return (lval = (InputManager::InputManagerState)(lval | rval));
     78    }
     79
     80    /**
     81    @brief
     82        Defines the &= operator for easier use.
     83    */
     84    inline InputManager::InputManagerState operator&=(InputManager::InputManagerState& lval, int rval)
     85    {
     86        return (lval = (InputManager::InputManagerState)(lval & rval));
     87    }
     88
    6989    // ############################################################
    7090    // #####                  Initialisation                  #####
     
    83103        , joySticksSize_(0)
    84104        , devicesNum_(0)
     105        , windowHnd_(0)
     106        , internalState_(Uninitialised)
    85107        , stateDetector_(0)
    86108        , stateCalibrator_(0)
     
    105127    @param windowHeight
    106128        The height of the render window
    107     */
    108     bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    109                                    bool createKeyboard, bool createMouse, bool createJoySticks)
    110     {
    111         if (inputSystem_ == 0)
     129    @param joyStickSupport
     130        Whether or not to load the joy sticks as well
     131    */
     132    void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
     133    {
     134        if (internalState_ == Uninitialised)
    112135        {
    113136            CCOUT(3) << "Initialising Input System..." << std::endl;
    114137            CCOUT(4) << "Initialising OIS components..." << std::endl;
    115138
     139            // store handle internally so we can reload OIS
     140            windowHnd_ = windowHnd;
     141
    116142            OIS::ParamList paramList;
    117143            std::ostringstream windowHndStr;
    118144
    119145            // Fill parameter list
    120             windowHndStr << (unsigned int)windowHnd;
     146            windowHndStr << (unsigned int)windowHnd_;
    121147            paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
    122148            //paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
     
    126152//#endif
    127153
    128             try
    129             {
    130                 inputSystem_ = OIS::InputManager::createInputSystem(paramList);
    131                 CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
    132             }
    133             catch (OIS::Exception ex)
    134             {
    135                 CCOUT(ORX_ERROR) << "Error: Failed creating an OIS input system."
    136                     << "OIS message: \"" << ex.eText << "\"" << std::endl;
    137                 inputSystem_ = 0;
    138                 return false;
    139             }
    140 
    141             if (createKeyboard)
    142                 _initialiseKeyboard();
    143 
    144             if (createMouse)
    145                 _initialiseMouse();
    146 
    147             if (createJoySticks)
     154            inputSystem_ = OIS::InputManager::createInputSystem(paramList);
     155            CCOUT(ORX_DEBUG) << "Created OIS input system" << std::endl;
     156
     157            _initialiseKeyboard();
     158
     159            _initialiseMouse();
     160
     161            if (joyStickSupport)
    148162                _initialiseJoySticks();
    149 
    150             // set all the std::vector list sizes now that the devices have been created
    151             _redimensionLists();
    152163
    153164            // Set mouse/joystick region
    154165            if (mouse_)
    155             {
    156166                setWindowExtents(windowWidth, windowHeight);
    157             }
     167
     168            // clear all buffers
     169            _clearBuffers();
    158170
    159171            CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
     
    178190            _updateActiveStates();
    179191
     192            internalState_ = Ready;
     193
    180194            CCOUT(3) << "Initialising complete." << std::endl;
    181195        }
     
    184198            CCOUT(2) << "Warning: OIS compoments already initialised, skipping" << std::endl;
    185199        }
    186         return true;
    187200    }
    188201
     
    193206        False if keyboard stays uninitialised, true otherwise.
    194207    */
    195     bool InputManager::_initialiseKeyboard()
     208    void InputManager::_initialiseKeyboard()
    196209    {
    197210        if (keyboard_ != 0)
    198211        {
    199212            CCOUT(2) << "Warning: Keyboard already initialised, skipping." << std::endl;
    200             return true;
    201         }
    202         try
    203         {
    204             if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
    205             {
    206                 keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
    207                 // register our listener in OIS.
    208                 keyboard_->setEventCallback(this);
    209                 // note: OIS will not detect keys that have already been down when the keyboard was created.
    210                 CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
    211                 return true;
    212             }
    213             else
    214             {
    215                 CCOUT(ORX_WARNING) << "Warning: No keyboard found!" << std::endl;
    216                 return false;
    217             }
    218         }
    219         catch (OIS::Exception ex)
    220         {
    221             CCOUT(ORX_WARNING) << "Warning: Failed to create an OIS keyboard\n"
    222                 << "OIS error message: \"" << ex.eText << "\"" << std::endl;
    223             keyboard_ = 0;
    224             return false;
     213            return;
     214        }
     215        if (inputSystem_->getNumberOfDevices(OIS::OISKeyboard) > 0)
     216        {
     217            keyboard_ = (OIS::Keyboard*)inputSystem_->createInputObject(OIS::OISKeyboard, true);
     218            // register our listener in OIS.
     219            keyboard_->setEventCallback(this);
     220            // note: OIS will not detect keys that have already been down when the keyboard was created.
     221            CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
     222        }
     223        else
     224        {
     225            ThrowException(InitialisationFailed, "No keyboard found!");
    225226        }
    226227    }
     
    232233        False if mouse stays uninitialised, true otherwise.
    233234    */
    234     bool InputManager::_initialiseMouse()
     235    void InputManager::_initialiseMouse()
    235236    {
    236237        if (mouse_ != 0)
    237238        {
    238239            CCOUT(2) << "Warning: Mouse already initialised, skipping." << std::endl;
    239             return true;
     240            return;
    240241        }
    241242        try
     
    247248                mouse_->setEventCallback(this);
    248249                CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
    249                 return true;
    250250            }
    251251            else
    252252            {
    253253                CCOUT(ORX_WARNING) << "Warning: No mouse found!" << std::endl;
    254                 return false;
    255254            }
    256255        }
     
    260259                << "OIS error message: \"" << ex.eText << "\"" << std::endl;
    261260            mouse_ = 0;
    262             return false;
    263261        }
    264262    }
     
    270268        False joy stick stay uninitialised, true otherwise.
    271269    */
    272     bool InputManager::_initialiseJoySticks()
     270    void InputManager::_initialiseJoySticks()
    273271    {
    274272        if (joySticksSize_ > 0)
    275273        {
    276274            CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
    277             return true;
    278         }
    279         bool success = false;
     275            return;
     276        }
    280277        if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
    281278        {
     
    290287                    // register our listener in OIS.
    291288                    stig->setEventCallback(this);
    292                     success = true;
    293289                }
    294290                catch (OIS::Exception ex)
     
    301297        else
    302298        {
    303             CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
    304             return false;
    305         }
    306         return success;
     299            //CCOUT(ORX_WARNING) << "Warning: Joy stick support requested, but no joy stick was found" << std::endl;
     300        }
     301        _redimensionLists();
    307302    }
    308303
     
    412407    InputManager::~InputManager()
    413408    {
    414         if (inputSystem_)
     409        if (internalState_ != Uninitialised)
    415410        {
    416411            try
     
    429424                    (*rit).second->onLeave();
    430425                }
    431                 //activeStates_.clear();
    432                 //_updateActiveStates();
    433426
    434427                // destroy all input states
    435428                while (inputStatesByPriority_.size() > 0)
    436                 {
    437429                    _destroyState((*inputStatesByPriority_.rbegin()).second);
    438                 }
    439 
    440                 //stateEmpty_ = 0;
    441                 //stateCalibrator_ = 0;
    442                 //stateDetector_ = 0;
    443430
    444431                // destroy the devices
     
    447434                _destroyJoySticks();
    448435
    449                 // 0 joy sticks now
    450                 //_redimensionLists();
    451 
    452436                OIS::InputManager::destroyInputSystem(inputSystem_);
    453                 //inputSystem_ = 0;
    454437
    455438                CCOUT(3) << "Destroying done." << std::endl;
     
    457440            catch (OIS::Exception& ex)
    458441            {
    459                 CCOUT(1) << "An exception has occured while destroying:\n" << ex.what() << std::endl;
     442                CCOUT(1) << "An exception has occured while destroying:\n" << ex.what()
     443                         << "This could lead to a possible memory/resource leak!" << std::endl;
    460444            }
    461445        }
     
    468452    void InputManager::_destroyKeyboard()
    469453    {
     454        assert(inputSystem_);
    470455        if (keyboard_)
    471456            inputSystem_->destroyInputObject(keyboard_);
    472457        keyboard_ = 0;
    473         keysDown_.clear();
    474458        CCOUT(4) << "Keyboard destroyed." << std::endl;
    475459    }
     
    481465    void InputManager::_destroyMouse()
    482466    {
     467        assert(inputSystem_);
    483468        if (mouse_)
    484469            inputSystem_->destroyInputObject(mouse_);
    485470        mouse_ = 0;
    486         mouseButtonsDown_.clear();
    487471        CCOUT(4) << "Mouse destroyed." << std::endl;
    488472    }
     
    496480        if (joySticksSize_ > 0)
    497481        {
    498             // note: inputSystem_ can never be 0, or else the code is mistaken
     482            assert(inputSystem_);
    499483            for (unsigned int i = 0; i < joySticksSize_; i++)
    500484                if (joySticks_[i] != 0)
     
    520504    }
    521505
     506    void InputManager::_clearBuffers()
     507    {
     508        keysDown_.clear();
     509        keyboardModifiers_ = 0;
     510        mouseButtonsDown_.clear();
     511        for (unsigned int i = 0; i < joySticksSize_; ++i)
     512        {
     513            joyStickButtonsDown_[i].clear();
     514            for (int j = 0; j < 4; ++j)
     515            {
     516                sliderStates_[i].sliderStates[j].x = 0;
     517                sliderStates_[i].sliderStates[j].y = 0;
     518                povStates_[i][j] = 0;
     519            }
     520        }
     521    }
     522
     523
     524    // ############################################################
     525    // #####                     Reloading                    #####
     526    // ##########                                        ##########
     527    // ############################################################
     528
     529    /**
     530    @brief
     531        Public interface. Only reloads immediately if the call stack doesn't
     532        include the tick() method.
     533    @param joyStickSupport
     534        Whether or not to initialise joy sticks as well.
     535    */
     536    void InputManager::reloadInputSystem(bool joyStickSupport)
     537    {
     538        if (internalState_ & Ticking)
     539        {
     540            // We cannot destroy OIS right now, because reload was probably
     541            // caused by a user clicking on a GUI item. The backtrace would then
     542            // include an OIS method. So it would be a very bad thing to destroy it..
     543            internalState_ |= ReloadRequest;
     544            // Misuse of internalState_: We can easily store the joyStickSupport bool.
     545            // use Uninitialised as 0 value in order to use the overloaded |= operator
     546            internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
     547        }
     548        else if (internalState_ == Ready)
     549        {
     550            _reload(joyStickSupport);
     551        }
     552        else
     553        {
     554            CCOUT(2) << "Warning: Cannot reload OIS. May not yet be initialised or"
     555                     << "joy sticks are currently calibrating." << std::endl;
     556        }
     557    }
     558
     559    /**
     560    @brief
     561        Internal reload method. Destroys the OIS devices and loads them again.
     562    */
     563    void InputManager::_reload(bool joyStickSupport)
     564    {
     565        try
     566        {
     567            CCOUT(3) << "Reloading ..." << std::endl;
     568
     569            // Save mouse clipping size
     570            int mouseWidth  = mouse_->getMouseState().width;
     571            int mouseHeight = mouse_->getMouseState().height;
     572
     573            internalState_ = Uninitialised;
     574            // destroy the devices
     575            _destroyKeyboard();
     576            _destroyMouse();
     577            _destroyJoySticks();
     578
     579            OIS::InputManager::destroyInputSystem(inputSystem_);
     580            inputSystem_ = 0;
     581
     582            // clear all buffers containing input information
     583            _clearBuffers();
     584
     585            initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport);
     586
     587            CCOUT(3) << "Reloading done." << std::endl;
     588        }
     589        catch (OIS::Exception& ex)
     590        {
     591            CCOUT(1) << "An exception has occured while reloading:\n" << ex.what() << std::endl;
     592        }
     593    }
    522594
    523595    // ############################################################
     
    534606    void InputManager::tick(float dt)
    535607    {
    536         if (inputSystem_ == 0)
     608        if (internalState_ == Uninitialised)
    537609            return;
     610        else if (internalState_ & ReloadRequest)
     611        {
     612            _reload(internalState_ & JoyStickSupport);
     613            internalState_ &= ~ReloadRequest;
     614            internalState_ &= ~JoyStickSupport;
     615        }
     616        internalState_ |= Ticking;
    538617
    539618        // check for states to leave (don't use unsigned int!)
     
    594673                activeStatesTicked_[i]->tickInput(dt);
    595674        }
     675
     676        internalState_ &= ~Ready;
    596677    }
    597678
  • code/branches/gui/src/core/input/InputManager.h

    r1653 r1656  
    5555    {
    5656    public:
    57         int operator[](unsigned int index) { return povStates[index]; }
     57        int& operator[](unsigned int index) { return povStates[index]; }
    5858        int povStates[4];
    5959    };
     
    9090
    9191    public:
     92        enum InputManagerState
     93        {
     94            Uninitialised    = 0,
     95            Ready            = 1,
     96            Ticking          = 2,
     97            Calibrating      = 4,
     98            ReloadRequest    = 8,
     99            JoyStickSupport  = 16 // used with ReloadRequest to store a bool
     100        };
     101
    92102        InputManager ();
    93103        ~InputManager();
    94104
    95         bool initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    96                                bool createKeyboard = true, bool createMouse = true, bool createJoySticks = false);
     105        void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
     106
     107        void reloadInputSystem(bool joyStickSupport = true);
    97108
    98109        int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
     
    134145
    135146        // Intenal methods
    136         bool _initialiseKeyboard();
    137         bool _initialiseMouse();
    138         bool _initialiseJoySticks();
     147        void _initialiseKeyboard();
     148        void _initialiseMouse();
     149        void _initialiseJoySticks();
    139150        void _redimensionLists();
    140151
     
    143154        void _destroyJoySticks();
    144155        void _destroyState(InputState* state);
     156        void _clearBuffers();
     157
     158        void _reload(bool joyStickSupport);
    145159
    146160        void _completeCalibration();
     
    177191        unsigned int                        joySticksSize_;
    178192        unsigned int                        devicesNum_;
     193        size_t                              windowHnd_;            //!< Render window handle
     194        InputManagerState                   internalState_;        //!< Current internal state
    179195
    180196        // some internally handled states
Note: See TracChangeset for help on using the changeset viewer.