]> git.mxchange.org Git - flightgear.git/blob - src/Input/FGEventInput.hxx
fix a pointer reference.
[flightgear.git] / src / Input / FGEventInput.hxx
1 // FGEventInput.hxx -- handle event driven input devices
2 //
3 // Written by Torsten Dreyer, started July 2009
4 //
5 // Copyright (C) 2009 Torsten Dreyer, Torsten (at) t3r _dot_ de
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifndef __FGEVENTINPUT_HXX
24 #define __FGEVENTINPUT_HXX
25
26 #include "FGCommonInput.hxx"
27 #include "FGButton.hxx"
28 #include "FGDeviceConfigurationMap.hxx"
29 #include <simgear/structure/subsystem_mgr.hxx>
30
31 /*
32  * A base structure for event data. 
33  * To be extended for O/S specific implementation data
34  */
35 struct FGEventData {
36   FGEventData( double aValue, double aDt, int aModifiers ) : modifiers(aModifiers), value(aValue), dt(aDt) {}
37   int modifiers;
38   double value;
39   double dt;
40 };
41
42 class FGEventSetting : public SGReferenced {
43 public:
44   FGEventSetting( SGPropertyNode_ptr base );
45
46   bool Test();
47
48   /* 
49    * access for the value property
50    */
51   double GetValue();
52
53 protected:
54   double value;
55   SGPropertyNode_ptr valueNode;
56   SGSharedPtr<const SGCondition> condition;
57 };
58
59 typedef SGSharedPtr<FGEventSetting> FGEventSetting_ptr;
60 typedef vector<FGEventSetting_ptr> setting_list_t;
61
62 /*
63  * A wrapper class for a configured event. 
64  * 
65  * <event>
66  *   <desc>Change the view pitch</desc>
67  *   <name>rel-x-rotate</name>
68  *   <binding>
69  *     <command>property-adjust</command>
70  *     <property>sim/current-view/pitch-offset-deg</property>
71  *     <factor type="double">0.01</factor>
72  *     <min type="double">-90.0</min>
73  *     <max type="double">90.0</max>
74  *     <wrap type="bool">false</wrap>
75  *   </binding>
76  *   <mod-xyz>
77  *    <binding>
78  *      ...
79  *    </binding>
80  *   </mod-xyz>
81  * </event>
82  */
83 class FGInputDevice;
84 class FGInputEvent : public SGReferenced,FGCommonInput {
85 public:
86   /*
87    * Constructor for the class. The arg node shall point
88    * to the property corresponding to the <event>  node
89    */
90   FGInputEvent( FGInputDevice * device, SGPropertyNode_ptr node );
91   virtual ~FGInputEvent();
92
93   /*
94    * dispatch the event value through all bindings 
95    */
96   virtual void fire( FGEventData & eventData );
97
98   /*
99    * access for the name property
100    */
101   string GetName() const { return name; }
102
103   /*
104    * access for the description property
105    */
106   string GetDescription() const { return desc; }
107
108   virtual void update( double dt );
109
110   static FGInputEvent * NewObject( FGInputDevice * device, SGPropertyNode_ptr node );
111
112 protected:
113   /* A more or less meaningfull description of the event */
114   string desc;
115
116   /* One of the predefined names of the event */
117   string name;
118
119   /* A list of SGBinding objects */
120   binding_list_t bindings[KEYMOD_MAX];
121
122   /* A list of FGEventSetting objects */
123   setting_list_t settings;
124
125   /* A pointer to the associated device */
126   FGInputDevice * device;
127
128   double lastDt;
129   double intervalSec;
130   double lastSettingValue;
131 };
132
133 class FGButtonEvent : public FGInputEvent {
134 public:
135   FGButtonEvent( FGInputDevice * device, SGPropertyNode_ptr node );
136   virtual void fire( FGEventData & eventData );
137
138 protected:
139   bool repeatable;
140   bool lastState;
141 };
142
143 class FGAxisEvent : public FGInputEvent {
144 public:
145   FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
146 protected:
147   virtual void fire( FGEventData & eventData );
148   double tolerance;
149   double minRange;
150   double maxRange;
151   double center;
152   double deadband;
153   double lowThreshold;
154   double highThreshold;
155   double lastValue;
156 };
157
158 typedef class SGSharedPtr<FGInputEvent> FGInputEvent_ptr;
159
160 /*
161  * A abstract class implementing basic functionality of input devices for
162  * all operating systems. This is the base class for the O/S-specific
163  * implementation of input device handlers
164  */
165 class FGInputDevice : public SGReferenced {
166 public:
167   FGInputDevice() : debugEvents(false), grab(false) {}
168   FGInputDevice( string aName ) : name(aName) {}
169     
170   virtual ~FGInputDevice();
171
172   virtual void Open() = 0;
173   virtual void Close() = 0;
174
175   virtual void Send( const char * eventName, double value ) = 0;
176
177   inline void Send( const string & eventName, double value ) {
178     Send( eventName.c_str(), value );
179   }
180
181   virtual const char * TranslateEventName( FGEventData & eventData ) = 0;
182
183
184   void SetName( string name );
185   string & GetName() { return name; }
186
187   void HandleEvent( FGEventData & eventData );
188
189   void AddHandledEvent( FGInputEvent_ptr handledEvent ) {
190     if( handledEvents.count( handledEvent->GetName() ) == 0 )
191       handledEvents[handledEvent->GetName()] = handledEvent;
192   }
193
194   virtual void Configure( SGPropertyNode_ptr deviceNode );
195
196   virtual void update( double dt );
197
198   bool GetDebugEvents () const { return debugEvents; }
199
200   bool GetGrab() const { return grab; }
201
202   const string & GetNasalModule() const { return nasalModule; }
203
204 private:
205   // A map of events, this device handles
206   map<string,FGInputEvent_ptr> handledEvents;
207
208   // the device has a name to be recognized
209   string name;
210
211   // print out events comming in from the device
212   // if true
213   bool   debugEvents;
214
215   // grab the device exclusively, if O/S supports this
216   // so events are not sent to other applications
217   bool   grab;
218
219   SGPropertyNode_ptr deviceNode;
220   string nasalModule;
221 };
222
223 typedef SGSharedPtr<FGInputDevice> FGInputDevice_ptr;
224
225
226 /*
227  * The Subsystem for the event input device 
228  */
229 class FGEventInput : public SGSubsystem,FGCommonInput {
230 public:
231   FGEventInput();
232   virtual ~FGEventInput();
233   virtual void init();
234   virtual void postinit();
235   virtual void update( double dt );
236
237   const static unsigned MAX_DEVICES = 1000;
238   const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
239 protected:
240   static const char * PROPERTY_ROOT;
241
242   unsigned AddDevice( FGInputDevice * inputDevice );
243   void RemoveDevice( unsigned index );
244
245   map<int,FGInputDevice*> input_devices;
246   FGDeviceConfigurationMap configMap;
247
248   SGPropertyNode_ptr nasalClose;
249 };
250
251 #endif