Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/wiimote/src/libraries/core/input/InputState.h @ 9856

Last change on this file since 9856 was 9805, checked in by smerkli, 11 years ago
  • Converted some absolute paths into relative ones
  • Increased the handlers_ vector size by 1 as a hack to get the wiimote working in this branch (This will have to be cleanly redone once I have a better concept for wiimotes and joysticks)
  • Removed a local inputStates_ variable that georgr added in wiimote, it shadowed the one from the basis class and hence never got any entries

To be discussed with georgr on monday.

  • Property svn:eol-style set to native
File size: 11.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _InputState_H__
30#define _InputState_H__
31
32#include "InputPrereqs.h"
33
34#include <cassert>
35#include <string>
36#include <vector>
37#include <boost/function.hpp>
38#include <boost/bind.hpp>
39
40#include "util/tribool.h"
41#include "InputHandler.h"
42#include "InputManager.h"
43#include "JoyStickQuantityListener.h"
44
45#define INPUT_STATE_PUSH_CALL(deviceIndex, functionName, ...) \
46    InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(&InputHandler::functionName, handlers_[deviceIndex], __VA_ARGS__)))
47
48namespace orxonox
49{
50    /**
51    @brief
52        InputStates allow you to customise the input event targets at runtime.
53
54        The general idea is a stack: Every activated InputState will be pushed on
55        that stack and only the top one gets the input events. This is done for
56        every device (keyboard, mouse, all joy sticks) separately to allow
57        for instance keyboard input capturing for the console while you can still
58        steer a ship with the mouse.
59        There are two exceptions to this behaviour though:
60        - If an InputState is created with the 'Transparent' parameter on, the
61          state will not prevent input from getting to the state below it on the stack.
62          This can be useful for instance if you need to deploy input to multiple
63          handlers: Simply create two InputStates and make the high priority one transparent.
64        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
65          the state will always receive input as long as it is activated.
66        - Note: If you mark an InputState with both parameters on, then it will
67          not influence only other InputState at all.
68
69    @par Priorities
70        Every InputState has a priority when on the stack, but mostly this
71        priority is dynamic (InputStatePriority::Dynamic) which means that a state
72        pushed onto the stack will simply have a higher priority than the top one.
73        This behaviour really only applies to normal states that don't have
74        a high priority (InputStatePriority::HighPriority). These 'special' ones
75        are used for features like the KeyDetector or the console. Use with care!
76
77    @par Exclusive/Non-Exclusive mouse Mode
78        You can select a specific mouse mode that tells whether the application
79        should have exclusive access to it or not.
80        When in non-exclusive mode, you can move the mouse out of the window
81        like with any other normal window (only for windowed mode!).
82        The setting is dictated by the topmost InputState that gets mouse events.
83    */
84    class _CoreExport InputState : public JoyStickQuantityListener
85    {
86        friend class InputManager;
87
88        //! Marks the index in the handler vector for the keyboard handler
89        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
90        //! Marks the index in the handler vector for the mouse handler
91        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
92        //! Marks the index in the handler vector for the first joy stick handler
93        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
94
95    public:
96        //! Sets the keyboard event handler (overwrites if there already was one!)
97        void setKeyHandler     (InputHandler* handler)
98            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
99        //! Sets the mouse event handler (overwrites if there already was one!)
100        void setMouseHandler   (InputHandler* handler)
101            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
102
103        // SANDRO HACK
104        void setWiiMoteHandler(InputHandler* handler)
105        { // TODO make this a dynamically chosen number
106          handlers_[2]    = handler; bExpired_ = true;
107        }
108
109        /**
110        @brief
111            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
112        @return
113            Returns false if the specified device was not found
114        */
115        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
116        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
117        void setJoyStickHandler(InputHandler* handler);
118        //! Sets an InputHandler to be used for all devices
119        void setHandler        (InputHandler* handler);
120
121        void setMouseExclusive(tribool value) { exclusiveMouse_ = value; this->bExpired_ = true; }
122        tribool getMouseExclusive() const { return exclusiveMouse_; }
123
124        //! Returns the name of the state (which is unique!)
125        const std::string& getName() const { return name_; }
126        //! Returns the priority of the state (which is unique if != 0)
127        int getPriority()            const { return priority_; }
128
129        //! Tells whether there a handler installed for a specific device
130        bool isInputDeviceEnabled(unsigned int device);
131
132        //! Returns true if the handler situation has changed
133        bool hasExpired()      { return this->bExpired_; }
134        //! Call this if you have applied the changes resulting from changed handlers
135        void resetExpiration() { bExpired_ = false; }
136
137        //! Updates one specific device handler with deviceUpdated
138        void update(float dt, unsigned int device);
139        //! Updates all handlers with allDevicesUpdated
140        void update(float dt);
141
142        //! Generic function that distributes all 9 button events
143        template <typename EventType, class ButtonTypeParam>
144        void buttonEvent(unsigned int device, ButtonTypeParam button);
145
146        //! Event handler
147        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
148        //! Event handler
149        void mouseScrolled(int abs, int rel);
150        //! Event handler
151        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
152
153        // Functors
154        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
155        void entered();
156        //! Called upon deactivation of the state
157        void left();
158        //! Sets a functor to be called upon activation of the state
159        void setEnterFunctor(const FunctorPtr& functor) { this->enterFunctor_ = functor; }
160        //! Sets a functor to be called upon deactivation of the state
161        void setLeaveFunctor(const FunctorPtr& functor) { this->leaveFunctor_ = functor; }
162
163    private:
164        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
165        ~InputState() { }
166
167        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
168
169        //! Sets the priority (only to be used by the InputManager!)
170        void setPriority(int priority) { priority_ = priority; }
171
172        const std::string           name_;                  //!< Name of the state
173        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
174        const bool                  bTransparent_;          //!< See class declaration for explanation
175        tribool                     exclusiveMouse_;        //!< See class declaration for explanation
176        int                         priority_;              //!< Current priority (might change)
177        bool                        bExpired_;              //!< See hasExpired()
178        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
179        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
180        InputHandler*               joyStickHandlerAll_;
181        FunctorPtr                  enterFunctor_;          //!< Functor to be executed on enter
182        FunctorPtr                  leaveFunctor_;          //!< Functor to be executed on leave
183    };
184
185    ORX_FORCEINLINE void InputState::update(float dt)
186    {
187        for (unsigned int i = 0; i < handlers_.size(); ++i)
188            if (handlers_[i] != NULL)
189                INPUT_STATE_PUSH_CALL(i, allDevicesUpdated, dt);
190    }
191
192    ORX_FORCEINLINE void InputState::update(float dt, unsigned int device)
193    {
194        switch (device)
195        {
196        case InputDeviceEnumerator::Keyboard:
197            if (handlers_[keyboardIndex_s] != NULL)
198                INPUT_STATE_PUSH_CALL(keyboardIndex_s, keyboardUpdated, dt);
199            break;
200
201        case InputDeviceEnumerator::Mouse:
202            if (handlers_[mouseIndex_s] != NULL)
203                INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseUpdated, dt);
204            break;
205
206        default: // joy sticks
207            if (handlers_[device] != NULL)
208                INPUT_STATE_PUSH_CALL(device, joyStickUpdated, device - firstJoyStickIndex_s, dt);
209            break;
210        }
211    }
212
213    template <typename EventType, class ButtonTypeParam>
214    ORX_FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
215    {
216        assert(device < handlers_.size());
217        if (handlers_[device] != NULL)
218        {
219            // We have to store the function pointer to tell the compiler about its actual type because of overloading
220            void (InputHandler::*function)(unsigned int, ButtonTypeParam, EventType) = &InputHandler::buttonEvent<ButtonTypeParam>;
221            InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(function, handlers_[device], device, button, EventType())));
222        }
223    }
224
225    ORX_FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
226    {
227        if (handlers_[mouseIndex_s] != NULL)
228            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseMoved, abs, rel, clippingSize);
229    }
230
231    ORX_FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
232    {
233        if (handlers_[mouseIndex_s] != NULL)
234            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseScrolled, abs, rel);
235    }
236
237    ORX_FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
238    {
239        assert(device < handlers_.size());
240        if (handlers_[device] != NULL)
241            INPUT_STATE_PUSH_CALL(device, axisMoved, device - firstJoyStickIndex_s, axis, value);
242    }
243}
244
245#endif /* _InputState_H__ */
Note: See TracBrowser for help on using the repository browser.