Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamestate/src/libraries/core/input/InputState.h @ 6656

Last change on this file since 6656 was 6656, checked in by rgrieder, 14 years ago

Moved InputStatePriority from InputState.h to InputPrereqs.h

  • Property svn:eol-style set to native
File size: 10.1 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
38#include "util/TriBool.h"
39#include "InputHandler.h"
40#include "JoyStickQuantityListener.h"
41
42namespace orxonox
43{
44    /**
45    @brief
46        InputStates allow you to customise the input event targets at runtime.
47
48        The general idea is a stack: Every activated InputState will be pushed on
49        that stack and only the top one gets the input events. This is done for
50        every device (keyboard, mouse, all joy sticks) separately to allow
51        for instance keyboard input capturing for the console while you can still
52        steer a ship with the mouse.
53        There are two exceptions to this behaviour though:
54        - If an InputState is created with the 'Transparent' parameter on, the
55          state will not prevent input from getting to the state below it on the stack.
56          This can be useful for instance if you need to deploy input to multiple
57          handlers: Simply create two InputStates and make the high priority one transparent.
58        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
59          the state will always receive input as long as it is activated.
60        - Note: If you mark an InputState with both parameters on, then it will
61          not influence only other InputState at all.
62
63    @par Priorities
64        Every InputState has a priority when on the stack, but mostly this
65        priority is dynamic (InputStatePriority::Dynamic) which means that a state
66        pushed onto the stack will simply have a higher priority than the top one.
67        This behaviour really only applies to normal states that don't have
68        a high priority (InputStatePriority::HighPriority). These 'special' ones
69        are used for features like the KeyDetector or the console. Use with care!
70
71    @par Exclusive/Non-Exclusive mouse Mode
72        You can select a specific mouse mode that tells whether the application
73        should have exclusive access to it or not.
74        When in non-exclusive mode, you can move the mouse out of the window
75        like with any other normal window (only for windowed mode!).
76        The setting is dictated by the topmost InputState that gets mouse events.
77    */
78    class _CoreExport InputState : public JoyStickQuantityListener
79    {
80        friend class InputManager;
81
82        //! Marks the index in the handler vector for the keyboard handler
83        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
84        //! Marks the index in the handler vector for the mouse handler
85        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
86        //! Marks the index in the handler vector for the first joy stick handler
87        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
88
89    public:
90        //! Sets the keyboard event handler (overwrites if there already was one!)
91        void setKeyHandler     (InputHandler* handler)
92            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
93        //! Sets the mouse event handler (overwrites if there already was one!)
94        void setMouseHandler   (InputHandler* handler)
95            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
96        /**
97        @brief
98            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
99        @return
100            Returns false if the specified device was not found
101        */
102        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
103        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
104        void setJoyStickHandler(InputHandler* handler);
105        //! Sets an InputHandler to be used for all devices
106        void setHandler        (InputHandler* handler);
107
108        void setMouseExclusive(TriBool::Value value) { exclusiveMouse_ = value; this->bExpired_ = true; }
109        TriBool::Value getMouseExclusive() const { return exclusiveMouse_; }
110
111        //! Returns the name of the state (which is unique!)
112        const std::string& getName() const { return name_; }
113        //! Returns the priority of the state (which is unique if != 0)
114        int getPriority()            const { return priority_; }
115
116        //! Tells whether there a handler installed for a specific device
117        bool isInputDeviceEnabled(unsigned int device);
118
119        //! Returns true if the handler situation has changed
120        bool hasExpired()      { return this->bExpired_; }
121        //! Call this if you have applied the changes resulting from changed handlers
122        void resetExpiration() { bExpired_ = false; }
123
124        //! Updates one specific device handler with #device#Updated
125        void update(float dt, unsigned int device);
126        //! Updates all handlers with allDevicesUpdated
127        void update(float dt);
128
129        //! Generic function that distributes all 9 button events
130        template <typename EventType, class Traits>
131        void buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button);
132
133        //! Event handler
134        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
135        //! Event handler
136        void mouseScrolled(int abs, int rel);
137        //! Event handler
138        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
139
140        // Functors
141        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
142        void entered();
143        //! Called upon deactivation of the state
144        void left();
145        //! Sets a functor to be called upon activation of the state
146        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
147        //! Sets a functor to be called upon deactivation of the state
148        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
149
150    private:
151        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
152        ~InputState() { }
153
154        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
155
156        //! Sets the priority (only to be used by the InputManager!)
157        void setPriority(int priority) { priority_ = priority; }
158
159        const std::string           name_;                  //!< Name of the state
160        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
161        const bool                  bTransparent_;          //!< See class declaration for explanation
162        TriBool::Value              exclusiveMouse_;        //!< See class declaration for explanation
163        int                         priority_;              //!< Current priority (might change)
164        bool                        bExpired_;              //!< See hasExpired()
165        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
166        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
167        InputHandler*               joyStickHandlerAll_;
168        Functor*                    enterFunctor_;          //!< Functor to be executed on enter
169        Functor*                    leaveFunctor_;          //!< Functor to be executed on leave
170    };
171
172    FORCEINLINE void InputState::update(float dt)
173    {
174        for (unsigned int i = 0; i < handlers_.size(); ++i)
175            if (handlers_[i] != NULL)
176                handlers_[i]->allDevicesUpdated(dt);
177    }
178
179    FORCEINLINE void InputState::update(float dt, unsigned int device)
180    {
181        switch (device)
182        {
183        case InputDeviceEnumerator::Keyboard:
184            if (handlers_[keyboardIndex_s] != NULL)
185                handlers_[keyboardIndex_s]->keyboardUpdated(dt);
186            break;
187
188        case InputDeviceEnumerator::Mouse:
189            if (handlers_[mouseIndex_s] != NULL)
190                handlers_[mouseIndex_s]->mouseUpdated(dt);
191            break;
192
193        default: // joy sticks
194            if (handlers_[device] != NULL)
195                handlers_[device]->joyStickUpdated(device - firstJoyStickIndex_s, dt);
196            break;
197        }
198    }
199
200    template <typename EventType, class Traits>
201    FORCEINLINE void InputState::buttonEvent(unsigned int device, const typename Traits::ButtonTypeParam button)
202    {
203        assert(device < handlers_.size());
204        if (handlers_[device] != NULL)
205            handlers_[device]->buttonEvent(device, button, EventType());
206    }
207
208    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
209    {
210        if (handlers_[mouseIndex_s] != NULL)
211            handlers_[mouseIndex_s]->mouseMoved(abs, rel, clippingSize);
212    }
213
214    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
215    {
216        if (handlers_[mouseIndex_s] != NULL)
217            handlers_[mouseIndex_s]->mouseScrolled(abs, rel);
218    }
219
220    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
221    {
222        assert(device < handlers_.size());
223        if (handlers_[device] != NULL)
224            handlers_[device]->axisMoved(device - firstJoyStickIndex_s, axis, value);
225    }
226}
227
228#endif /* _InputState_H__ */
Note: See TracBrowser for help on using the repository browser.