Orxonox  0.0.5 Codename: Arcturus
InputDevice.h
Go to the documentation of this file.
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 
35 #ifndef _InputDevice_H__
36 #define _InputDevice_H__
37 
38 #include "InputPrereqs.h"
39 
40 #include <vector>
41 #include <ois/OISInputManager.h>
42 #include <ois/OISException.h>
43 
44 #include "util/Clock.h"
45 #include "util/Output.h"
46 #include "util/Exception.h"
47 #include "InputState.h"
48 
49 namespace orxonox
50 {
58  {
59  public:
61  InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { }
62  virtual ~InputDevice() = default;
64  virtual std::string getClassName() const = 0;
66  virtual void update(const Clock& time) = 0;
68  virtual void clearBuffers() = 0;
69 
72  {
73  bCalibrating_ = true;
74  this->calibrationStarted();
75  }
76 
79  {
80  this->calibrationStopped();
81  bCalibrating_ = false;
82  }
83 
85  std::vector<InputState*>& getStateListRef() { return this->inputStates_; }
87  unsigned int getDeviceID() const { return this->deviceID_; }
89  bool isCalibrating() const { return bCalibrating_; }
90 
91  protected:
93  virtual void calibrationStarted() { }
95  virtual void calibrationStopped() { }
96 
98  std::vector<InputState*> inputStates_;
99 
100  private:
101  // non-copyable:
102  InputDevice(const InputDevice&) = delete;
103  InputDevice& operator=(const InputDevice&) = delete;
104 
106  const unsigned int deviceID_;
107  };
108 
120  template <class Traits>
121  class InputDeviceTemplated : public InputDevice
122  {
123  typedef typename Traits::DeviceClass DeviceClass;
124  typedef typename Traits::OISDeviceClass OISDeviceClass;
125  typedef typename Traits::ButtonType ButtonType;
126  typedef typename Traits::ButtonTypeParam ButtonTypeParam;
127  static const OIS::Type OISDeviceValue = Traits::OISDeviceValue;
128 
129  public:
131  InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager)
132  : InputDevice(id)
133  , oisInputManager_(oisInputManager)
134  {
135  oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true));
136  // Note: after the static_cast here, the cast this pointer becomes
137  // invalid right until the subclass has been constructed!
138  oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
139  orxout(verbose, context::input) << "Instantiated a " << this->getClassName() << endl;
140  }
141 
144  {
145  try
146  {
147  oisInputManager_->destroyInputObject(oisDevice_);
148  }
149  catch (const OIS::Exception& ex)
150  {
151  orxout(internal_error, context::input) << this->getClassName() << " destruction failed: " << ex.eText << '\n'
152  << "Potential resource leak!" << endl;
153  }
154  }
155 
157  virtual void update(const Clock& time) override
158  {
159  oisDevice_->capture();
160 
161  // Call all the states with the held button event
162  for (ButtonType& button : pressedButtons_)
163  for (InputState* state : inputStates_)
164  state->template buttonEvent<ButtonEvent::THold, typename Traits::ButtonTypeParam>(
165  this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
166 
167  // Call states with device update events
168  for (InputState* state : inputStates_)
169  state->update(time.getDeltaTime(), this->getDeviceID());
170 
171  static_cast<DeviceClass*>(this)->updateImpl(time);
172  }
173 
175  virtual void clearBuffers() override
176  {
177  pressedButtons_.clear();
178  static_cast<DeviceClass*>(this)->clearBuffersImpl();
179  }
180 
181  // Returns a pointer to the OIS device
182  OISDeviceClass* getOISDevice() { return this->oisDevice_; }
183  // Returns the name of the derived class as string
184  virtual std::string getClassName() const override { return DeviceClass::getClassNameImpl(); }
185 
186  protected:
188  ORX_FORCEINLINE void buttonPressed(ButtonTypeParam button)
189  {
190  // check whether the button already is in the list (can happen when focus was lost)
191  unsigned int iButton = 0;
192  while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
193  iButton++;
194  if (iButton == pressedButtons_.size())
195  pressedButtons_.push_back(button);
196  else
197  return; // Button already pressed
198 
199  // Call states
200  for (InputState* state : inputStates_)
201  state->template buttonEvent<ButtonEvent::TPress, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
202  }
203 
205  ORX_FORCEINLINE void buttonReleased(ButtonTypeParam button)
206  {
207  // remove the button from the pressedButtons_ list
208  bool found = false;
209  for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
210  {
211  if (pressedButtons_[iButton] == button)
212  {
213  pressedButtons_.erase(pressedButtons_.begin() + iButton);
214  found = true;
215  break;
216  }
217  }
218  if (!found)
219  return; // We ignore release strokes when the press was not captured
220 
221  // Call states
222  for (InputState* state : inputStates_)
223  state->template buttonEvent<ButtonEvent::TRelease, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
224  }
225 
227  OISDeviceClass* oisDevice_;
228 
229  private:
231  void clearBuffersImpl() { }
233  void updateImpl(const Clock& time) { }
235  ButtonType& getButtonEventArg(ButtonType& button) { return button; }
236 
237  std::vector<ButtonType> pressedButtons_;
239  };
240 }
241 
242 #endif /* _InputDevice_H__ */
Heavily templated base class for all three input devices.
Definition: CorePrereqs.h:281
virtual void calibrationStopped()
To be ovrridden by the subclass.
Definition: InputDevice.h:95
virtual void update(const Clock &time)=0
Updates the device which should in turn distribute events.
virtual std::string getClassName() const override
Returns the device class (derived) name as string.
Definition: InputDevice.h:184
bool bCalibrating_
Whether the device is in calibration mode.
Definition: InputDevice.h:105
std::vector< ButtonType > pressedButtons_
List of all buttons that are currently pressed down.
Definition: InputDevice.h:237
::std::string string
Definition: gtest-port.h:756
virtual void calibrationStarted()
To be ovrridden by the subclass.
Definition: InputDevice.h:93
Output level, usually not visible, used for unimportant debug information.
Definition: OutputDefinitions.h:99
InputDevice(unsigned int id)
Only resets the members.
Definition: InputDevice.h:61
ORX_FORCEINLINE void buttonReleased(ButtonTypeParam button)
Common code for all button released events (updates pressed buttons list and calls the input states) ...
Definition: InputDevice.h:205
const unsigned int deviceID_
ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
Definition: InputDevice.h:106
ButtonType & getButtonEventArg(ButtonType &button)
Definition: InputDevice.h:235
OISDeviceClass * oisDevice_
Managed pointer to the OIS device.
Definition: InputDevice.h:227
virtual ~InputDevice()=default
Output level, used for error messages which are important for developers.
Definition: OutputDefinitions.h:95
void stopCalibration()
Stop calibrating and evaluate the data (only useful for joy sticks)
Definition: InputDevice.h:78
void updateImpl(const Clock &time)
Fallback dummy function for static polymorphism.
Definition: InputDevice.h:233
Definition: OISException.h:51
void startCalibration()
Start calibrating (only useful for joy sticks)
Definition: InputDevice.h:71
Declaration of facilities to handle exceptions.
bool isCalibrating() const
Tells whether the device is in calibration mode.
Definition: InputDevice.h:89
virtual std::string getClassName() const =0
Returns the device class (derived) name as string.
virtual void update(const Clock &time) override
Captures OIS events (which then get distributed to the derived class) and creates the button held eve...
Definition: InputDevice.h:157
OIS::InputManager * oisInputManager_
Pointer to the OIS InputManager that can create and destroy devices.
Definition: InputDevice.h:238
Declarations of all key/button/axis code enumeration and string literals and an input device enumerat...
Traits::ButtonTypeParam ButtonTypeParam
Definition: InputDevice.h:126
OutputStream & orxout(OutputLevel level=level::debug_output, const OutputContextContainer &context=context::undefined())
This helper function returns a reference to a commonly used instance of OutputStream.
Definition: Output.h:81
Die Wagnis Klasse hat die folgenden Aufgaben:
Definition: ApplicationPaths.cc:66
InputDeviceTemplated(unsigned int id, OIS::InputManager *oisInputManager)
Creates the OIS device.
Definition: InputDevice.h:131
Traits::ButtonType ButtonType
Definition: InputDevice.h:125
Defines the helper function orxout() and includes all necessary headers to use the output system...
unsigned int getDeviceID() const
Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard) ...
Definition: InputDevice.h:87
InputDevice & operator=(const InputDevice &)=delete
std::vector< InputState * > & getStateListRef()
Returns a reference to the internal input state vector. Use with care!
Definition: InputDevice.h:85
Type
Each Input class has a General Type variable, a form of RTTI.
Definition: OISPrereqs.h:138
InputStates allow you to customise the input event targets at runtime.
Definition: InputState.h:83
Base Manager class.
Definition: OISInputManager.h:38
Simple real time clock based on Ogre::Timer.
Definition: Clock.h:57
void clearBuffersImpl()
< Fallback dummy function for static polymorphism
Definition: InputDevice.h:231
virtual void clearBuffers()=0
Clear all button related buffers.
virtual ~InputDeviceTemplated()
Destroys the OIS device.
Definition: InputDevice.h:143
Traits::OISDeviceClass OISDeviceClass
Definition: InputDevice.h:124
#define ORX_FORCEINLINE
Definition: OrxonoxConfig.h:95
OISDeviceClass * getOISDevice()
Definition: InputDevice.h:182
ORX_FORCEINLINE void buttonPressed(ButtonTypeParam button)
Common code for all button pressed events (updates pressed buttons list and calls the input states) ...
Definition: InputDevice.h:188
std::vector< InputState * > inputStates_
List of all input states that receive events from this device.
Definition: InputDevice.h:98
Traits::DeviceClass DeviceClass
Definition: InputDevice.h:123
virtual void clearBuffers() override
Clears the list of pressed buttons and calls the derived class&#39;s method.
Definition: InputDevice.h:175
float getDeltaTime() const
Returns the timespan in seconds between the last two calls to capture()
Definition: Clock.h:89
const char * eText
A message passed along when the exception was raised.
Definition: OISException.h:71
Abstract base class for all input devices (mouse, keyboard and joy sticks).
Definition: InputDevice.h:57