]> git.mxchange.org Git - flightgear.git/blob - src/Input/FGEventInput.hxx
Stop the property tree from keeping a shadow of the deleted input properties, as...
[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
28 #include <vector>
29
30 #include "FGButton.hxx"
31 #include "FGDeviceConfigurationMap.hxx"
32 #include <simgear/structure/subsystem_mgr.hxx>
33
34 /*
35  * A base structure for event data. 
36  * To be extended for O/S specific implementation data
37  */
38 struct FGEventData {
39   FGEventData( double aValue, double aDt, int aModifiers ) : modifiers(aModifiers), value(aValue), dt(aDt) {}
40   int modifiers;
41   double value;
42   double dt;
43 };
44
45 class FGEventSetting : public SGReferenced {
46 public:
47   FGEventSetting( SGPropertyNode_ptr base );
48
49   bool Test();
50
51   /* 
52    * access for the value property
53    */
54   double GetValue();
55
56 protected:
57   double value;
58   SGPropertyNode_ptr valueNode;
59   SGSharedPtr<const SGCondition> condition;
60 };
61
62 typedef SGSharedPtr<FGEventSetting> FGEventSetting_ptr;
63 typedef std::vector<FGEventSetting_ptr> setting_list_t;
64
65 /*
66  * A wrapper class for a configured event. 
67  * 
68  * <event>
69  *   <desc>Change the view pitch</desc>
70  *   <name>rel-x-rotate</name>
71  *   <binding>
72  *     <command>property-adjust</command>
73  *     <property>sim/current-view/pitch-offset-deg</property>
74  *     <factor type="double">0.01</factor>
75  *     <min type="double">-90.0</min>
76  *     <max type="double">90.0</max>
77  *     <wrap type="bool">false</wrap>
78  *   </binding>
79  *   <mod-xyz>
80  *    <binding>
81  *      ...
82  *    </binding>
83  *   </mod-xyz>
84  * </event>
85  */
86 class FGInputDevice;
87 class FGInputEvent : public SGReferenced,FGCommonInput {
88 public:
89
90   /*
91    * Constructor for the class. The arg node shall point
92    * to the property corresponding to the <event>  node
93    */
94   FGInputEvent( FGInputDevice * device, SGPropertyNode_ptr node );
95   virtual ~FGInputEvent();
96
97   /*
98    * dispatch the event value through all bindings 
99    */
100   virtual void fire( FGEventData & eventData );
101
102   /*
103    * access for the name property
104    */
105   std::string GetName() const { return name; }
106
107   /*
108    * access for the description property
109    */
110   std::string GetDescription() const { return desc; }
111
112   virtual void update( double dt );
113
114   static FGInputEvent * NewObject( FGInputDevice * device, SGPropertyNode_ptr node );
115
116 protected:
117   virtual void fire( SGBinding * binding, FGEventData & eventData );
118   /* A more or less meaningfull description of the event */
119   std::string desc;
120
121   /* One of the predefined names of the event */
122   std::string name;
123
124   /* A list of SGBinding objects */
125   binding_list_t bindings[KEYMOD_MAX];
126
127   /* A list of FGEventSetting objects */
128   setting_list_t settings;
129
130   /* A pointer to the associated device */
131   FGInputDevice * device;
132
133   double lastDt;
134   double intervalSec;
135   double lastSettingValue;
136 };
137
138 class FGButtonEvent : public FGInputEvent {
139 public:
140   FGButtonEvent( FGInputDevice * device, SGPropertyNode_ptr node );
141   virtual void fire( FGEventData & eventData );
142
143 protected:
144   bool repeatable;
145   bool lastState;
146 };
147
148 class FGAxisEvent : public FGInputEvent {
149 public:
150   FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
151   void SetMaxRange( double value ) { maxRange = value; }
152   void SetMinRange( double value ) { minRange = value; }
153   void SetRange( double min, double max ) { minRange = min; maxRange = max; }
154 protected:
155   virtual void fire( FGEventData & eventData );
156   double tolerance;
157   double minRange;
158   double maxRange;
159   double center;
160   double deadband;
161   double lowThreshold;
162   double highThreshold;
163   double lastValue;
164 };
165
166 class FGRelAxisEvent : public FGAxisEvent {
167 public:
168   FGRelAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
169 protected:
170   virtual void fire( SGBinding * binding, FGEventData & eventData );
171 };
172
173 class FGAbsAxisEvent : public FGAxisEvent {
174 public:
175   FGAbsAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node ) : FGAxisEvent( device, node ) {}
176 protected:
177   virtual void fire( SGBinding * binding, FGEventData & eventData );
178 };
179
180 typedef class SGSharedPtr<FGInputEvent> FGInputEvent_ptr;
181
182 /*
183  * A abstract class implementing basic functionality of input devices for
184  * all operating systems. This is the base class for the O/S-specific
185  * implementation of input device handlers
186  */
187 class FGInputDevice : public SGReferenced {
188 public:
189   FGInputDevice() : debugEvents(false), grab(false) {}
190   FGInputDevice( std::string aName ) : name(aName), debugEvents(false), grab(false)  {}
191     
192   virtual ~FGInputDevice();
193
194   virtual void Open() = 0;
195   virtual void Close() = 0;
196
197   virtual void Send( const char * eventName, double value ) = 0;
198
199   inline void Send( const std::string & eventName, double value ) {
200     Send( eventName.c_str(), value );
201   }
202
203   virtual const char * TranslateEventName( FGEventData & eventData ) = 0;
204
205
206   void SetName( std::string name );
207   std::string & GetName() { return name; }
208
209   void HandleEvent( FGEventData & eventData );
210
211   void AddHandledEvent( FGInputEvent_ptr handledEvent ) {
212     if( handledEvents.count( handledEvent->GetName() ) == 0 )
213       handledEvents[handledEvent->GetName()] = handledEvent;
214   }
215
216   virtual void Configure( SGPropertyNode_ptr deviceNode );
217
218   virtual void update( double dt );
219
220   bool GetDebugEvents () const { return debugEvents; }
221
222   bool GetGrab() const { return grab; }
223
224   const std::string & GetNasalModule() const { return nasalModule; }
225
226 private:
227   // A map of events, this device handles
228   std::map<std::string,FGInputEvent_ptr> handledEvents;
229
230   // the device has a name to be recognized
231   std::string name;
232
233   // print out events comming in from the device
234   // if true
235   bool   debugEvents;
236
237   // grab the device exclusively, if O/S supports this
238   // so events are not sent to other applications
239   bool   grab;
240
241   SGPropertyNode_ptr deviceNode;
242   std::string nasalModule;
243 };
244
245 typedef SGSharedPtr<FGInputDevice> FGInputDevice_ptr;
246
247
248 /*
249  * The Subsystem for the event input device 
250  */
251 class FGEventInput : public SGSubsystem,FGCommonInput {
252 public:
253   FGEventInput();
254   virtual ~FGEventInput();
255   virtual void init();
256   virtual void postinit();
257   virtual void update( double dt );
258
259   const static unsigned MAX_DEVICES = 1000;
260   const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
261 protected:
262   static const char * PROPERTY_ROOT;
263
264   unsigned AddDevice( FGInputDevice * inputDevice );
265   void RemoveDevice( unsigned index );
266
267   std::map<int,FGInputDevice*> input_devices;
268   FGDeviceConfigurationMap configMap;
269
270   SGPropertyNode_ptr nasalClose;
271 };
272
273 #endif