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:
7 deleted
16 edited
12 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r3280 r3327  
    6060        nCommands_[2]=0;
    6161        this->configContainer_ = 0;
    62         clear();
    6362    }
    6463
     
    8382                commands_[j] = 0;
    8483                nCommands_[j] = 0;
    85             }
    86             else
    87             {
    88                 commands_[j] = 0;
    8984            }
    9085        }
  • code/trunk/src/core/input/Button.h

    r3280 r3327  
    3636#define _Button_H__
    3737
    38 #include "core/CorePrereqs.h"
     38#include "InputPrereqs.h"
    3939
    4040#include <string>
  • code/trunk/src/core/input/CMakeLists.txt

    r3196 r3327  
    11ADD_SOURCE_FILES(CORE_SRC_FILES
    22  Button.cc
    3   ExtendedInputState.cc
    43  HalfAxis.cc
    54  InputBuffer.cc
    65  InputCommands.cc
    76  InputManager.cc
    8   JoyStickDeviceNumberListener.cc
     7  InputState.cc
     8  JoyStick.cc
     9  JoyStickQuantityListener.cc
    910  KeyBinder.cc
     11  Keyboard.cc
    1012  KeyDetector.cc
    11   SimpleInputState.cc
     13  Mouse.cc
    1214)
  • code/trunk/src/core/input/HalfAxis.cc

    r1887 r3327  
    4949            nParamCommands_ = 0;
    5050        }
    51         else
    52         {
    53             nParamCommands_ = 0; nParamCommands_ = 0;
    54         }
    5551    }
    5652
  • code/trunk/src/core/input/HalfAxis.h

    r3196 r3327  
    3636#define _HalfAxis_H__
    3737
    38 #include "core/CorePrereqs.h"
     38#include "InputPrereqs.h"
    3939
    4040#include "Button.h"
  • code/trunk/src/core/input/InputBuffer.cc

    r3301 r3327  
    184184
    185185
    186     void InputBuffer::processKey(const KeyEvent &evt)
    187     {
    188         if (evt.isModifierDown(KeyboardModifier::Alt) && evt.key == KeyCode::Tab)
     186    void InputBuffer::processKey(const KeyEvent& evt)
     187    {
     188        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
    189189            return;
    190190
    191191        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
    192192        {
    193             if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.key))
     193            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
    194194                (*it)->callFunction();
    195195        }
     
    197197        if (evt.isModifierDown(KeyboardModifier::Ctrl))
    198198        {
    199             if (evt.key == KeyCode::V)
     199            if (evt.getKeyCode() == KeyCode::V)
    200200                this->insert(fromClipboard());
    201             else if (evt.key == KeyCode::C)
     201            else if (evt.getKeyCode() == KeyCode::C)
    202202                toClipboard(this->buffer_);
    203             else if (evt.key == KeyCode::X)
     203            else if (evt.getKeyCode() == KeyCode::X)
    204204            {
    205205                toClipboard(this->buffer_);
     
    209209        else if (evt.isModifierDown(KeyboardModifier::Shift))
    210210        {
    211             if (evt.key == KeyCode::Insert)
     211            if (evt.getKeyCode() == KeyCode::Insert)
    212212                this->insert(fromClipboard());
    213             else if (evt.key == KeyCode::Delete)
     213            else if (evt.getKeyCode() == KeyCode::Delete)
    214214            {
    215215                toClipboard(this->buffer_);
     
    218218        }
    219219
    220         this->insert(static_cast<char>(evt.text));
     220        this->insert(static_cast<char>(evt.getText()));
    221221    }
    222222
     
    225225        @param dt Delta time
    226226    */
    227     void InputBuffer::updateInput(float dt)
     227    void InputBuffer::keyboardUpdated(float dt)
    228228    {
    229229        timeSinceKeyPressed_ += dt;
     
    239239    }
    240240
    241     void InputBuffer::keyPressed(const KeyEvent &evt)
    242     {
    243         lastKey_ = evt.key;
     241    void InputBuffer::buttonPressed(const KeyEvent& evt)
     242    {
     243        lastKey_ = evt.getKeyCode();
    244244        timeSinceKeyPressed_ = 0.0;
    245245        timeSinceKeyRepeated_ = keyRepeatDeleay_;
     
    249249    }
    250250
    251     void InputBuffer::keyHeld(const KeyEvent& evt)
    252     {
    253         if (evt.key == lastKey_)
     251    void InputBuffer::buttonHeld(const KeyEvent& evt)
     252    {
     253        if (evt.getKeyCode() == lastKey_)
    254254        {
    255255            while (keysToRepeat_)
  • code/trunk/src/core/input/InputBuffer.h

    r3196 r3327  
    3030#define _InputBuffer_H__
    3131
    32 #include "core/CorePrereqs.h"
     32#include "InputPrereqs.h"
    3333
    3434#include <list>
    3535#include <string>
    3636#include "core/OrxonoxClass.h"
    37 #include "InputInterfaces.h"
     37#include "InputHandler.h"
    3838
    3939namespace orxonox
     
    7474    };
    7575
    76     class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass
     76    class _CoreExport InputBuffer : public InputHandler, public OrxonoxClass
    7777    {
    7878        public:
     
    165165            bool charIsAllowed(const char& input);
    166166
    167             void keyPressed (const KeyEvent& evt);
    168             void keyReleased(const KeyEvent& evt) { }
    169             void keyHeld    (const KeyEvent& evt);
    170             void processKey (const KeyEvent &e);
     167            void buttonPressed(const KeyEvent& evt);
     168            void buttonHeld   (const KeyEvent& evt);
     169            void processKey   (const KeyEvent& evt);
    171170
    172             void updateInput(float dt);
    173             void updateKey(float dt) { }
     171            void keyboardUpdated(float dt);
    174172
    175173            std::string buffer_;
  • code/trunk/src/core/input/InputCommands.h

    r2087 r3327  
    3636#define _InputCommands_H__
    3737
    38 #include "core/CorePrereqs.h"
     38#include "InputPrereqs.h"
    3939#include "core/CommandEvaluation.h"
    4040
  • code/trunk/src/core/input/InputDevice.h

    r3276 r3327  
    2929/**
    3030@file
    31 @brief
     31@brief
     32    Implementation of InputDevice and InputDeviceTemplated
    3233*/
    3334
     
    3839
    3940#include <vector>
    40 #include <boost/foreach.hpp>
    4141#include <ois/OISInputManager.h>
    4242
    4343#include "util/Debug.h"
    4444#include "core/Clock.h"
    45 // TODO: Try to remove this
    46 #include "InputManager.h"
    4745#include "InputState.h"
    4846
     
    5149    /**
    5250    @brief
     51        Abstract base class for all input devices (mouse, keyboard and joy sticks).
     52
     53        It provides common virtual functions to be used by the InputManager.
    5354    */
    5455    class InputDevice
    5556    {
    56         friend class InputManager;
    57 
    5857    public:
    59         InputDevice(unsigned int id) : bCalibrating_(false), id_(id) { }
     58        //! Only resets the members
     59        InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { }
    6060        virtual ~InputDevice() { }
    61         virtual std::string getClassName() = 0;
     61        //! Returns the device class (derived) name as string
     62        virtual std::string getClassName() const = 0;
     63        //! Updates the device which should in turn distribute events
    6264        virtual void update(const Clock& time) = 0;
     65        //! Clear all button related buffers
    6366        virtual void clearBuffers() = 0;
    6467
     68        //! Start calibrating (only useful for joy sticks)
    6569        void startCalibration()
    6670        {
     
    6973        }
    7074
     75        //! Stop calibrating and evaluate the data (only useful for joy sticks)
    7176        void stopCalibration()
    7277        {
     
    7580        }
    7681
    77         unsigned int getDeviceID() { return this->id_; }
     82        //! Returns a reference to the internal input state vector. Use with care!
     83        std::vector<InputState*>& getStateListRef() { return this->inputStates_; }
     84        //! Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
     85        unsigned int getDeviceID() const { return this->deviceID_; }
     86        //! Tells whether the device is in calibration mode
     87        bool isCalibrating() const { return bCalibrating_; }
    7888
    7989    protected:
     90        //! To be ovrridden by the subclass
    8091        virtual void calibrationStarted() { }
     92        //! To be ovrridden by the subclass
    8193        virtual void calibrationStopped() { }
    82         bool isCalibrating() { return bCalibrating_; }
    83 
    84         // InputState handling
     94
     95        //! List of all input states that receive events from this device
    8596        std::vector<InputState*> inputStates_;
    8697
    8798    private:
    88         InputDevice(const InputDevice& rhs);
    89 
    90         std::vector<InputState*>& getStateListRef()
    91         {
    92             return this->inputStates_;
    93         }
    94 
    95         bool bCalibrating_;
    96         const unsigned int id_;
     99        InputDevice(const InputDevice& rhs); //!< Don't use!
     100
     101        bool bCalibrating_;                  //!< Whether the device is in calibration mode
     102        const unsigned int deviceID_;        //!< ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
    97103    };
    98104
    99105    /**
    100106    @brief
     107        Heavily templated base class for all three input devices.
     108
     109        The purpose of this class is not to provide an interface but rather
     110        to reduce code redundancy. This concerns device creation and destruction
     111        as well as common code for button events (press, release, hold).
     112
     113        In order to derive from this class you have to supply it with a struct
     114        as template parameter that contains the necessary type traits.
    101115    */
    102116    template <class Traits>
     
    110124
    111125    public:
    112         InputDeviceTemplated(unsigned int id)
     126        //! Creates the OIS device
     127        InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager)
    113128            : InputDevice(id)
    114         {
    115             OIS::InputManager* system = InputManager::getInstance().getInputSystem();
    116             oisDevice_ = static_cast<OISDeviceClass*>(system->createInputObject(OISDeviceValue, true));
     129            , oisInputManager_(oisInputManager)
     130        {
     131            oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true));
     132            // Note: after the static_cast here, the casted this pointer becomes
     133            //       invalid right until the subclass has been constructed!
    117134            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
    118135            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
    119136        }
    120137
     138        //! Destroys the OIS device
    121139        virtual ~InputDeviceTemplated()
    122140        {
    123141            try
    124142            {
    125                 InputManager::getInstance().getInputSystem()->destroyInputObject(oisDevice_);
     143                oisInputManager_->destroyInputObject(oisDevice_);
    126144            }
    127145            catch (...)
     
    131149        }
    132150
    133         OISDeviceClass* getOISDevice()
    134         {
    135             return this->oisDevice_;
    136         }
    137 
    138         std::string getClassName()
    139         {
    140             return InputDeviceNames::values[OISDeviceValue];
    141         }
    142 
     151        //! Captures OIS events (which then get distributed to the derived class) and creates the button held events
    143152        void update(const Clock& time)
    144153        {
    145154            oisDevice_->capture();
    146155
    147             if (!this->isCalibrating())
    148             {
    149                 // Call all the states with the held button event
    150                 for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
    151                     for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
    152                         inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
    153                             this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
    154 
    155                 // Call states with device update events
    156                 for (unsigned int i = 0; i < inputStates_.size(); ++i)
    157                     inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
    158             }
     156            // Call all the states with the held button event
     157            for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
     158                for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
     159                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
     160                        this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
     161
     162            // Call states with device update events
     163            for (unsigned int i = 0; i < inputStates_.size(); ++i)
     164                inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
    159165
    160166            static_cast<DeviceClass*>(this)->updateImpl(time);
    161167        }
    162168
     169        //! Clears the list of pressed buttons and calls the derived class's method
    163170        void clearBuffers()
    164171        {
     
    167174        }
    168175
     176        // Returns a pointer to the OIS device
     177        OISDeviceClass* getOISDevice()   { return this->oisDevice_; }
     178        // Returns the name of the derived class as string
     179        std::string getClassName() const { return DeviceClass::getClassNameImpl(); }
     180
    169181    protected:
    170         void buttonPressed(ButtonTypeParam button)
     182        //! Common code for all button pressed events (updates pressed buttons list and calls the input states)
     183        FORCEINLINE void buttonPressed(ButtonTypeParam button)
    171184        {
    172185            // check whether the button already is in the list (can happen when focus was lost)
     
    184197        }
    185198
    186         void buttonReleased(ButtonTypeParam button)
     199        //! Common code for all button released events (updates pressed buttons list and calls the input states)
     200        FORCEINLINE void buttonReleased(ButtonTypeParam button)
    187201        {
    188202            // remove the button from the pressedButtons_ list
     
    201215        }
    202216
     217        //! Managed pointer to the OIS device
    203218        OISDeviceClass* oisDevice_;
    204219
    205220    private:
    206         void clearBuffersImpl() { } //!< Fallback dummy function for static polymorphism
    207         void updateImpl(const Clock& time) { } //!< Fallback dummy function for static polymorphism
     221        //!< Fallback dummy function for static polymorphism
     222        void clearBuffersImpl() { }
     223        //!< Fallback dummy function for static polymorphism
     224        void updateImpl(const Clock& time) { }
    208225        //!< Fallback dummy function for static polymorphism
    209226        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
    210227
    211         std::vector<ButtonType> pressedButtons_;
     228        std::vector<ButtonType> pressedButtons_; //!< List of all buttons that are currently pressed down
     229        OIS::InputManager* oisInputManager_;     //!< Pointer to the OIS InputManager that can create and destroy devices
    212230    };
    213231}
  • code/trunk/src/core/input/InputHandler.h

    r3276 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32     Declarations of various interface classes for the input management.
    33 */
    34 
    3529#ifndef _InputHandler_H__
    3630#define _InputHandler_H__
     
    4135namespace orxonox
    4236{
     37    namespace ButtonEvent
     38    {
     39        //! Helper enum to deploy events with the help of templates
     40        enum Value
     41        {
     42            Press,
     43            Release,
     44            Hold
     45        };
     46
     47        //! Enables function overloading with integer values
     48        template <ButtonEvent::Value Event>
     49        struct EnumToType { };
     50        typedef EnumToType<Press>   TPress;
     51        typedef EnumToType<Release> TRelease;
     52        typedef EnumToType<Hold>    THold;
     53    }
     54
     55    namespace KeyboardModifier
     56    {
     57        //! Keyboard modifiers (shift, ctrl and alt)
     58        enum Enum
     59        {
     60            Shift = 0x0000001,
     61            Ctrl  = 0x0000010,
     62            Alt   = 0x0000100
     63        };
     64    }
     65
     66    //! Event argument for key events
     67    class _CoreExport KeyEvent
     68    {
     69    public:
     70        KeyEvent(const OIS::KeyEvent& evt)
     71            : key_(static_cast<KeyCode::ByEnum>(evt.key))
     72            , text_(evt.text)
     73            , modifiers_(0)
     74        { }
     75        bool operator==(const KeyEvent& rhs) const
     76            { return rhs.key_ == key_; }
     77        bool operator!=(const KeyEvent& rhs) const
     78            { return rhs.key_ != key_; }
     79        void setModifiers(int modifiers)
     80            { modifiers_ = modifiers; }
     81
     82        bool isModifierDown(KeyboardModifier::Enum modifier) const
     83            { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }
     84        KeyCode::ByEnum getKeyCode() const
     85            { return key_; }
     86        unsigned int getText() const { return text_; }
     87
     88    private:
     89        KeyCode::ByEnum key_;
     90        unsigned int text_;
     91        int modifiers_;
     92    };
     93
    4394    /**
    4495    @brief
     96        Base class for all input handlers like KeyBinder, InputBuffer, etc.
     97
     98        Derive from this class if you wish to receive input events.
     99        But keep in mind that this is pointless wihtout first having an InputState.
     100    @note
     101        The definitions for the button events with the weird arguments are simply
     102        to avoid redunant code in the input devices.
    45103    */
    46104    class _CoreExport InputHandler
     
    83141        virtual void allDevicesUpdated(float dt) { }
    84142
     143        //! Use this input handler if you want to occupy a device in an input state.
    85144        static InputHandler EMPTY;
    86145    };
  • 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}
  • code/trunk/src/core/input/InputManager.h

    r3196 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32     Implementation of a little Input handler that distributes everything
    33     coming from OIS.
    34 */
    35 
    3629#ifndef _InputManager_H__
    3730#define _InputManager_H__
    3831
    39 #include "core/CorePrereqs.h"
     32#include "InputPrereqs.h"
    4033
    4134#include <map>
     
    4336#include <string>
    4437#include <vector>
    45 #include <ois/OISKeyboard.h>
    46 #include <ois/OISMouse.h>
    47 #include <ois/OISJoyStick.h>
    48 
    49 #include "util/Math.h"
    50 #include "util/OrxEnum.h"
    51 #include "core/OrxonoxClass.h"
    52 #include "InputInterfaces.h"
     38
     39#include "core/WindowEventListener.h"
     40#include "InputState.h"
    5341
    5442namespace orxonox
     
    5644    /**
    5745    @brief
    58         Helper class to realise a vector<int[4]>
     46        Manages the input devices (mouse, keyboard, joy sticks) and the input states.
     47
     48        Every input device has its own wrapper class which does the actualy input event
     49        distribution. The InputManager only creates reloads (on request) those devices.
     50
     51        The other functionality concerns handling InputStates. They act as a layer
     52        between InputHandlers (like the KeyBinder or the GUIManager) and InputDevices.
     53        InputStates are memory managed by the IputManager. You cannot create or destroy
     54        them on your own. Therefore all states get destroyed with the InputManager d'tor.
     55    @note
     56        - The actual lists containing all the InputStates for a specific device are stored
     57          in the InputDevices themselves.
     58        - The devices_ vector always has at least two elements: Keyboard (first) and mouse.
     59          You best access them intenally with InputDeviceEnumerator::Keyboard/Mouse
     60          The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick.
     61        - Keyboard construction is mandatory , mouse and joy sticks are not.
     62          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
    5963    */
    60     class POVStates
     64    class _CoreExport InputManager : public WindowEventListener
    6165    {
    6266    public:
    63         int& operator[](unsigned int index) { return povStates[index]; }
    64         int povStates[4];
    65     };
    66 
    67     /**
    68     @brief
    69         Helper class to realise a vector< {int[4], int[4]} >
    70     */
    71     class SliderStates
    72     {
    73     public:
    74         IntVector2 sliderStates[4];
    75     };
    76 
    77     struct JoyStickCalibration
    78     {
    79         int middleValue[24];
    80         float positiveCoeff[24];
    81         float negativeCoeff[24];
    82     };
    83 
    84     struct InputStatePriority : OrxEnum<InputStatePriority>
    85     {
    86         OrxEnumConstructors(InputStatePriority);
    87 
    88         static const int Empty        = -1;
    89         static const int Dynamic      = 0;
    90 
    91         static const int HighPriority = 1000;
    92         static const int Console      = HighPriority + 0;
    93         static const int Calibrator   = HighPriority + 1;
    94         static const int Detector     = HighPriority + 2;
    95     };
    96 
    97     /**
    98     @brief
    99         Captures and distributes mouse and keyboard input.
    100     */
    101     class _CoreExport InputManager
    102         : public OrxonoxClass,
    103         public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
    104     {
    105         // --> setConfigValues is private
    106         friend class ClassIdentifier<InputManager>;
    107 
    108     public:
    109         enum InputManagerState
     67        //! Represents internal states of the InputManager.
     68        enum State
    11069        {
    111             Uninitialised    = 0x00,
    112             OISReady         = 0x01,
    113             InternalsReady   = 0x02,
    114             Ticking          = 0x04,
    115             Calibrating      = 0x08,
    116             ReloadRequest    = 0x10,
    117             JoyStickSupport  = 0x20 // used with ReloadRequest to store a bool
     70            Nothing       = 0x00,
     71            Bad           = 0x02,
     72            Ticking       = 0x04,
     73            Calibrating   = 0x08,
     74            ReloadRequest = 0x10,
    11875        };
    11976
    120         InputManager ();
     77        /**
     78        @brief
     79            Loads the devices and initialises the KeyDetector and the Calibrator.
     80           
     81            If either the OIS input system and/or the keyboard could not be created,
     82            the constructor fails with an std::exception.
     83        */
     84        InputManager(size_t windowHnd);
     85        //! Destroys all devices AND all input states!
    12186        ~InputManager();
    122 
    123         void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
    124 
    125         void reloadInputSystem(bool joyStickSupport = true);
    126 
     87        void setConfigValues();
     88
     89        /**
     90        @brief
     91            Updates the devices (which distribute the input events) and the input states.
     92
     93            Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request
     94            was submitted while updating, the request wil be postponed until the next update call.
     95        */
     96        void update(const Clock& time);
     97        //! Clears all input device buffers. This usually only includes the pressed button list.
    12798        void clearBuffers();
    128 
    129         unsigned int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
    130         unsigned int  numberOfMice()      { return mouse_    ? 1 : 0; }
    131         unsigned int  numberOfJoySticks() { return joySticksSize_; }
    132 
    133         void setWindowExtents(const int width, const int height);
     99        //! Starts joy stick calibration.
     100        void calibrate();
     101        /**
     102        @brief
     103            Reloads all the input devices. Use this method to initialise new joy sticks.
     104        @note
     105            Only reloads immediately if the call stack doesn't include the update() method.
     106        */
     107        void reload();
     108
     109        //-------------------------------
     110        // Input States
     111        //-------------------------------
     112        /**
     113        @brief
     114            Creates a new InputState that gets managed by the InputManager.
     115        @remarks
     116            The InputManager will take care of the state completely. That also
     117            means it gets deleted when the InputManager is destroyed!
     118        @param name
     119            Unique name of the InputState when referenced as string
     120        @param priority
     121            Priority matters when multiple states are active. You can specify any
     122            number, but 1 - 99 is preferred (99 means high priority).
     123        */
     124        InputState* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
     125        /**
     126        @brief
     127            Returns a pointer to a InputState referenced by name.
     128        @return
     129            Returns NULL if state was not found.
     130        */
     131        InputState* getState(const std::string& name);
     132        /**
     133        @brief
     134            Activates a specific input state.
     135            It might not be actually activated if the priority is too low!
     136        @return
     137            False if name was not found, true otherwise.
     138        */
     139        bool enterState(const std::string& name);
     140        /**
     141        @brief
     142            Deactivates a specific input state.
     143        @return
     144            False if name was not found, true otherwise.
     145        */
     146        bool leaveState(const std::string& name);
     147        /**
     148        @brief
     149            Removes and destroys an input state.
     150        @return
     151            True if removal was successful, false if name was not found.
     152        @remarks
     153            - You can't remove the internal states "empty", "calibrator" and "detector".
     154            - The removal process is being postponed if InputManager::update() is currently running.
     155        */
     156        bool destroyState(const std::string& name);
     157
     158        //-------------------------------
     159        // Various getters and setters
     160        //-------------------------------
     161        //! Sets the the name of the command used by the KeyDetector as callback.
    134162        void setKeyDetectorCallback(const std::string& command);
    135 
    136         template <class T>
    137         T* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
    138 
    139         InputState* getState       (const std::string& name);
    140         InputState* getCurrentState();
    141         bool requestDestroyState   (const std::string& name);
    142         bool requestEnterState     (const std::string& name);
    143         bool requestLeaveState     (const std::string& name);
    144 
    145 #ifdef ORXONOX_PLATFORM_LINUX
    146         // HACK!
    147         static void grabMouse();
    148         static void ungrabMouse();
    149 #endif
    150 
    151         void update(const Clock& time);
    152 
    153         static InputManager& getInstance()    { assert(singletonRef_s); return *singletonRef_s; }
    154         static InputManager* getInstancePtr() { return singletonRef_s; }
    155 
    156         // console commands
    157         static void calibrate();
    158         static void reload(bool joyStickSupport = true);
    159 
    160     public: // variables
    161         static EmptyHandler                 EMPTY_HANDLER;
    162         static const unsigned int           sliderAxes = 8;
     163        //! Returns the number of joy stick that have been created since the c'tor or last call to reload().
     164        unsigned int getJoyStickQuantity() const
     165            { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
     166        //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
     167        OIS::InputManager* getOISInputManager()
     168            { return this->oisInputManager_; }
     169
     170        //! Returns a reference to the singleton instance
     171        static InputManager& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
    163172
    164173    private: // functions
    165174        // don't mess with a Singleton
    166         InputManager (const InputManager&);
     175        InputManager(const InputManager&);
    167176
    168177        // Intenal methods
    169         void _initialiseKeyboard();
    170         void _initialiseMouse();
    171         void _initialiseJoySticks();
    172         void _configureJoySticks();
    173 
    174         void _loadCalibration();
    175         void _startCalibration();
    176         void _completeCalibration();
    177         void _evaluateCalibration();
    178 
    179         void _destroyKeyboard();
    180         void _destroyMouse();
    181         void _destroyJoySticks();
    182         void _destroyState(InputState* state);
    183         void _clearBuffers();
    184 
    185         void _reload(bool joyStickSupport);
    186 
    187         void _fireAxis(unsigned int iJoyStick, int axis, int value);
    188         unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
    189 
    190         void _updateActiveStates();
    191         bool _configureInputState(InputState* state, const std::string& name, bool bAlwaysGetsInput, bool bTransparent, int priority);
    192 
    193         // input events
    194         bool mousePressed  (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
    195         bool mouseReleased (const OIS::MouseEvent    &arg, OIS::MouseButtonID id);
    196         bool mouseMoved    (const OIS::MouseEvent    &arg);
    197         bool keyPressed    (const OIS::KeyEvent      &arg);
    198         bool keyReleased   (const OIS::KeyEvent      &arg);
    199         bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
    200         bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
    201         bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
    202         bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
    203         bool povMoved      (const OIS::JoyStickEvent &arg, int id);
    204         // don't remove that! Or else add OIS as dependency library to orxonox.
    205         bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
    206 
    207         void setConfigValues();
    208         void _calibrationFileCallback();
     178        void loadDevices(size_t windowHnd);
     179        void loadMouse();
     180        void loadJoySticks();
     181        void destroyDevices();
     182
     183        void stopCalibration();
     184        void reloadInternal();
     185
     186        void destroyStateInternal(InputState* state);
     187        void updateActiveStates();
     188
     189        // From WindowEventListener
     190        void windowFocusChanged();
    209191
    210192    private: // variables
    211         OIS::InputManager*                  inputSystem_;          //!< OIS input manager
    212         OIS::Keyboard*                      keyboard_;             //!< OIS mouse
    213         OIS::Mouse*                         mouse_;                //!< OIS keyboard
    214         std::vector<OIS::JoyStick*>         joySticks_;            //!< OIS joy sticks
    215         unsigned int                        joySticksSize_;
    216         std::vector<std::string>            joyStickIDs_;          //!< Execution unique identification strings for the joy sticks
    217         unsigned int                        devicesNum_;
    218         size_t                              windowHnd_;            //!< Render window handle
    219         InputManagerState                   internalState_;        //!< Current internal state
     193        State                               internalState_;        //!< Current internal state
     194        OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
     195        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
     196        // TODO: Get this from the GraphicsManager during reload
     197        size_t                              windowHnd_;            //!< Render window handle (used to reload the InputManager)
    220198
    221199        // some internally handled states and handlers
    222         SimpleInputState*                   stateEmpty_;
     200        InputState*                         emptyState_;           //!< Lowest priority states (makes handling easier)
    223201        KeyDetector*                        keyDetector_;          //!< KeyDetector instance
    224         InputBuffer*                        calibratorCallbackBuffer_;
    225 
    226         std::map<std::string, InputState*>  inputStatesByName_;
    227 
    228         std::set<InputState*>               stateEnterRequests_;   //!< Request to enter a new state
    229         std::set<InputState*>               stateLeaveRequests_;   //!< Request to leave a running state
    230         std::set<InputState*>               stateDestroyRequests_; //!< Request to destroy a state
    231 
    232         std::map<int, InputState*>          activeStates_;
    233         std::vector<std::vector<InputState*> > activeStatesTriggered_;
    234         std::vector<InputState*>            activeStatesTicked_;
    235 
    236         // joystick calibration
    237         std::vector<std::vector<int> >      joyStickMinValues_;
    238         std::vector<std::vector<int> >      joyStickMaxValues_;
    239         std::vector<std::vector<int> >      joyStickMiddleValues_;
    240         std::vector<ConfigValueContainer*>  calibrationConfigValueContainers_;
    241         std::vector<JoyStickCalibration>    joyStickCalibrations_;
    242 
    243         unsigned int                        keyboardModifiers_;    //!< Bit mask representing keyboard modifiers.
    244         std::vector<POVStates>              povStates_;            //!< Keeps track of the joy stick POV states.
    245         std::vector<SliderStates>           sliderStates_;         //!< Keeps track of the possibly two slider axes.
    246 
    247         std::vector<Key>                    keysDown_;
    248         std::vector<MouseButtonCode::ByEnum>      mouseButtonsDown_;
    249         std::vector<std::vector<JoyStickButtonCode::ByEnum> >  joyStickButtonsDown_;
    250 
    251         // ConfigValues
    252         std::string                         calibrationFilename_;  //!< Joy stick calibration ini filename
    253 
    254         static InputManager*                singletonRef_s;
     202        //! InputBuffer that reacts to the Enter key when calibrating the joy sticks
     203        InputBuffer*                        calibratorCallbackHandler_;
     204
     205        std::map<std::string, InputState*>  statesByName_;         //!< Contains all the created input states by name
     206        std::map<int, InputState*>          activeStates_;         //!< Contains all active input states by priority (std::map is sorted!)
     207        std::vector<InputState*>            activeStatesTicked_;   //!< Like activeStates_, but only contains the ones that currently receive events
     208
     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
     212
     213        static InputManager*                singletonRef_s;        //!< Pointer reference to the singleton
    255214    };
    256 
    257     /**
    258     @brief
    259         Creates a new InputState by type, name and priority.
    260        
    261         You will have to use this method because the
    262         c'tors and d'tors are private.
    263     @remarks
    264         The InputManager will take care of the state completely. That also
    265         means it gets deleted when the InputManager is destroyed!
    266     @param name
    267         Name of the InputState when referenced as string
    268     @param priority
    269         Priority matters when multiple states are active. You can specify any
    270         number, but 1 - 99 is preferred (99 means high).
    271     */
    272     template <class T>
    273     T* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
    274     {
    275         T* state = new T;
    276         if (_configureInputState(state, name, bAlwaysGetsInput, bTransparent, priority))
    277             return state;
    278         else
    279         {
    280             delete state;
    281             return 0;
    282         }
    283     }
    284215}
    285216
  • code/trunk/src/core/input/InputPrereqs.h

    r3276 r3327  
    3030@file
    3131@brief
    32     Declarations of various interface classes for the input management.
     32    Declarations of all key/button/axis code enumeration and string literals
     33    and an input device enumeration.
    3334*/
    3435
     
    5253        const unsigned int numberOfKeys = 0xEE; // 238
    5354
    54         // note: KeyCode comments were directly copied from OISKeyboard.h
     55        //! Key codes as enumeration
    5556        enum ByEnum
    5657        {
     
    202203        };
    203204       
    204         // Names as string. Has no real linkage!
     205        //! Key codes as strings
    205206        const char* const ByString[] =
    206207        {
     
    307308        const unsigned int numberOfButtons = 8;
    308309
     310        //! Mouse button codes as enumeration
    309311        enum ByEnum
    310312        {
     
    319321        };
    320322
    321         // Names as string. Has no real linkage!
     323        // Mouse button codes as strings
    322324        const char* const ByString[] =
    323325        {
     
    337339        const unsigned int numberOfAxes = 2;
    338340
     341        // Mouse axis codes as enumeration
    339342        enum ByEnum
    340343        {
     
    343346        };
    344347
    345         // Names as string. Has no real linkage!
     348        // Mouse axis codes as strings
    346349        const char* const ByString[] =
    347350        {
     
    356359        const unsigned int numberOfButtons = 64;
    357360
     361        // Joy stick button codes as enumeration
    358362        enum ByEnum
    359363        {
     
    380384        };
    381385
    382         // Names as string. Has no real linkage!
     386        // Joy stick button codes as strings
    383387        const char* const ByString[] =
    384388        {
     
    406410        const unsigned int numberOfAxes = 24;
    407411
     412        // Joy stick axis codes as enumeration
    408413        enum ByEnum
    409414        {
     
    416421        };
    417422
    418         // Names as string. Has no real linkage!
     423        // Joy stick axis codes as strings
    419424        const char* const ByString[] =
    420425        {
     
    435440    namespace InputDeviceEnumerator
    436441    {
     442        //! Used to access the devices in an array
    437443        enum Value
    438444        {
     
    442448        };
    443449    }
    444 
    445     namespace ButtonEvent
    446     {
    447         enum Value
    448         {
    449             Press,
    450             Release,
    451             Hold
    452         };
    453 
    454         template <ButtonEvent::Value Event>
    455         struct EnumToType { };
    456         typedef EnumToType<Press>   TPress;
    457         typedef EnumToType<Release> TRelease;
    458         typedef EnumToType<Hold>    THold;
    459     }
    460 
    461 
    462     namespace KeyboardModifier
    463     {
    464         enum Enum
    465         {
    466             Shift = 0x0000001,
    467             Ctrl  = 0x0000010,
    468             Alt   = 0x0000100
    469         };
    470     }
    471 
    472     class _CoreExport KeyEvent
    473     {
    474     public:
    475         KeyEvent(const OIS::KeyEvent& evt)
    476             : key_(static_cast<KeyCode::ByEnum>(evt.key))
    477             , text_(evt.text)
    478             , modifiers_(0)
    479         { }
    480         bool operator==(const KeyEvent& rhs) const
    481             { return rhs.key_ == key_; }
    482         bool operator!=(const KeyEvent& rhs) const
    483             { return rhs.key_ != key_; }
    484         void setModifiers(int modifiers)
    485             { modifiers_ = modifiers; }
    486 
    487         bool isModifierDown(KeyboardModifier::Enum modifier) const
    488             { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }
    489         KeyCode::ByEnum getKeyCode() const
    490             { return key_; }
    491         unsigned int getText() const { return text_; }
    492 
    493     private:
    494         KeyCode::ByEnum key_;
    495         unsigned int text_;
    496         int modifiers_;
    497     };
    498 
    499 
    500     //-----------------------------------------------------------------------
    501     // Device type traits
    502     //-----------------------------------------------------------------------
    503 
    504     struct KeyboardTraits
    505     {
    506         typedef Keyboard DeviceClass;
    507         typedef OIS::Keyboard OISDeviceClass;
    508         typedef KeyEvent ButtonType;
    509         typedef KeyEvent& ButtonTypeParam;
    510         static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
    511     };
    512 
    513     struct MouseTraits
    514     {
    515         typedef Mouse DeviceClass;
    516         typedef OIS::Mouse OISDeviceClass;
    517         typedef MouseButtonCode::ByEnum ButtonType;
    518         typedef MouseButtonCode::ByEnum ButtonTypeParam;
    519         static const OIS::Type OISDeviceValue = OIS::OISMouse;
    520     };
    521 
    522     struct JoyStickTraits
    523     {
    524         typedef JoyStick DeviceClass;
    525         typedef OIS::JoyStick OISDeviceClass;
    526         typedef JoyStickButtonCode::ByEnum ButtonType;
    527         typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
    528         static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
    529     };
    530 
    531     // Note: Entries correspond to OIS::Type enum
    532     namespace InputDeviceNames
    533     {
    534         const char* const values[] = { "", "Keyboard", "Mouse", "JoyStick" };
    535     }
    536450}
    537451
  • code/trunk/src/core/input/InputState.cc

    r3276 r3327  
    3232namespace orxonox
    3333{
    34     InputState::InputState()
    35         : priority_(0)
    36         , bAlwaysGetsInput_(false)
    37         , bTransparent_(false)
     34    //! Sets priority of it's a high priority and resizes the handler list
     35    InputState::InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
     36        : name_(name)
     37        , bAlwaysGetsInput_(bAlwaysGetsInput)
     38        , bTransparent_(bTransparent)
    3839        , bExpired_(true)
    3940        , handlers_(2)
     
    4243        , leaveFunctor_(0)
    4344    {
     45        if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
     46            priority_ = priority;
     47        else
     48            priority_ = 0;
     49
     50        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + this->getJoyStickList().size(), NULL);
    4451    }
    4552
     
    5259    }
    5360
    54     void InputState::JoyStickQuantityChanged(unsigned int n)
     61    //! Called by JoyStickQuantityListener upon joy stick adding/removal
     62    void InputState::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
    5563    {
    5664        unsigned int oldSize = handlers_.size();
    57         handlers_.resize(InputDeviceEnumerator::FirstJoyStick + n, NULL);
     65        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + joyStickList.size(), NULL);
    5866
    5967        for (unsigned int i = oldSize; i < handlers_.size(); ++i)
     
    6371    }
    6472
    65     /**
    66     @brief
    67         Adds a joy stick handler.
    68     @param handler
    69         Pointer to the handler object.
    70     @param joyStickID
    71         ID of the joy stick
    72     @return
    73         True if added, false otherwise.
    74     */
    7573    bool InputState::setJoyStickHandler(InputHandler* handler, unsigned int joyStick)
    7674    {
     
    8482    }
    8583
    86     /**
    87     @brief
    88         Adds a joy stick handler.
    89     @param handler
    90         Pointer to the handler object.
    91     @return
    92         True if added, false if handler already existed.
    93     */
    94     bool InputState::setJoyStickHandler(InputHandler* handler)
     84    void InputState::setJoyStickHandler(InputHandler* handler)
    9585    {
    9686        joyStickHandlerAll_ = handler;
     
    9888            handlers_[i] = handler;
    9989        bExpired_ = true;
    100         return true;
    10190    }
    10291
    103     /**
    104     @brief
    105         Adds a handler of any kind. dynamic_cast determines to which list it is added.
    106     @param handler
    107         Pointer to the handler object.
    108     @return
    109         True if added, false if handler already existed.
    110     */
    111     bool InputState::setHandler(InputHandler* handler)
     92    void InputState::setHandler(InputHandler* handler)
    11293    {
    11394        setKeyHandler(handler);
    11495        setMouseHandler(handler);
    115         return setJoyStickHandler(handler);
     96        setJoyStickHandler(handler);
    11697    }
    11798
  • code/trunk/src/core/input/InputState.h

    r3196 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32 */
    33 
    3429#ifndef _InputState_H__
    3530#define _InputState_H__
    3631
    37 #include "core/CorePrereqs.h"
    38 
     32#include "InputPrereqs.h"
     33
     34#include <cassert>
    3935#include <string>
    4036#include <vector>
    41 #include "InputInterfaces.h"
     37
     38#include "util/OrxEnum.h"
     39#include "InputHandler.h"
     40#include "JoyStickQuantityListener.h"
    4241
    4342namespace orxonox
    4443{
    45     class _CoreExport InputState
     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    /**
     59    @brief
     60        InputStates allow you to customise the input event targets at runtime.
     61
     62        The general idea is a stack: Every activated InputState will be pushed on
     63        that stack and only the top one gets the input events. This is done for
     64        every device (keyboard, mouse, all joy sticks) separately to allow
     65        for intance keyboard input capturing for the console while you can still
     66        steer a ship with the mouse.
     67        There are two exceptions to this behaviour though:
     68        - If an InputState is created with the 'Transparent' parameter on, the
     69          state will not prevent input from getting to the state below it on the stack.
     70          This can be useful for instance if you need to deploy input to multiple
     71          handlers: Simply create two InputStates and make the high priority one transparent.
     72        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
     73          the state will always receive input as long as it is activated.
     74        - Note: If you mark an InputState with both parameters on, then it will
     75          not influence ony other InputState at all.
     76
     77        Priorities
     78        **********
     79        Every InputState has a priority when on the stack, but mostly this
     80        priority is dynamic (InputStatePriority::Dynamic) which means that a state
     81        pushed onto the stack will simply have a higher priority than the top one.
     82        This behaviour really only applies to normal states that don't have
     83        a high priority (InputStatePriority::HighPriority). These 'special' ones
     84        are used for features like the KeyDetector or the console. Use with care!
     85    */
     86    class _CoreExport InputState : public JoyStickQuantityListener
    4687    {
    4788        friend class InputManager;
    4889
     90        //! Marks the index in the handler vector for the keyboard handler
     91        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
     92        //! Marks the index in the handler vector for the mouse handler
     93        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
     94        //! Marks the index in the handler vector for the first joy stick handler
     95        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
     96
    4997    public:
     98        //! Sets the keyboard event handler (overwrites if there already was one!)
     99        void setKeyHandler     (InputHandler* handler)
     100            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
     101        //! Sets the mouse event handler (overwrites if there already was one!)
     102        void setMouseHandler   (InputHandler* handler)
     103            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
     104        /**
     105        @brief
     106            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
     107        @return
     108            Returns false if the specified device was not found
     109        */
     110        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
     111        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
     112        void setJoyStickHandler(InputHandler* handler);
     113        //! Sets an InputHandler to be used for all devices
     114        void setHandler        (InputHandler* handler);
     115
     116        //! Returns the name of the state (which is unique!)
    50117        const std::string& getName() const { return name_; }
     118        //! Returns the priority of the state (which is unique if != 0)
    51119        int getPriority()            const { return priority_; }
    52120
    53         bool isInputDeviceEnabled(unsigned int device)
     121        //! Tells whether there a handler installed for a specific device
     122        bool isInputDeviceEnabled(unsigned int device);
     123
     124        //! Returns true if the handler situation has changed
     125        bool hasExpired()      { return this->bExpired_; }
     126        //! Call this if you have applied the changes resulting from changed handlers
     127        void resetExpiration() { bExpired_ = false; }
     128
     129        //! Updates one specific device handler with #device#Updated
     130        void update(float dt, unsigned int device);
     131        //! Updates all handlers with allDevicesUpdated
     132        void update(float dt);
     133
     134        //! Generic function that distributes all 9 button events
     135        template <typename EventType, class Traits>
     136        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
     137
     138        //! Event handler
     139        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
     140        //! Event handler
     141        void mouseScrolled(int abs, int rel);
     142        //! Event handler
     143        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
     144
     145        // Functors
     146        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
     147        void entered();
     148        //! Called upon deactivation of the state
     149        void left();
     150        //! Sets a functor to be called upon activation of the state
     151        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
     152        //! Sets a functor to be called upon deactivation of the state
     153        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
     154
     155    private:
     156        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
     157        ~InputState() { }
     158
     159        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
     160
     161        //! Sets the priority (only to be used by the InputManager!)
     162        void setPriority(int priority) { priority_ = priority; }
     163
     164        const std::string           name_;                  //!< Name of the state
     165        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
     166        const bool                  bTransparent_;          //!< See class declaration for explanation
     167        int                         priority_;              //!< Current priority (might change)
     168        bool                        bExpired_;              //!< See hasExpired()
     169        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
     170        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
     171        InputHandler*               joyStickHandlerAll_;
     172        Functor*                    enterFunctor_;          //!< Functor to be executed on enter
     173        Functor*                    leaveFunctor_;          //!< Functor to be executed on leave
     174    };
     175
     176    FORCEINLINE void InputState::update(float dt)
     177    {
     178        for (unsigned int i = 0; i < handlers_.size(); ++i)
     179            if (handlers_[i] != NULL)
     180                handlers_[i]->allDevicesUpdated(dt);
     181    }
     182
     183    FORCEINLINE void InputState::update(float dt, unsigned int device)
     184    {
     185        switch (device)
    54186        {
    55             if (device < bInputDeviceEnabled_.size())
    56                 return bInputDeviceEnabled_[device];
    57             else
    58                 return false;
     187        case InputDeviceEnumerator::Keyboard:
     188            if (handlers_[keyboardIndex_s] != NULL)
     189                handlers_[keyboardIndex_s]->keyboardUpdated(dt);
     190            break;
     191
     192        case InputDeviceEnumerator::Mouse:
     193            if (handlers_[mouseIndex_s] != NULL)
     194                handlers_[mouseIndex_s]->mouseUpdated(dt);
     195            break;
     196
     197        default: // joy sticks
     198            if (handlers_[device] != NULL)
     199                handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
     200            break;
    59201        }
    60 
    61         bool handlersChanged() { return this->bHandlersChanged_; }
    62         void resetHandlersChanged() { bHandlersChanged_ = false; }
    63 
    64         virtual void onEnter() = 0;
    65         virtual void onLeave() = 0;
    66 
    67         virtual void registerOnEnter(Executor* executor)      { executorOnEnter_ = executor; }
    68         virtual void unRegisterOnEnter()                      { executorOnEnter_ = 0; }
    69         virtual void registerOnLeave(Executor* executor)      { executorOnLeave_ = executor; }
    70         virtual void unRegisterOnLeave()                      { executorOnLeave_ = 0; }
    71 
    72         virtual void updateInput(float dt, unsigned int device) = 0;
    73         virtual void updateInput(float dt) = 0;
    74 
    75         virtual void keyPressed (const KeyEvent& evt) = 0;
    76         virtual void keyReleased(const KeyEvent& evt) = 0;
    77         virtual void keyHeld    (const KeyEvent& evt) = 0;
    78 
    79         virtual void mouseButtonPressed (MouseButtonCode::ByEnum id) = 0;
    80         virtual void mouseButtonReleased(MouseButtonCode::ByEnum id) = 0;
    81         virtual void mouseButtonHeld    (MouseButtonCode::ByEnum id) = 0;
    82         virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
    83         virtual void mouseScrolled      (int abs, int rel) = 0;
    84 
    85         virtual void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
    86         virtual void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
    87         virtual void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id) = 0;
    88         virtual void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value) = 0;
    89 
    90     protected:
    91         InputState()
    92             : bHandlersChanged_(false)
    93             , executorOnEnter_(0)
    94             , executorOnLeave_(0)
    95             , priority_(0)
    96             , bAlwaysGetsInput_(false)
    97             , bTransparent_(false)
    98         { }
    99         virtual ~InputState() { }
    100 
    101         virtual void numberOfJoySticksChanged(unsigned int n) = 0;
    102         void setInputDeviceEnabled(unsigned int device, bool bEnabled)
    103         {
    104             if (device < bInputDeviceEnabled_.size())
    105                 bInputDeviceEnabled_[device] = bEnabled;
    106         }
    107 
    108         bool bHandlersChanged_;
    109         Executor*                                   executorOnEnter_;
    110         Executor*                                   executorOnLeave_;
    111 
    112     private:
    113         void setNumOfJoySticks(unsigned int n)
    114         {
    115             bInputDeviceEnabled_.resize(n + 2);
    116             numberOfJoySticksChanged(n);
    117         }
    118         void setName(const std::string& name)  { name_ = name; }
    119         void setPriority(int priority)         { priority_ = priority; }
    120 
    121         std::string                                 name_;
    122         int                                         priority_;
    123         std::vector<bool>                           bInputDeviceEnabled_;
    124         bool                                        bAlwaysGetsInput_;
    125         bool                                        bTransparent_;
    126     };
     202    }
     203
     204    template <typename EventType, class Traits>
     205    FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
     206    {
     207        assert(device < handlers_.size());
     208        if (handlers_[device] != NULL)
     209            handlers_[device]->buttonEvent(device, button, EventType());
     210    }
     211
     212    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     213    {
     214        if (handlers_[mouseIndex_s] != NULL)
     215            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
     216    }
     217
     218    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
     219    {
     220        if (handlers_[mouseIndex_s] != NULL)
     221            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
     222    }
     223
     224    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
     225    {
     226        assert(device < handlers_.size());
     227        if (handlers_[device] != NULL)
     228            handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
     229    }
    127230}
    128231
  • code/trunk/src/core/input/JoyStick.cc

    r3270 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32     Implementation of the JoyStick wrapper class.
    33 */
    34 
    3529#include "JoyStick.h"
    3630
    3731#include <ois/OISJoyStick.h>
    38 #include <ois/OISInputManager.h>
    3932#include <boost/foreach.hpp>
    4033
     
    4437#include "util/Convert.h"
    4538#include "InputState.h"
    46 #include "InputManager.h"
    4739
    4840namespace orxonox
    4941{
    50     /**
    51     @brief
    52         Helper function that loads the config value vector of one coefficient
    53     */
     42    //! Helper function that loads the config value vector of one coefficient
    5443    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
    5544
    56     JoyStick::JoyStick(const std::vector<InputState*>& states, unsigned int id)
    57         : id_(id)
    58         , bCalibrating_(false)
    59         , inputStates_(states)
     45    std::vector<std::string> JoyStick::deviceNames_s;
     46
     47    JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager)
     48        : super(id, oisInputManager)
    6049    {
    6150        RegisterRootObject(JoyStick);
    6251        this->setConfigValues();
    63 
    64         OIS::InputManager* system = InputManager::getInstance().getInputSystem();
    65         oisJoyStick_ = static_cast<OIS::JoyStick*>(system->createInputObject(OIS::OISJoyStick, true));
    66         oisJoyStick_->setEventCallback(this);
    67 
    68         idString_ = "JoyStick_";
    69         std::string name = oisJoyStick_->vendor();
    70         replaceCharacters(name, ' ', '_');
    71         idString_ += name + "_";
    72         idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Button))  + "_";
    73         idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
    74         idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
    75         idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_POV));
    76         //idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Vector3));
    77 
    78         if (InputManager::getInstance().checkJoyStickID(idString_) == false)
    79         {
    80             // Make the ID unique for this execution time.
    81             idString_ += "_" + multi_cast<std::string>(id_);
    82         }
    83 
    84         COUT(4) << "Created OIS joy stick with ID " << idString_ << std::endl;
     52        // Initialise POV and Slider states
     53        this->clearBuffersImpl();
     54
     55        // Generate unique name
     56        if (oisDevice_->vendor().empty())
     57            deviceName_ = "Unknown_";
     58        else
     59        {
     60            std::string name = oisDevice_->vendor();
     61            replaceCharacters(name, ' ', '_');
     62            deviceName_ = name + "_";
     63        }
     64        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
     65        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
     66        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
     67        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
     68        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
     69
     70        BOOST_FOREACH(std::string& idString, deviceNames_s)
     71        {
     72            if (deviceName_ == idString)
     73            {
     74                // Make the ID unique for this execution time.
     75                deviceName_ += "_" + multi_cast<std::string>(this->getDeviceName());
     76                break;
     77            }
     78        }
     79
     80        COUT(4) << "Created OIS joy stick with ID " << deviceName_ << std::endl;
    8581
    8682        // Load calibration
    87         size_t axes = sliderAxes_s + static_cast<size_t>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis));
    88         loadCalibration(configMinValues_,  idString_, "MinValue",  axes,  -32768);
    89         loadCalibration(configMaxValues_,  idString_, "MaxValue",  axes,   32768);
    90         loadCalibration(configZeroValues_, idString_, "ZeroValue", axes, 0);
     83        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
     84        loadCalibration(configMinValues_,  deviceName_, "MinValue",  axes,  -32768);
     85        loadCalibration(configMaxValues_,  deviceName_, "MaxValue",  axes,   32768);
     86        loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0);
    9187        this->evaluateCalibration();
    9288    }
    9389
    94     JoyStick::~JoyStick()
    95     {
    96         try
    97         {
    98             OIS::InputManager* system = InputManager::getInstance().getInputSystem();
    99             system->destroyInputObject(oisJoyStick_);
    100         }
    101         catch (...)
    102         {
    103             COUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
    104         }
    105     }
    106 
    107     /**
    108     @brief
    109         Callback for the joy stick calibration config file. @see setConfigValues.
    110     */
     90    //! Callback for the joy stick calibration config file.
    11191    void JoyStick::calibrationFileCallback()
    11292    {
     
    11494    }
    11595
    116     /**
    117     @brief
    118         Sets the configurable values.
    119     */
    12096    void JoyStick::setConfigValues()
    12197    {
     
    140116        // fill the rest with default values
    141117        for (unsigned int i = configValueVectorSize; i < size; ++i)
    142         {
    143118            list[i] = defaultValue;
    144         }
    145     }
    146 
    147     void JoyStick::startCalibration()
    148     {
    149         bCalibrating_ = true;
    150 
     119    }
     120
     121    //! Called by InputDevice when calibration mode has started
     122    void JoyStick::calibrationStarted()
     123    {
    151124        // Set initial values
    152125        BOOST_FOREACH(int& minVal, configMinValues_)
     
    158131    }
    159132
    160     void JoyStick::stopCalibration()
     133    //! Called by InputDevice when calibration mode has stopped
     134    void JoyStick::calibrationStopped()
    161135    {
    162136        // Get the middle positions now
     
    164138        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
    165139        {
    166             configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abX;
    167             configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abY;
    168         }
    169         // Note: joyStickMiddleValues_[iJoyStick] was already correctly resised in loadCalibration()
    170         assert(oisJoyStick_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
     140            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
     141            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
     142        }
     143        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
     144        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
    171145        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
    172             configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mAxes[i].abs;
     146            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
    173147
    174148        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
     
    178152                configMinValues_[i] = -32768;
    179153            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    180                 idString_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
     154                deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
    181155
    182156            // Maximum values
     
    184158                configMaxValues_[i] = 32767;
    185159            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    186                 idString_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
     160                deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
    187161
    188162            // Middle values
    189163            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
    190                 idString_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
     164                deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
    191165        }
    192166
    193167        this->evaluateCalibration();
    194 
    195         bCalibrating_ = false;
    196     }
    197 
     168    }
     169
     170    //! Evaluates the accumulated values during calibration
    198171    void JoyStick::evaluateCalibration()
    199172    {
     
    206179    }
    207180
    208     void JoyStick::clearBuffer()
    209     {
    210         pressedButtons_.clear();
     181    //! Resets the pov states
     182    void JoyStick::clearBuffersImpl()
     183    {
    211184        for (int j = 0; j < 4; ++j)
    212         {
    213185            povStates_[j] = 0;
    214             sliderStates_[j][0] = 0;
    215             sliderStates_[j][1] = 0;
    216         }
    217     }
    218 
    219 
    220     // ###### Events ######
    221 
    222     void JoyStick::capture()
    223     {
    224         oisJoyStick_->capture();
    225 
    226         // call all the handlers for the held joy stick button events
    227         for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
    228         {
    229             BOOST_FOREACH(InputState* state, inputStates_)
    230                 state->joyStickButtonHeld(id_, pressedButtons_[iButton]);
    231         }
    232     }
    233 
    234     bool JoyStick::buttonPressed(const OIS::JoyStickEvent &arg, int button)
    235     {
    236         // check whether the button already is in the list (can happen when focus was lost)
    237         unsigned int iButton = 0;
    238         while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
    239             iButton++;
    240         if (iButton == pressedButtons_.size())
    241             pressedButtons_.push_back(static_cast<JoyStickButtonCode::ByEnum>(button));
    242 
    243         BOOST_FOREACH(InputState* state, inputStates_)
    244             state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
    245 
    246         return true;
    247     }
    248 
    249     bool JoyStick::buttonReleased(const OIS::JoyStickEvent &arg, int button)
    250     {
    251         // remove the button from the pressedButtons_ list
    252         for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
    253         {
    254             if (static_cast<int>(pressedButtons_[iButton]) == button)
    255             {
    256                 pressedButtons_.erase(pressedButtons_.begin() + iButton);
    257                 break;
    258             }
    259         }
    260 
    261         BOOST_FOREACH(InputState* state, inputStates_)
    262             state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
    263 
    264         return true;
    265     }
    266 
    267     /**
    268     @brief
    269         Calls the states for a particular axis with our enumeration.
    270         Used by OIS sliders and OIS axes.
    271     */
     186    }
     187
     188    //! Generic method to forward axis events
    272189    void JoyStick::fireAxis(int axis, int value)
    273190    {
    274         if (bCalibrating_)
     191        if (this->isCalibrating())
    275192        {
    276193            if (value < configMinValues_[axis])
     
    288205
    289206            BOOST_FOREACH(InputState* state, inputStates_)
    290                 state->joyStickAxisMoved(id_, axis, fValue);
    291         }
    292     }
    293 
     207                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
     208        }
     209    }
     210
     211    //! OIS joy stick axis event handler
    294212    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
    295213    {
     
    300218    }
    301219
     220    //! A Slider always has an X and an Y direction!
    302221    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
    303222    {
     
    310229    }
    311230
     231    //! A POV is the big button that can point in all directions (but only in one at once)
    312232    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
    313233    {
  • code/trunk/src/core/input/JoyStick.h

    r3270 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32 */
     29#ifndef _Core_JoyStick_H__
     30#define _Core_JoyStick_H__
    3331
    34 #ifndef _JoyStick_H__
    35 #define _JoyStick_H__
    36 
    37 #include "core/CorePrereqs.h"
     32#include "InputPrereqs.h"
    3833
    3934#include <string>
    4035#include <vector>
    41 #include "InputInterfaces.h"
     36#include "InputDevice.h"
    4237
    4338namespace orxonox
    4439{
    45     class _CoreExport JoyStick : public OrxonoxClass, public OIS::JoyStickListener
     40    //! Template parameter collection for the base class
     41    struct JoyStickTraits
    4642    {
    47     private:
    48         struct JoyStickCalibration
    49         {
    50         };
     43        typedef JoyStick DeviceClass;
     44        typedef OIS::JoyStick OISDeviceClass;
     45        typedef JoyStickButtonCode::ByEnum ButtonType;
     46        typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
     47        static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
     48    };
     49
     50    /**
     51    @brief
     52        Wraps around an OIS::JoyStick and forwards the input events to
     53        a list of input states.
     54
     55        The class also supports joy stick calibration and stores the values
     56        in an ini-file.
     57    */
     58    class _CoreExport JoyStick
     59        : public OrxonoxClass
     60        , public InputDeviceTemplated<JoyStickTraits>
     61        , public OIS::JoyStickListener
     62    {
     63        friend class InputDeviceTemplated<JoyStickTraits>;
     64        //! Super class alias
     65        typedef InputDeviceTemplated<JoyStickTraits> super;
    5166
    5267    public:
    53         JoyStick(const std::vector<InputState*>& states, unsigned int id);
    54         ~JoyStick();
    55 
     68        //! Assigns a generated ID string and loads the calibration (if present)
     69        JoyStick(unsigned int id, OIS::InputManager* oisInputManager);
     70        ~JoyStick() { }
    5671        void setConfigValues();
    5772
    58         OIS::JoyStick* getOISJoyStick() { return this->oisJoyStick_; }
    59         const std::string& getIDString() const { return this->idString_; }
    60 
    61         void startCalibration();
    62         void stopCalibration();
    63 
    64         void capture();
    65         void clearBuffer();
     73        //! Returns the name generated from the number of knobs and the device name
     74        const std::string& getDeviceName() const { return this->deviceName_; }
    6675
    6776    private:
     77        void calibrationStarted();
     78        void calibrationStopped();
     79        void evaluateCalibration();
     80
     81        void clearBuffersImpl();
    6882        void calibrationFileCallback();
    69         void evaluateCalibration();
    7083        void fireAxis(int axis, int value);
    7184
    72         bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
    73         bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
     85        //! OIS event handler
     86        bool buttonPressed (const OIS::JoyStickEvent &arg, int button)
     87        {
     88            super::buttonPressed(static_cast<JoyStickButtonCode::ByEnum>(button));
     89            return true;
     90        }
     91
     92        //! OIS event handler
     93        bool buttonReleased(const OIS::JoyStickEvent &arg, int button)
     94        {
     95            super::buttonReleased(static_cast<JoyStickButtonCode::ByEnum>(button));
     96            return true;
     97        }
     98
    7499        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
    75100        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
    76101        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
    77         // don't remove that! Or else add OIS as dependency library to orxonox (it actually is..)
     102        //! OIS event handler (don't remove that because of OIS version issues!)
    78103        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
    79104
    80         static const unsigned int sliderAxes_s = 8;
     105        //! Returns the class name as string
     106        static std::string getClassNameImpl() { return "JoyStick"; }
    81107
    82         OIS::JoyStick* oisJoyStick_;
    83         const unsigned int id_;
    84         std::string idString_;
     108        std::string deviceName_;              //!< Name generated by the number of knobs and the device name
     109        int povStates_[4];                    //!< Internal states for the POVs
     110        int sliderStates_[4][2];              //!< Internal states for the Sliders (each slider has X and Y!)
    85111
    86112        // calibration
    87         bool bCalibrating_;
    88         int zeroValues_[24];
    89         float positiveCoeffs_[24];
    90         float negativeCoeffs_[24];
     113        int zeroValues_[24];                  //!< Axes values when the knob is in the middle
     114        float positiveCoeffs_[24];            //!< Maps the negative part of an axis to a 0.0 to 1.0 floating range
     115        float negativeCoeffs_[24];            //!< Maps the positive part of an axis to a 0.0 to 1.0 floating range
    91116
    92         std::vector<int> configMinValues_;
    93         std::vector<int> configMaxValues_;
    94         std::vector<int> configZeroValues_;
    95 
    96         int povStates_[4];
    97         int sliderStates_[4][2];
    98         std::vector<JoyStickButtonCode::ByEnum> pressedButtons_;
    99 
    100         // InputState handling
    101         const std::vector<InputState*>& inputStates_;
     117        std::vector<int> configZeroValues_;   //!< Config file stored axis values when the knob is in the middle
     118        std::vector<int> configMinValues_;    //!< Config file stored minimum axis values
     119        std::vector<int> configMaxValues_;    //!< Config file stored maximum axis values
    102120
    103121        // ConfigValues
    104         std::string calibrationFilename_;  //!< Joy stick calibration ini filename
     122        std::string calibrationFilename_;     //!< Joy stick calibration ini filename
     123
     124        //! Contains a list of all names to avoid duplicates
     125        static std::vector<std::string> deviceNames_s;
     126
     127        //!< Maximum number of slider axes
     128        static const unsigned int sliderAxes_s = 8;
    105129    };
    106130}
    107131
    108 #endif /* _JoyStick_H__ */
     132#endif /* _Core_JoyStick_H__ */
  • code/trunk/src/core/input/JoyStickQuantityListener.cc

    r3276 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32     Implementation of the JoyStickQuantityListener class.
    33 */
     29#include "JoyStickQuantityListener.h"
    3430
    35 #include "JoyStickQuantityListener.h"
    3631#include "core/CoreIncludes.h"
     32#include "core/ObjectList.h"
    3733
    3834namespace orxonox
    3935{
     36    std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s;
     37
    4038    JoyStickQuantityListener::JoyStickQuantityListener()
    4139    {
    4240        RegisterObject(JoyStickQuantityListener);
    4341    }
     42
     43    //! Calls all registered objects and sets the static variable
     44    /*static*/ void JoyStickQuantityListener::changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList)
     45    {
     46        joyStickList_s = joyStickList;
     47        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
     48            it->JoyStickQuantityChanged(joyStickList);
     49    }
    4450}
  • code/trunk/src/core/input/JoyStickQuantityListener.h

    r3276 r3327  
    4040namespace orxonox
    4141{
     42    //! Derive from this class to get informed when joy sticks get added/removed
    4243    class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass
    4344    {
    44     public:
     45        friend class InputManager;
     46    protected:
    4547        JoyStickQuantityListener();
    4648        virtual ~JoyStickQuantityListener() { }
    4749
    48         virtual void JoyStickQuantityChanged(unsigned int value) = 0;
     50        //! Returns a list with all JoySticks currently loaded
     51        const std::vector<JoyStick*>& getJoyStickList() const { return joyStickList_s; }
     52
     53    private:
     54        //! Called whenever joy sticks get added/removed
     55        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) = 0;
     56
     57        static void changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList);
     58
     59        //! Static variable that holds the latest distributed information
     60        static std::vector<JoyStick*> joyStickList_s;
    4961    };
    5062}
  • code/trunk/src/core/input/KeyBinder.cc

    r3301 r3327  
    4040#include "core/ConfigFileManager.h"
    4141#include "InputCommands.h"
    42 #include "InputManager.h"
     42#include "JoyStick.h"
    4343
    4444namespace orxonox
     
    4949    */
    5050    KeyBinder::KeyBinder()
    51         : numberOfJoySticks_(0)
    52         , deriveTime_(0.0f)
     51        : deriveTime_(0.0f)
    5352    {
    5453        mouseRelative_[0] = 0;
     
    5655        mousePosition_[0] = 0;
    5756        mousePosition_[1] = 0;
     57
     58        joyStickButtons_.reserve(1000);
     59        joyStickAxes_.reserve(1000);
    5860
    5961        RegisterRootObject(KeyBinder);
     
    8082            else
    8183                nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
    82             mouseButtons_[i].name_ = std::string("Mouse") + nameSuffix;
     84            mouseButtons_[i].name_ = nameSuffix;
    8385            mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
    8486            mouseButtons_[i].groupName_ = "MouseButtons";
     
    8789        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
    8890        {
    89             mouseAxes_[i].name_ = std::string("Mouse") + MouseAxisCode::ByString[i / 2];
     91            mouseAxes_[i].name_ = MouseAxisCode::ByString[i / 2];
    9092            if (i & 1)
    9193                mouseAxes_[i].name_ += "Pos";
     
    100102
    101103        // initialise joy sticks separatly to allow for reloading
    102         numberOfJoySticks_ = InputManager::getInstance().numberOfJoySticks();
    103         initialiseJoyStickBindings();
    104 
    105         // collect all Buttons and HalfAxes
    106         compilePointerLists();
     104        this->JoyStickQuantityChanged(this->getJoyStickList());
    107105
    108106        // set them here to use allHalfAxes_
     
    152150    }
    153151
    154     void KeyBinder::JoyStickDeviceNumberChanged(unsigned int value)
    155     {
    156         unsigned int oldValue = numberOfJoySticks_;
    157         numberOfJoySticks_ = value;
     152    void KeyBinder::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
     153    {
     154        unsigned int oldValue = joySticks_.size();
     155        joySticks_ = joyStickList;
    158156
    159157        // initialise joy stick bindings
     
    166164        if (configFile_ != ConfigFileType::NoType)
    167165        {
    168             for (unsigned int iDev = oldValue; iDev < numberOfJoySticks_; ++iDev)
     166            for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev)
    169167            {
    170168                for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
     
    181179    void KeyBinder::initialiseJoyStickBindings()
    182180    {
    183         this->joyStickAxes_.resize(numberOfJoySticks_);
    184         this->joyStickButtons_.resize(numberOfJoySticks_);
     181        this->joyStickAxes_.resize(joySticks_.size());
     182        this->joyStickButtons_.resize(joySticks_.size());
    185183
    186184        // reinitialise all joy stick binings (doesn't overwrite the old ones)
    187         for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
    188         {
    189             std::string deviceNumber = multi_cast<std::string>(iDev);
     185        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
     186        {
     187            std::string deviceName = joySticks_[iDev]->getDeviceName();
    190188            // joy stick buttons
    191189            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
    192190            {
    193                 joyStickButtons_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickButtonCode::ByString[i];
     191                joyStickButtons_[iDev][i].name_ = JoyStickButtonCode::ByString[i];
    194192                joyStickButtons_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
    195                 joyStickButtons_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Buttons";
     193                joyStickButtons_[iDev][i].groupName_ = "JoyStickButtons_" + deviceName;
    196194            }
    197195            // joy stick axes
    198196            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
    199197            {
    200                 joyStickAxes_[iDev][i].name_ = std::string("JoyStick") + deviceNumber + JoyStickAxisCode::ByString[i >> 1];
     198                joyStickAxes_[iDev][i].name_ = JoyStickAxisCode::ByString[i / 2];
    201199                if (i & 1)
    202200                    joyStickAxes_[iDev][i].name_ += "Pos";
     
    204202                    joyStickAxes_[iDev][i].name_ += "Neg";
    205203                joyStickAxes_[iDev][i].paramCommandBuffer_ = &paramCommandBuffer_;
    206                 joyStickAxes_[iDev][i].groupName_ = std::string("JoyStick") + deviceNumber + "Axes";
     204                joyStickAxes_[iDev][i].groupName_ = "JoyStickAxes_" + deviceName;
    207205            }
    208206        }
     
    217215        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
    218216            if (!keys_[i].name_.empty())
    219                 allButtons_[keys_[i].name_] = keys_ + i;
     217                allButtons_[keys_[i].groupName_ + "." + keys_[i].name_] = keys_ + i;
    220218        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
    221             allButtons_[mouseButtons_[i].name_] = mouseButtons_ + i;
     219            allButtons_[mouseButtons_[i].groupName_ + "." + mouseButtons_[i].name_] = mouseButtons_ + i;
    222220        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
    223221        {
    224             allButtons_[mouseAxes_[i].name_] = mouseAxes_ + i;
     222            allButtons_[mouseAxes_[i].groupName_ + "." + mouseAxes_[i].name_] = mouseAxes_ + i;
    225223            allHalfAxes_.push_back(mouseAxes_ + i);
    226224        }
    227         for (unsigned int iDev = 0; iDev < numberOfJoySticks_; iDev++)
     225        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
    228226        {
    229227            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
    230                 allButtons_[joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
     228                allButtons_[joyStickButtons_[iDev][i].groupName_ + "." + joyStickButtons_[iDev][i].name_] = &(joyStickButtons_[iDev][i]);
    231229            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
    232230            {
    233                 allButtons_[joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
     231                allButtons_[joyStickAxes_[iDev][i].groupName_ + "." + joyStickAxes_[iDev][i].name_] = &(joyStickAxes_[iDev][i]);
    234232                allHalfAxes_.push_back(&(joyStickAxes_[iDev][i]));
    235233            }
     
    301299    void KeyBinder::resetJoyStickAxes()
    302300    {
    303         for (unsigned int iDev = 0; iDev < numberOfJoySticks_; ++iDev)
     301        for (unsigned int iDev = 0; iDev < joySticks_.size(); ++iDev)
    304302        {
    305303            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
     
    311309    }
    312310
    313     void KeyBinder::updateMouse(float dt)
     311    void KeyBinder::mouseUpdated(float dt)
    314312    {
    315313        if (bDeriveMouseInput_)
     
    364362    }
    365363
    366     void KeyBinder::updateJoyStick(float dt, unsigned int joyStick)
     364    void KeyBinder::joyStickUpdated(unsigned int joyStick, float dt)
    367365    {
    368366        for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
     
    480478    }
    481479
    482     void KeyBinder::joyStickAxisMoved(unsigned int joyStickID, unsigned int axis, float value)
    483     {
    484         int i = axis * 2;
     480    void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value)
     481    {
     482        int i = axisID * 2;
     483        JoyStickAxisVector& axis = joyStickAxes_[device];
    485484        if (value < 0)
    486485        {
    487             joyStickAxes_[joyStickID][i].absVal_ = -value;
    488             joyStickAxes_[joyStickID][i].relVal_ = -value;
    489             joyStickAxes_[joyStickID][i].hasChanged_ = true;
    490             if (joyStickAxes_[joyStickID][i + 1].absVal_ > 0.0f)
    491             {
    492                 joyStickAxes_[joyStickID][i + 1].absVal_ = -0.0f;
    493                 joyStickAxes_[joyStickID][i + 1].relVal_ = -0.0f;
    494                 joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
     486            axis[i].absVal_ = -value;
     487            axis[i].relVal_ = -value;
     488            axis[i].hasChanged_ = true;
     489            if (axis[i + 1].absVal_ > 0.0f)
     490            {
     491                axis[i + 1].absVal_ = -0.0f;
     492                axis[i + 1].relVal_ = -0.0f;
     493                axis[i + 1].hasChanged_ = true;
    495494            }
    496495        }
    497496        else
    498497        {
    499             joyStickAxes_[joyStickID][i + 1].absVal_ = value;
    500             joyStickAxes_[joyStickID][i + 1].relVal_ = value;
    501             joyStickAxes_[joyStickID][i + 1].hasChanged_ = true;
    502             if (joyStickAxes_[joyStickID][i].absVal_ > 0.0f)
    503             {
    504                 joyStickAxes_[joyStickID][i].absVal_ = -0.0f;
    505                 joyStickAxes_[joyStickID][i].relVal_ = -0.0f;
    506                 joyStickAxes_[joyStickID][i].hasChanged_ = true;
     498            axis[i + 1].absVal_ = value;
     499            axis[i + 1].relVal_ = value;
     500            axis[i + 1].hasChanged_ = true;
     501            if (axis[i].absVal_ > 0.0f)
     502            {
     503                axis[i].absVal_ = -0.0f;
     504                axis[i].relVal_ = -0.0f;
     505                axis[i].hasChanged_ = true;
    507506            }
    508507        }
  • code/trunk/src/core/input/KeyBinder.h

    r3196 r3327  
    3636#define _KeyBinder_H__
    3737
    38 #include "core/CorePrereqs.h"
     38#include "InputPrereqs.h"
    3939
    4040#include <cassert>
     
    4242#include <vector>
    4343
    44 #include "InputInterfaces.h"
     44#include "InputHandler.h"
    4545#include "Button.h"
    4646#include "HalfAxis.h"
    4747#include "InputCommands.h"
    48 #include "JoyStickDeviceNumberListener.h"
     48#include "JoyStickQuantityListener.h"
    4949
    5050namespace orxonox
     
    5555        Manages the key bindings.
    5656    */
    57     class _CoreExport KeyBinder : public KeyHandler, public MouseHandler, public JoyStickHandler,
    58                                   public JoyStickDeviceNumberListener
     57    class _CoreExport KeyBinder : public InputHandler, public JoyStickQuantityListener
    5958    {
    6059    public:
     
    6968
    7069    protected: // functions
    71         void updateInput(float dt);
    72         void updateKey(float dt) { }
    73         void updateMouse(float dt);
    74         void updateJoyStick(float dt, unsigned int joyStick);
     70        void allDevicesUpdated(float dt);
     71        void mouseUpdated(float dt);
     72        void joyStickUpdated(unsigned int joyStick, float dt);
    7573        // internal
    7674        void tickHalfAxis(HalfAxis& halfAxis);
    7775
    7876        void buttonThresholdChanged();
    79         // from JoyStickDeviceNumberListener interface
    80         virtual void JoyStickDeviceNumberChanged(unsigned int value);
     77        // from JoyStickQuantityListener interface
     78        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
    8179        void initialiseJoyStickBindings();
    8280        void compilePointerLists();
    8381
    84         void keyPressed (const KeyEvent& evt);
    85         void keyReleased(const KeyEvent& evt);
    86         void keyHeld    (const KeyEvent& evt);
    87 
    88         void mouseButtonPressed (MouseButtonCode::ByEnum id);
    89         void mouseButtonReleased(MouseButtonCode::ByEnum id);
    90         void mouseButtonHeld    (MouseButtonCode::ByEnum id);
    91         void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
    92         void mouseScrolled      (int abs, int rel);
    93 
    94         void joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
    95         void joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
    96         void joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id);
    97         void joyStickAxisMoved     (unsigned int joyStickID, unsigned int axis, float value);
     82        void buttonPressed (const KeyEvent& evt);
     83        void buttonReleased(const KeyEvent& evt);
     84        void buttonHeld    (const KeyEvent& evt);
     85
     86        void buttonPressed (MouseButtonCode::ByEnum button);
     87        void buttonReleased(MouseButtonCode::ByEnum button);
     88        void buttonHeld    (MouseButtonCode::ByEnum button);
     89        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
     90        void mouseScrolled (int abs, int rel);
     91
     92        void buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button);
     93        void buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button);
     94        void buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button);
     95        void axisMoved     (unsigned int device, unsigned int axis, float value);
    9896
    9997    protected: // variables
    10098        //! Currently active joy sticks
    101         unsigned int numberOfJoySticks_;
     99        std::vector<JoyStick*>  joySticks_;
    102100
    103101        //! Actual key bindings for keys on the keyboard
     
    172170    };
    173171
    174     inline void KeyBinder::keyPressed (const KeyEvent& evt)
    175     { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnPress); }
    176 
    177     inline void KeyBinder::keyReleased(const KeyEvent& evt)
    178     { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnRelease); }
    179 
    180     inline void KeyBinder::keyHeld    (const KeyEvent& evt)
    181     { assert(!keys_[evt.key].name_.empty()); keys_[evt.key].execute(KeybindMode::OnHold); }
    182 
    183 
    184     inline void KeyBinder::mouseButtonPressed (MouseButtonCode::ByEnum id)
    185     { mouseButtons_[id].execute(KeybindMode::OnPress); }
    186 
    187     inline void KeyBinder::mouseButtonReleased(MouseButtonCode::ByEnum id)
    188     { mouseButtons_[id].execute(KeybindMode::OnRelease); }
    189 
    190     inline void KeyBinder::mouseButtonHeld    (MouseButtonCode::ByEnum id)
    191     { mouseButtons_[id].execute(KeybindMode::OnHold); }
    192 
    193 
    194     inline void KeyBinder::joyStickButtonPressed (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
    195     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnPress); }
    196 
    197     inline void KeyBinder::joyStickButtonReleased(unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
    198     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnRelease); }
    199 
    200     inline void KeyBinder::joyStickButtonHeld    (unsigned int joyStickID, JoyStickButtonCode::ByEnum id)
    201     { joyStickButtons_[joyStickID][id].execute(KeybindMode::OnHold); }
    202 
    203     inline void KeyBinder::updateInput(float dt)
     172    inline void KeyBinder::buttonPressed (const KeyEvent& evt)
     173    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnPress); }
     174
     175    inline void KeyBinder::buttonReleased(const KeyEvent& evt)
     176    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnRelease); }
     177
     178    inline void KeyBinder::buttonHeld    (const KeyEvent& evt)
     179    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnHold); }
     180
     181
     182    inline void KeyBinder::buttonPressed (MouseButtonCode::ByEnum button)
     183    { mouseButtons_[button].execute(KeybindMode::OnPress); }
     184
     185    inline void KeyBinder::buttonReleased(MouseButtonCode::ByEnum button)
     186    { mouseButtons_[button].execute(KeybindMode::OnRelease); }
     187
     188    inline void KeyBinder::buttonHeld    (MouseButtonCode::ByEnum button)
     189    { mouseButtons_[button].execute(KeybindMode::OnHold); }
     190
     191
     192    inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button)
     193    { joyStickButtons_[device][button].execute(KeybindMode::OnPress); }
     194
     195    inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button)
     196    { joyStickButtons_[device][button].execute(KeybindMode::OnRelease); }
     197
     198    inline void KeyBinder::buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button)
     199    { joyStickButtons_[device][button].execute(KeybindMode::OnHold); }
     200
     201    inline void KeyBinder::allDevicesUpdated(float dt)
    204202    {
    205203        // execute all buffered bindings (additional parameter)
  • code/trunk/src/core/input/KeyDetector.cc

    r3196 r3327  
    2626 *
    2727 */
    28 
    29 /**
    30 @file
    31 @brief
    32     Implementation of the different input handlers.
    33 */
    3428
    3529#include "KeyDetector.h"
     
    6862        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
    6963        {
    70             it->second->bindingString_ = callbackCommand_ + it->second->name_;
     64            it->second->bindingString_ = callbackCommand_ + it->second->groupName_ + "." + it->second->name_;
    7165            it->second->parse();
    7266        }
    7367    }
    7468
    75     void KeyDetector::JoyStickDeviceNumberChanged(unsigned int value)
     69    void KeyDetector::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
    7670    {
    77         KeyBinder::JoyStickDeviceNumberChanged(value);
     71        KeyBinder::JoyStickQuantityChanged(joyStickList);
    7872        setCallbackCommand(callbackCommand_);
    7973    }
  • code/trunk/src/core/input/KeyDetector.h

    r3196 r3327  
    2727 */
    2828
    29 /**
    30 @file
    31 @brief
    32     Different definitions of input processing.
    33 */
    34 
    3529#ifndef _KeyDetector_H__
    3630#define _KeyDetector_H__
    3731
    38 #include "core/CorePrereqs.h"
     32#include "InputPrereqs.h"
    3933
    4034#include <string>
     
    4943        ~KeyDetector();
    5044        void setCallbackCommand(const std::string& command);
    51         void JoyStickDeviceNumberChanged(unsigned int value);
     45        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
    5246
    5347    private:
  • code/trunk/src/core/input/Keyboard.h

    r3276 r3327  
    3131
    3232#include "InputPrereqs.h"
     33
     34#include "InputHandler.h"
    3335#include "InputDevice.h"
    3436
    3537namespace orxonox
    3638{
     39    //! Template parameter collection for the base class
     40    struct KeyboardTraits
     41    {
     42        typedef Keyboard DeviceClass;
     43        typedef OIS::Keyboard OISDeviceClass;
     44        typedef KeyEvent ButtonType;
     45        typedef KeyEvent& ButtonTypeParam;
     46        static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
     47    };
     48
    3749    /**
    3850    @brief
     
    5163
    5264    public:
    53         Keyboard(unsigned int id) : super(id), modifiers_(0) { }
     65        //! Only resets the keyboard modifiers. Initialising is done in the base class.
     66        Keyboard(unsigned int id, OIS::InputManager* oisInputManager) : super(id, oisInputManager), modifiers_(0) { }
    5467        ~Keyboard() { }
    5568
    5669    private:
    57         // TODO: Do we need to reset the modifiers?
    58         void clearBuffersImpl() { }
     70        //! Resets the keyboard modifiers
     71        void clearBuffersImpl() { this->modifiers_ = 0; }
    5972        //! Translates the KeyHandle to a KeyEvent
    60         KeyEvent& getButtonEventArg(KeyEvent& button) { button.setModifiers(modifiers_); return button; }
     73        KeyEvent& getButtonEventArg(KeyEvent& button)
     74        {
     75            button.setModifiers(modifiers_);
     76            return button;
     77        }
    6178
    6279        bool keyPressed(const OIS::KeyEvent& arg);
    6380        bool keyReleased(const OIS::KeyEvent& arg);
     81
     82        //! Returns the class name as string
     83        static std::string getClassNameImpl() { return "Keyboard"; }
    6484
    6585        //! Bit mask representing keyboard modifiers
  • code/trunk/src/core/input/Mouse.cc

    r3276 r3327  
    3030
    3131#include <ois/OISMouse.h>
    32 #include <boost/foreach.hpp>
     32#include "core/ConsoleCommand.h"
     33#include "core/CoreIncludes.h"
    3334#include "InputState.h"
    34 #include "core/ConsoleCommand.h"
    3535
    36 // HACK (include this as last, X11 seems to define some macros...)
    3736#ifdef ORXONOX_PLATFORM_LINUX
    38 #  include <ois/linux/LinuxMouse.h>
     37// include this as last, X11 seems to define some macros...
     38#include <ois/linux/LinuxMouse.h>
    3939#endif
    4040
    4141namespace orxonox
    4242{
    43     Mouse::Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight)
    44         : super(id)
     43    Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager)
     44        : super(id, oisInputManager)
    4545    {
    46         this->setMouseClipping(windowWidth, windowHeight);
    47         // HACK:
    48         instancePointer_s = this;
    49     }
     46        RegisterRootObject(Mouse);
     47        this->windowResized(this->getWindowWidth(), this->getWindowHeight());
    5048
    51     void Mouse::setMouseClipping(unsigned int width, unsigned int height)
    52     {
    53         oisDevice_->getMouseState().width  = width;
    54         oisDevice_->getMouseState().height = height;
    55     }
    56 
    57     unsigned int Mouse::getClippingWidth() const
    58     {
    59         return oisDevice_->getMouseState().width;
    60     }
    61 
    62     unsigned int Mouse::getClippingHeight() const
    63     {
    64         return oisDevice_->getMouseState().height;
     49#ifdef ORXONOX_PLATFORM_LINUX
     50        {
     51            // Mouse grab console command
     52            FunctorMember<Mouse>* functor = createFunctor(&Mouse::grab);
     53            functor->setObject(this);
     54            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "grab"), false);
     55        }
     56        {
     57            // Mouse ungrab console command
     58            FunctorMember<Mouse>* functor = createFunctor(&Mouse::ungrab);
     59            functor->setObject(this);
     60            this->getIdentifier()->addConsoleCommand(createConsoleCommand(functor, "ungrab"), false);
     61        }
     62#endif
    6563    }
    6664
     
    7472            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
    7573            IntVector2 clippingSize(e.state.width, e.state.height);
    76             BOOST_FOREACH(InputState* state, inputStates_)
    77                 state->mouseMoved(abs, rel, clippingSize);
     74            for (unsigned int i = 0; i < inputStates_.size(); ++i)
     75                inputStates_[i]->mouseMoved(abs, rel, clippingSize);
    7876        }
    7977
     
    8179        if (e.state.Z.rel != 0)
    8280        {
    83             BOOST_FOREACH(InputState* state, inputStates_)
    84                 state->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
     81            for (unsigned int i = 0; i < inputStates_.size(); ++i)
     82                inputStates_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
    8583        }
    8684
     
    8886    }
    8987
    90     // ############################################################
    91     // #####                   ugly hacks                     #####
    92     // ##########                                        ##########
    93     // ############################################################
    94 
    95     // HACK:
    96     SetConsoleCommand(Mouse, setMouseClipping_s, false);
    97 #ifdef ORXONOX_PLATFORM_LINUX
    98     SetConsoleCommand(Mouse, grabMouse, true);
    99     SetConsoleCommand(Mouse, ungrabMouse, true);
    100 #endif
    101     Mouse* Mouse::instancePointer_s = NULL;
     88    void Mouse::windowResized(unsigned int newWidth, unsigned int newHeight)
     89    {
     90        oisDevice_->getMouseState().width  = newWidth;
     91        oisDevice_->getMouseState().height = newHeight;
     92    }
    10293
    10394#ifdef ORXONOX_PLATFORM_LINUX
    104     void Mouse::grabMouse()
     95    void Mouse::grab()
    10596    {
    106         OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(instancePointer_s->oisDevice_);
     97        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
    10798        assert(linuxMouse);
    10899        linuxMouse->grab(true);
    109100    }
    110101
    111     void Mouse::ungrabMouse()
     102    void Mouse::ungrab()
    112103    {
    113         OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(instancePointer_s->oisDevice_);
     104        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
    114105        assert(linuxMouse);
    115106        linuxMouse->grab(false);
  • code/trunk/src/core/input/Mouse.h

    r3276 r3327  
    3131
    3232#include "InputPrereqs.h"
     33
    3334#include "InputDevice.h"
     35#include "core/WindowEventListener.h"
    3436
    3537namespace orxonox
    3638{
     39    //! Template parameter collection for the base class
     40    struct MouseTraits
     41    {
     42        typedef Mouse DeviceClass;
     43        typedef OIS::Mouse OISDeviceClass;
     44        typedef MouseButtonCode::ByEnum ButtonType;
     45        typedef MouseButtonCode::ByEnum ButtonTypeParam;
     46        static const OIS::Type OISDeviceValue = OIS::OISMouse;
     47    };
     48
    3749    /**
    3850    @brief
     
    4355        : public InputDeviceTemplated<MouseTraits>
    4456        , public OIS::MouseListener
     57        , public WindowEventListener
    4558    {
    4659        friend class InputDeviceTemplated<MouseTraits>;
     
    4962
    5063    public:
    51         Mouse(unsigned int id, unsigned int windowWidth, unsigned int windowHeight);
     64        //! Only sets the clipping size. Initialising is done in the base class.
     65        Mouse(unsigned int id, OIS::InputManager* oisInputManager);
    5266        ~Mouse() { }
    5367
    54         /**
    55         @brief
    56             Adjusts the mouse window metrics.
    57 
    58             This method has to be called every time the size of the window changes.
    59         */
    60         void setMouseClipping(unsigned int width, unsigned int height);
    61         unsigned int getClippingWidth() const;
    62         unsigned int getClippingHeight() const;
    63 
    64         // HACK!
    65         static void setMouseClipping_s(unsigned int width, unsigned int height)
    66             { instancePointer_s->setMouseClipping(width, height); }
    67         void setConfigValues() { }
    6868#ifdef ORXONOX_PLATFORM_LINUX
    69         // HACK!
    70         static void grabMouse();
    71         static void ungrabMouse();
     69        // TODO: Make this a feature rather than a hack
     70        void grab();
     71        void ungrab();
    7272#endif
    7373
    7474    private:
    75         // TODO: Do we need to reset the mouse position?
    76         void clearBuffersImpl() { }
    77 
    7875        //! OIS event handler
    7976        bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
     
    9289        bool mouseMoved(const OIS::MouseEvent &arg);
    9390
    94         // HACK:
    95         static Mouse* instancePointer_s;
     91        void windowResized(unsigned int newWidth, unsigned int newHeight);
     92
     93        // Returns the class name as string
     94        static std::string getClassNameImpl() { return "Mouse"; }
    9695    };
    9796}
Note: See TracChangeset for help on using the changeset viewer.