Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 16, 2010, 2:50:16 PM (15 years ago)
Author:
rgrieder
Message:

Merged gamestates2 branch back to trunk.
This brings in some heavy changes in the GUI framework.
It should also fix problems with triggered asserts in the InputManager.

Note: PickupInventory does not seem to work —> Segfault when showing because before, the owner in GUIOverlay::setGUIName is already NULL.
I haven't tested it before, so I can't tell whether it's my changes.

Location:
code/trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/input/InputDevice.h

    r6417 r6746  
    159159            for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
    160160                for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
    161                     inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
     161                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, typename Traits::ButtonTypeParam>(
    162162                        this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
    163163
     
    196196            // Call states
    197197            for (unsigned int i = 0; i < inputStates_.size(); ++i)
    198                 inputStates_[i]->buttonEvent<ButtonEvent::TPress, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
     198                inputStates_[i]->buttonEvent<ButtonEvent::TPress, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
    199199        }
    200200
     
    218218            // Call states
    219219            for (unsigned int i = 0; i < inputStates_.size(); ++i)
    220                 inputStates_[i]->buttonEvent<ButtonEvent::TRelease, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
     220                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
    221221        }
    222222
  • code/trunk/src/libraries/core/input/InputHandler.h

    r6105 r6746  
    112112        virtual ~InputHandler() { }
    113113
    114         template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TPress)
     114        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TPress)
    115115            { this->buttonPressed(button); }
    116         template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::TRelease)
     116        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TRelease)
    117117            { this->buttonReleased(button); }
    118         template<class T> void buttonEvent(unsigned int device, const T& button, ButtonEvent::THold)
     118        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::THold)
    119119            { this->buttonHeld(button); }
    120         void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
    121             { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
    122         void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
    123             { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
    124         void buttonEvent(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
    125             { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
    126120
    127121        virtual void buttonPressed (const KeyEvent& evt) { }
     
    149143        static InputHandler EMPTY;
    150144    };
     145
     146    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
     147        { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
     148    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
     149        { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
     150    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
     151        { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
    151152}
    152153
  • code/trunk/src/libraries/core/input/InputManager.cc

    r6422 r6746  
    8787        , oisInputManager_(0)
    8888        , devices_(2)
    89         , mouseMode_(MouseMode::Nonexclusive)
     89        , exclusiveMouse_(TriBool::False)
    9090        , emptyState_(0)
    9191        , calibratorCallbackHandler_(0)
     
    9595        CCOUT(4) << "Constructing..." << std::endl;
    9696
     97        // Allocate space for the function call buffer
     98        this->callBuffer_.reserve(16);
     99
    97100        this->setConfigValues();
    98101
    99102        if (GraphicsManager::getInstance().isFullScreen())
    100             mouseMode_ = MouseMode::Exclusive;
     103            exclusiveMouse_ = TriBool::True;
    101104        this->loadDevices();
    102105
     
    155158        paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND"));
    156159        paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND"));
    157         if (mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())
     160        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
    158161        {
    159162            // Disable Windows key plus special keys (like play, stop, next, etc.)
     
    168171        paramList.insert(std::make_pair("XAutoRepeatOn", "true"));
    169172
    170         if (mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())
     173        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
    171174        {
    172175            if (CommandLineParser::getValue("keyboard_no_grab").getBool())
     
    266269        CCOUT(3) << "Destroying..." << std::endl;
    267270
     271        // Leave all active InputStates (except "empty")
     272        while (this->activeStates_.size() > 1)
     273            this->leaveState(this->activeStates_.rbegin()->second->getName());
     274        this->activeStates_.clear();
     275
    268276        // Destroy calibrator helper handler and state
    269277        this->destroyState("calibrator");
    270278        // Destroy KeyDetector and state
    271279        calibratorCallbackHandler_->destroy();
    272         // destroy the empty InputState
     280        // Destroy the empty InputState
    273281        this->destroyStateInternal(this->emptyState_);
    274282
    275         // destroy all user InputStates
     283        // Destroy all user InputStates
    276284        while (statesByName_.size() > 0)
    277285            this->destroyStateInternal(statesByName_.rbegin()->second);
     
    335343    void InputManager::reload()
    336344    {
    337         if (internalState_ & Ticking)
    338         {
    339             // We cannot destroy OIS right now, because reload was probably
    340             // caused by a user clicking on a GUI item. The stack trace would then
    341             // include an OIS method. So it would be a very bad thing to destroy it..
    342             internalState_ |= ReloadRequest;
    343         }
    344         else if (internalState_ & Calibrating)
     345        if (internalState_ & Calibrating)
    345346            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
    346347        else
     
    351352    void InputManager::reloadInternal()
    352353    {
    353         CCOUT(3) << "Reloading ..." << std::endl;
     354        CCOUT(4) << "Reloading ..." << std::endl;
    354355
    355356        this->destroyDevices();
     
    357358
    358359        internalState_ &= ~Bad;
    359         internalState_ &= ~ReloadRequest;
    360360        CCOUT(4) << "Reloading complete." << std::endl;
    361361    }
     
    370370        if (internalState_ & Bad)
    371371            ThrowException(General, "InputManager was not correctly reloaded.");
    372 
    373         else if (internalState_ & ReloadRequest)
    374             reloadInternal();
    375 
    376         // check for states to leave
    377         if (!stateLeaveRequests_.empty())
    378         {
    379             for (std::set<InputState*>::iterator it = stateLeaveRequests_.begin();
    380                 it != stateLeaveRequests_.end(); ++it)
    381             {
    382                 (*it)->left();
    383                 // just to be sure that the state actually is registered
    384                 assert(statesByName_.find((*it)->getName()) != statesByName_.end());
    385 
    386                 activeStates_.erase((*it)->getPriority());
    387                 if ((*it)->getPriority() < InputStatePriority::HighPriority)
    388                     (*it)->setPriority(0);
    389                 updateActiveStates();
    390             }
    391             stateLeaveRequests_.clear();
    392         }
    393 
    394         // check for states to enter
    395         if (!stateEnterRequests_.empty())
    396         {
    397             for (std::set<InputState*>::const_iterator it = stateEnterRequests_.begin();
    398                 it != stateEnterRequests_.end(); ++it)
    399             {
    400                 // just to be sure that the state actually is registered
    401                 assert(statesByName_.find((*it)->getName()) != statesByName_.end());
    402 
    403                 if ((*it)->getPriority() == 0)
    404                 {
    405                     // Get smallest possible priority between 1 and maxStateStackSize_s
    406                     for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
    407                         rit != activeStates_.rend(); ++rit)
    408                     {
    409                         if (rit->first < InputStatePriority::HighPriority)
    410                         {
    411                             (*it)->setPriority(rit->first + 1);
    412                             break;
    413                         }
    414                     }
    415                     // In case no normal handler was on the stack
    416                     if ((*it)->getPriority() == 0)
    417                         (*it)->setPriority(1);
    418                 }
    419                 activeStates_[(*it)->getPriority()] = (*it);
    420                 updateActiveStates();
    421                 (*it)->entered();
    422             }
    423             stateEnterRequests_.clear();
    424         }
    425 
    426         // check for states to destroy
    427         if (!stateDestroyRequests_.empty())
    428         {
    429             for (std::set<InputState*>::iterator it = stateDestroyRequests_.begin();
    430                 it != stateDestroyRequests_.end(); ++it)
    431             {
    432                 destroyStateInternal((*it));
    433             }
    434             stateDestroyRequests_.clear();
    435         }
    436372
    437373        // check whether a state has changed its EMPTY situation
     
    448384            updateActiveStates();
    449385
    450         // mark that we now start capturing and distributing input
    451         internalState_ |= Ticking;
    452 
    453         // Capture all the input and handle it
     386        // Capture all the input and collect the function calls
     387        // No event gets triggered here yet!
    454388        BOOST_FOREACH(InputDevice* device, devices_)
    455389            if (device != NULL)
    456390                device->update(time);
    457391
    458         // Update the states
     392        // Collect function calls for the update
    459393        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
    460394            activeStatesTicked_[i]->update(time.getDeltaTime());
    461395
    462         internalState_ &= ~Ticking;
     396        // Execute all cached function calls in order
     397        // Why so complicated? The problem is that an InputHandler could trigger
     398        // a reload that would destroy the OIS devices or it could even leave and
     399        // then destroy its own InputState. That would of course lead to access
     400        // violations.
     401        // If we delay the calls, then OIS and and the InputStates are not anymore
     402        // in the call stack and can therefore be edited.
     403        for (size_t i = 0; i < this->callBuffer_.size(); ++i)
     404            this->callBuffer_[i]();
     405
     406        this->callBuffer_.clear();
    463407    }
    464408
     
    470414    void InputManager::updateActiveStates()
    471415    {
    472         assert((internalState_ & InputManager::Ticking) == 0);
    473         // temporary resize
     416        // Calculate the stack of input states
     417        // and assign it to the corresponding device
    474418        for (unsigned int i = 0; i < devices_.size(); ++i)
    475419        {
     
    490434        }
    491435
    492         // update tickables (every state will only appear once)
    493         // Using a std::set to avoid duplicates
     436        // See that we only update each InputState once for each device
     437        // Using an std::set to avoid duplicates
    494438        std::set<InputState*> tempSet;
    495439        for (unsigned int i = 0; i < devices_.size(); ++i)
     
    498442                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
    499443
    500         // copy the content of the std::set back to the actual vector
     444        // Copy the content of the std::set back to the actual vector
    501445        activeStatesTicked_.clear();
    502446        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
     
    504448
    505449        // Check whether we have to change the mouse mode
    506         MouseMode::Value requestedMode = MouseMode::Dontcare;
     450        TriBool::Value requestedMode = TriBool::Dontcare;
    507451        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
    508452        if (mouseStates.empty())
    509             requestedMode = MouseMode::Nonexclusive;
    510         else
    511             requestedMode = mouseStates.front()->getMouseMode();
    512         if (requestedMode != MouseMode::Dontcare && mouseMode_ != requestedMode)
    513         {
    514             mouseMode_ = requestedMode;
     453            requestedMode = TriBool::False;
     454        else
     455            requestedMode = mouseStates.front()->getMouseExclusive();
     456        if (requestedMode != TriBool::Dontcare && exclusiveMouse_ != requestedMode)
     457        {
     458            exclusiveMouse_ = requestedMode;
    515459            if (!GraphicsManager::getInstance().isFullScreen())
    516460                this->reloadInternal();
     
    622566        // get pointer from the map with all stored handlers
    623567        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
    624         if (it != statesByName_.end())
    625         {
    626             // exists
    627             if (activeStates_.find(it->second->getPriority()) == activeStates_.end())
    628             {
    629                 // not active
    630                 if (stateDestroyRequests_.find(it->second) == stateDestroyRequests_.end())
     568        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) == activeStates_.end())
     569        {
     570            // exists and not active
     571            if (it->second->getPriority() == 0)
     572            {
     573                // Get smallest possible priority between 1 and maxStateStackSize_s
     574                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
     575                    rit != activeStates_.rend(); ++rit)
    631576                {
    632                     // not scheduled for destruction
    633                     // prevents a state from being added multiple times
    634                     stateEnterRequests_.insert(it->second);
    635                     return true;
     577                    if (rit->first < InputStatePriority::HighPriority)
     578                    {
     579                        it->second->setPriority(rit->first + 1);
     580                        break;
     581                    }
    636582                }
    637             }
    638             else if (this->stateLeaveRequests_.find(it->second) != this->stateLeaveRequests_.end())
    639             {
    640                 // State already scheduled for leaving --> cancel
    641                 this->stateLeaveRequests_.erase(this->stateLeaveRequests_.find(it->second));
    642             }
     583                // In case no normal handler was on the stack
     584                if (it->second->getPriority() == 0)
     585                    it->second->setPriority(1);
     586            }
     587            activeStates_[it->second->getPriority()] = it->second;
     588            updateActiveStates();
     589            it->second->entered();
     590
     591            return true;
    643592        }
    644593        return false;
     
    654603        // get pointer from the map with all stored handlers
    655604        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
    656         if (it != statesByName_.end())
    657         {
    658             // exists
    659             if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
    660             {
    661                 // active
    662                 stateLeaveRequests_.insert(it->second);
    663                 return true;
    664             }
    665             else if (this->stateEnterRequests_.find(it->second) != this->stateEnterRequests_.end())
    666             {
    667                 // State already scheduled for entering --> cancel
    668                 this->stateEnterRequests_.erase(this->stateEnterRequests_.find(it->second));
    669             }
     605        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) != activeStates_.end())
     606        {
     607            // exists and active
     608
     609            it->second->left();
     610
     611            activeStates_.erase(it->second->getPriority());
     612            if (it->second->getPriority() < InputStatePriority::HighPriority)
     613                it->second->setPriority(0);
     614            updateActiveStates();
     615
     616            return true;
    670617        }
    671618        return false;
     
    682629        if (it != statesByName_.end())
    683630        {
    684             if (activeStates_.find(it->second->getPriority()) != activeStates_.end())
    685             {
    686                 // The state is still active. We have to postpone
    687                 stateLeaveRequests_.insert(it->second);
    688                 stateDestroyRequests_.insert(it->second);
    689             }
    690             else if (this->internalState_ & Ticking)
    691             {
    692                 // cannot remove state while ticking
    693                 stateDestroyRequests_.insert(it->second);
    694             }
    695             else
    696                 destroyStateInternal(it->second);
     631            this->leaveState(name);
     632            destroyStateInternal(it->second);
    697633
    698634            return true;
     
    704640    void InputManager::destroyStateInternal(InputState* state)
    705641    {
    706         assert(state && !(this->internalState_ & Ticking));
    707         std::map<int, InputState*>::iterator it = this->activeStates_.find(state->getPriority());
    708         if (it != this->activeStates_.end())
    709         {
    710             this->activeStates_.erase(it);
    711             updateActiveStates();
    712         }
     642        assert(state && this->activeStates_.find(state->getPriority()) == this->activeStates_.end());
    713643        statesByName_.erase(state->getName());
    714644        state->destroy();
  • code/trunk/src/libraries/core/input/InputManager.h

    r6417 r6746  
    3636#include <string>
    3737#include <vector>
     38#include <boost/function.hpp>
    3839
    3940#include "util/Singleton.h"
     41#include "util/TriBool.h"
    4042#include "core/WindowEventListener.h"
    41 #include "InputState.h"
    4243
    4344// tolua_begin
     
    7576            Nothing       = 0x00,
    7677            Bad           = 0x02,
    77             Ticking       = 0x04,
    78             Calibrating   = 0x08,
    79             ReloadRequest = 0x10,
     78            Calibrating   = 0x04,
    8079        };
    8180
     
    159158            - The removal process is being postponed if InputManager::preUpdate() is currently running.
    160159        */
    161         bool destroyState(const std::string& name);
     160        bool destroyState(const std::string& name); // tolua_export
    162161
    163162        //-------------------------------
     
    169168        //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
    170169        OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
     170        //! Returns the position of the cursor as std::pair of ints
    171171        std::pair<int, int> getMousePosition() const;
     172        //! Tells whether the mouse is used exclusively to the game
     173        bool isMouseExclusive() const { return this->exclusiveMouse_; } // tolua_export
     174
     175        //-------------------------------
     176        // Function call caching
     177        //-------------------------------
     178        void pushCall(const boost::function<void ()>& function)
     179            { this->callBuffer_.push_back(function); }
    172180
    173181        static InputManager& getInstance() { return Singleton<InputManager>::getInstance(); } // tolua_export
     
    196204        OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
    197205        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
    198         MouseMode::Value                    mouseMode_;            //!< Currently applied mouse mode
     206        TriBool::Value                      exclusiveMouse_;       //!< Currently applied mouse mode
    199207
    200208        // some internally handled states and handlers
     
    207215        std::vector<InputState*>            activeStatesTicked_;   //!< Like activeStates_, but only contains the ones that currently receive events
    208216
    209         std::set<InputState*>               stateEnterRequests_;   //!< Requests to enter a new state
    210         std::set<InputState*>               stateLeaveRequests_;   //!< Requests to leave a running state
    211         std::set<InputState*>               stateDestroyRequests_; //!< Requests to destroy a state
     217        std::vector<boost::function<void ()> > callBuffer_;        //!< Caches all calls from InputStates to be executed afterwards (see preUpdate)
    212218
    213219        static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
  • code/trunk/src/libraries/core/input/InputPrereqs.h

    r6417 r6746  
    4242#include <ois/OISMouse.h>
    4343#include <ois/OISJoyStick.h>
     44#include "util/OrxEnum.h"
    4445
    4546namespace orxonox
     
    448449        };
    449450    }
     451
     452    //! Enumeration wrapper for input state priorities
     453    struct InputStatePriority : OrxEnum<InputStatePriority>
     454    {
     455        OrxEnumConstructors(InputStatePriority);
     456
     457        static const int Empty        = -1;
     458        static const int Dynamic      = 0;
     459
     460        static const int HighPriority = 1000;
     461        static const int Console      = HighPriority + 0;
     462        static const int Calibrator   = HighPriority + 1;
     463        static const int Detector     = HighPriority + 2;
     464    };
    450465}
    451466
  • code/trunk/src/libraries/core/input/InputState.cc

    r6417 r6746  
    3737        , bAlwaysGetsInput_(bAlwaysGetsInput)
    3838        , bTransparent_(bTransparent)
    39         , mouseMode_(MouseMode::Dontcare)
     39        , exclusiveMouse_(TriBool::Dontcare)
    4040        , bExpired_(true)
    4141        , handlers_(2)
  • code/trunk/src/libraries/core/input/InputState.h

    r5929 r6746  
    3535#include <string>
    3636#include <vector>
    37 
    38 #include "util/OrxEnum.h"
     37#include <boost/function.hpp>
     38#include <boost/bind.hpp>
     39
     40#include "util/TriBool.h"
    3941#include "InputHandler.h"
     42#include "InputManager.h"
    4043#include "JoyStickQuantityListener.h"
     44
     45#define INPUT_STATE_PUSH_CALL(deviceIndex, functionName, ...) \
     46    InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(&InputHandler::functionName, handlers_[deviceIndex], __VA_ARGS__)))
    4147
    4248namespace orxonox
    4349{
    44     //! Enumeration wrapper for input state priorities
    45     struct InputStatePriority : OrxEnum<InputStatePriority>
    46     {
    47         OrxEnumConstructors(InputStatePriority);
    48 
    49         static const int Empty        = -1;
    50         static const int Dynamic      = 0;
    51 
    52         static const int HighPriority = 1000;
    53         static const int Console      = HighPriority + 0;
    54         static const int Calibrator   = HighPriority + 1;
    55         static const int Detector     = HighPriority + 2;
    56     };
    57 
    58     namespace MouseMode
    59     {
    60         enum Value
    61         {
    62             Exclusive,
    63             Nonexclusive,
    64             Dontcare
    65         };
    66     }
    67 
    6850    /**
    6951    @brief
     
    7355        that stack and only the top one gets the input events. This is done for
    7456        every device (keyboard, mouse, all joy sticks) separately to allow
    75         for intance keyboard input capturing for the console while you can still
     57        for instance keyboard input capturing for the console while you can still
    7658        steer a ship with the mouse.
    7759        There are two exceptions to this behaviour though:
     
    8365          the state will always receive input as long as it is activated.
    8466        - Note: If you mark an InputState with both parameters on, then it will
    85           not influence ony other InputState at all.
     67          not influence only other InputState at all.
    8668
    8769    @par Priorities
     
    9577    @par Exclusive/Non-Exclusive mouse Mode
    9678        You can select a specific mouse mode that tells whether the application
    97         should have exclusive accessto it or not.
     79        should have exclusive access to it or not.
    9880        When in non-exclusive mode, you can move the mouse out of the window
    9981        like with any other normal window (only for windowed mode!).
     
    130112        void setHandler        (InputHandler* handler);
    131113
    132         void setMouseMode(MouseMode::Value value) { mouseMode_ = value; this->bExpired_ = true; }
    133         MouseMode::Value getMouseMode() const { return mouseMode_; }
     114        void setMouseExclusive(TriBool::Value value) { exclusiveMouse_ = value; this->bExpired_ = true; }
     115        TriBool::Value getMouseExclusive() const { return exclusiveMouse_; }
    134116
    135117        //! Returns the name of the state (which is unique!)
     
    152134
    153135        //! Generic function that distributes all 9 button events
    154         template <typename EventType, class Traits>
    155         void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
     136        template <typename EventType, class ButtonTypeParam>
     137        void buttonEvent(unsigned int device, ButtonTypeParam button);
    156138
    157139        //! Event handler
     
    184166        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
    185167        const bool                  bTransparent_;          //!< See class declaration for explanation
    186         MouseMode::Value            mouseMode_;             //!< See class declaration for explanation
     168        TriBool::Value              exclusiveMouse_;        //!< See class declaration for explanation
    187169        int                         priority_;              //!< Current priority (might change)
    188170        bool                        bExpired_;              //!< See hasExpired()
     
    198180        for (unsigned int i = 0; i < handlers_.size(); ++i)
    199181            if (handlers_[i] != NULL)
    200                 handlers_[i]->allDevicesUpdated(dt);
     182                INPUT_STATE_PUSH_CALL(i, allDevicesUpdated, dt);
    201183    }
    202184
     
    207189        case InputDeviceEnumerator::Keyboard:
    208190            if (handlers_[keyboardIndex_s] != NULL)
    209                 handlers_[keyboardIndex_s]->keyboardUpdated(dt);
     191                INPUT_STATE_PUSH_CALL(keyboardIndex_s, keyboardUpdated, dt);
    210192            break;
    211193
    212194        case InputDeviceEnumerator::Mouse:
    213195            if (handlers_[mouseIndex_s] != NULL)
    214                 handlers_[mouseIndex_s]->mouseUpdated(dt);
     196                INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseUpdated, dt);
    215197            break;
    216198
    217199        default: // joy sticks
    218200            if (handlers_[device] != NULL)
    219                 handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
     201                INPUT_STATE_PUSH_CALL(device, joyStickUpdated, device - firstJoyStickIndex_s, dt);
    220202            break;
    221203        }
    222204    }
    223205
    224     template <typename EventType, class Traits>
    225     FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
     206    template <typename EventType, class ButtonTypeParam>
     207    FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
    226208    {
    227209        assert(device < handlers_.size());
    228210        if (handlers_[device] != NULL)
    229             handlers_[device]->buttonEvent(device, button, EventType());
     211        {
     212            // We have to store the function pointer to tell the compiler about its actual type because of overloading
     213            void (InputHandler::*function)(unsigned int, ButtonTypeParam, EventType) = &InputHandler::buttonEvent<ButtonTypeParam>;
     214            InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(function, handlers_[device], device, button, EventType())));
     215        }
    230216    }
    231217
     
    233219    {
    234220        if (handlers_[mouseIndex_s] != NULL)
    235             handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
     221            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseMoved, abs, rel, clippingSize);
    236222    }
    237223
     
    239225    {
    240226        if (handlers_[mouseIndex_s] != NULL)
    241             handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
     227            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseScrolled, abs, rel);
    242228    }
    243229
     
    246232        assert(device < handlers_.size());
    247233        if (handlers_[device] != NULL)
    248             handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
     234            INPUT_STATE_PUSH_CALL(device, axisMoved, device - firstJoyStickIndex_s, axis, value);
    249235    }
    250236}
Note: See TracChangeset for help on using the changeset viewer.