Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6579 was 6537, checked in by rgrieder, 15 years ago

Linked every GUI sheet to exactly one InputState.
Also added util/TriBool that has states {true, false, Dontcare}.

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