Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6378 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

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