Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/core/input/InputDevice.h @ 3281

Last change on this file since 3281 was 3279, checked in by rgrieder, 15 years ago

Heavy clean up in the InputManager; not many real code changes though.
And temporary hack-fixed a problem in the Keybinder with std::vector.reserve(1000) ;)

  • Property svn:eol-style set to native
File size: 6.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/**
30@file
31@brief
32*/
33
34#ifndef _InputDevice_H__
35#define _InputDevice_H__
36
37#include "InputPrereqs.h"
38
39#include <vector>
40#include <boost/foreach.hpp>
41#include <ois/OISInputManager.h>
42
43#include "util/Debug.h"
44#include "core/Clock.h"
45// TODO: Try to remove this
46#include "InputManager.h"
47#include "InputState.h"
48
49namespace orxonox
50{
51    /**
52    @brief
53    */
54    class InputDevice
55    {
56        friend class InputManager;
57
58    public:
59        InputDevice(unsigned int id) : bCalibrating_(false), id_(id) { }
60        virtual ~InputDevice() { }
61        virtual std::string getClassName() = 0;
62        virtual void update(const Clock& time) = 0;
63        virtual void clearBuffers() = 0;
64
65        void startCalibration()
66        {
67            bCalibrating_ = true;
68            this->calibrationStarted();
69        }
70
71        void stopCalibration()
72        {
73            this->calibrationStopped();
74            bCalibrating_ = false;
75        }
76
77        unsigned int getDeviceID() { return this->id_; }
78
79    protected:
80        virtual void calibrationStarted() { }
81        virtual void calibrationStopped() { }
82        bool isCalibrating() { return bCalibrating_; }
83
84        // InputState handling
85        std::vector<InputState*> inputStates_;
86
87    private:
88        InputDevice(const InputDevice& rhs);
89
90        std::vector<InputState*>& getStateListRef()
91        {
92            return this->inputStates_;
93        }
94
95        bool bCalibrating_;
96        const unsigned int id_;
97    };
98
99    /**
100    @brief
101    */
102    template <class Traits>
103    class InputDeviceTemplated : public InputDevice
104    {
105        typedef typename Traits::DeviceClass DeviceClass;
106        typedef typename Traits::OISDeviceClass OISDeviceClass;
107        typedef typename Traits::ButtonType ButtonType;
108        typedef typename Traits::ButtonTypeParam ButtonTypeParam;
109        static const OIS::Type OISDeviceValue = Traits::OISDeviceValue;
110
111    public:
112        InputDeviceTemplated(unsigned int id)
113            : InputDevice(id)
114        {
115            OIS::InputManager* system = InputManager::getInstance().getOISInputManager();
116            oisDevice_ = static_cast<OISDeviceClass*>(system->createInputObject(OISDeviceValue, true));
117            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
118            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
119        }
120
121        virtual ~InputDeviceTemplated()
122        {
123            try
124            {
125                InputManager::getInstance().getOISInputManager()->destroyInputObject(oisDevice_);
126            }
127            catch (...)
128            {
129                COUT(1) << this->getClassName() << " destruction failed! Potential resource leak!" << std::endl;
130            }
131        }
132
133        OISDeviceClass* getOISDevice()
134        {
135            return this->oisDevice_;
136        }
137
138        std::string getClassName()
139        {
140            return InputDeviceNames::values[OISDeviceValue];
141        }
142
143        void update(const Clock& time)
144        {
145            oisDevice_->capture();
146
147            if (!this->isCalibrating())
148            {
149                // Call all the states with the held button event
150                for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
151                    for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
152                        inputStates_[iS]->buttonEvent<ButtonEvent::THold, Traits>(
153                            this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
154
155                // Call states with device update events
156                for (unsigned int i = 0; i < inputStates_.size(); ++i)
157                    inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
158            }
159
160            static_cast<DeviceClass*>(this)->updateImpl(time);
161        }
162
163        void clearBuffers()
164        {
165            pressedButtons_.clear();
166            static_cast<DeviceClass*>(this)->clearBuffersImpl();
167        }
168
169    protected:
170        void buttonPressed(ButtonTypeParam button)
171        {
172            // check whether the button already is in the list (can happen when focus was lost)
173            unsigned int iButton = 0;
174            while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
175                iButton++;
176            if (iButton == pressedButtons_.size())
177                pressedButtons_.push_back(button);
178            else
179                return; // Button already pressed
180
181            // Call states
182            for (unsigned int i = 0; i < inputStates_.size(); ++i)
183                inputStates_[i]->buttonEvent<ButtonEvent::TPress, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
184        }
185
186        void buttonReleased(ButtonTypeParam button)
187        {
188            // remove the button from the pressedButtons_ list
189            for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
190            {
191                if (pressedButtons_[iButton] == button)
192                {
193                    pressedButtons_.erase(pressedButtons_.begin() + iButton);
194                    break;
195                }
196            }
197
198            // Call states
199            for (unsigned int i = 0; i < inputStates_.size(); ++i)
200                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, Traits>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
201        }
202
203        OISDeviceClass* oisDevice_;
204
205    private:
206        void clearBuffersImpl() { } //!< Fallback dummy function for static polymorphism
207        void updateImpl(const Clock& time) { } //!< Fallback dummy function for static polymorphism
208        //!< Fallback dummy function for static polymorphism
209        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
210
211        std::vector<ButtonType> pressedButtons_;
212    };
213}
214
215#endif /* _InputDevice_H__ */
Note: See TracBrowser for help on using the repository browser.