Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/input/InputState.h @ 5839

Last change on this file since 5839 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

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