]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGPropertyManager.h
Bertrand Coconnier: updated fix for #204 and #222: JSBSim reset
[flightgear.git] / src / FDM / JSBSim / input_output / FGPropertyManager.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGPropertyManager.h
4  Author:       Tony Peden
5                Based on work originally by David Megginson
6  Date:         2/2002
7
8  ------------- Copyright (C) 2002 -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
18  details.
19
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 SENTRY
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30
31 #ifndef FGPROPERTYMANAGER_H
32 #define FGPROPERTYMANAGER_H
33
34 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 INCLUDES
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37
38 // This is needed by MSVC9 when included in FlightGear because of
39 // the new Vec4d class in props.hxx
40 #if defined( HAVE_CONFIG_H )
41 # include <config.h>
42 #endif
43
44 #include <string>
45 #include "simgear/props/props.hxx"
46 #if !PROPS_STANDALONE
47 # include "simgear/math/SGMath.hxx"
48 #endif
49
50 #include "FGJSBBase.h"
51
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 DEFINITIONS
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55
56 #define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.17 2010/07/08 11:36:28 jberndt Exp $"
57
58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 FORWARD DECLARATIONS
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61
62 namespace JSBSim {
63
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 CLASS DOCUMENTATION
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
67
68 /** Class wrapper for property handling.
69     @author David Megginson, Tony Peden
70   */
71
72 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 CLASS DECLARATION
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
75
76 class FGPropertyManager : public SGPropertyNode, public FGJSBBase
77 {
78   private:
79     static bool suppress_warning;
80     static std::vector<std::string> tied_properties;
81   public:
82     /// Constructor
83     FGPropertyManager(void) {suppress_warning = false;}
84     /// Destructor
85     virtual ~FGPropertyManager(void) {}
86
87     /** Property-ify a name
88      *  replaces spaces with '-' and, optionally, makes name all lower case
89      *  @param name string to change
90      *  @param lowercase true to change all upper case chars to lower
91      *  NOTE: this function changes its argument and thus relies
92      *  on pass by value
93      */
94     std::string mkPropertyName(std::string name, bool lowercase);
95
96     /**
97      * Get a property node.
98      *
99      * @param path The path of the node, relative to root.
100      * @param create true to create the node if it doesn't exist.
101      * @return The node, or 0 if none exists and none was created.
102      */
103     FGPropertyManager*
104     GetNode (const std::string &path, bool create = false);
105
106     FGPropertyManager*
107     GetNode (const std::string &relpath, int index, bool create = false);
108
109     /**
110      * Test whether a given node exists.
111      *
112      * @param path The path of the node, relative to root.
113      * @return true if the node exists, false otherwise.
114      */
115     bool HasNode (const std::string &path);
116
117     /**
118      * Get the name of a node
119      */
120     std::string GetName( void );
121
122     /**
123      * Get the name of a node without underscores, etc.
124      */
125     std::string GetPrintableName( void );
126
127     /**
128      * Get the fully qualified name of a node
129      * This function is very slow, so is probably useful for debugging only.
130      */
131     std::string GetFullyQualifiedName(void);
132
133     /**
134      * Get the qualified name of a node relative to given base path,
135      * otherwise the fully qualified name.
136      * This function is very slow, so is probably useful for debugging only.
137      *
138      * @param path The path to strip off, if found.
139      */
140     std::string GetRelativeName( const std::string &path = "/fdm/jsbsim/" );
141
142     /**
143      * Get a bool value for a property.
144      *
145      * This method is convenient but inefficient.  It should be used
146      * infrequently (i.e. for initializing, loading, saving, etc.),
147      * not in the main loop.  If you need to get a value frequently,
148      * it is better to look up the node itself using GetNode and then
149      * use the node's getBoolValue() method, to avoid the lookup overhead.
150      *
151      * @param name The property name.
152      * @param defaultValue The default value to return if the property
153      *        does not exist.
154      * @return The property's value as a bool, or the default value provided.
155      */
156     bool GetBool (const std::string &name, bool defaultValue = false);
157
158
159     /**
160      * Get an int value for a property.
161      *
162      * This method is convenient but inefficient.  It should be used
163      * infrequently (i.e. for initializing, loading, saving, etc.),
164      * not in the main loop.  If you need to get a value frequently,
165      * it is better to look up the node itself using GetNode and then
166      * use the node's getIntValue() method, to avoid the lookup overhead.
167      *
168      * @param name The property name.
169      * @param defaultValue The default value to return if the property
170      *        does not exist.
171      * @return The property's value as an int, or the default value provided.
172      */
173     int GetInt (const std::string &name, int defaultValue = 0);
174
175
176     /**
177      * Get a long value for a property.
178      *
179      * This method is convenient but inefficient.  It should be used
180      * infrequently (i.e. for initializing, loading, saving, etc.),
181      * not in the main loop.  If you need to get a value frequently,
182      * it is better to look up the node itself using GetNode and then
183      * use the node's getLongValue() method, to avoid the lookup overhead.
184      *
185      * @param name The property name.
186      * @param defaultValue The default value to return if the property
187      *        does not exist.
188      * @return The property's value as a long, or the default value provided.
189      */
190     int GetLong (const std::string &name, long defaultValue = 0L);
191
192
193     /**
194      * Get a float value for a property.
195      *
196      * This method is convenient but inefficient.  It should be used
197      * infrequently (i.e. for initializing, loading, saving, etc.),
198      * not in the main loop.  If you need to get a value frequently,
199      * it is better to look up the node itself using GetNode and then
200      * use the node's getFloatValue() method, to avoid the lookup overhead.
201      *
202      * @param name The property name.
203      * @param defaultValue The default value to return if the property
204      *        does not exist.
205      * @return The property's value as a float, or the default value provided.
206      */
207     float GetFloat (const std::string &name, float defaultValue = 0.0);
208
209
210     /**
211      * Get a double value for a property.
212      *
213      * This method is convenient but inefficient.  It should be used
214      * infrequently (i.e. for initializing, loading, saving, etc.),
215      * not in the main loop.  If you need to get a value frequently,
216      * it is better to look up the node itself using GetNode and then
217      * use the node's getDoubleValue() method, to avoid the lookup overhead.
218      *
219      * @param name The property name.
220      * @param defaultValue The default value to return if the property
221      *        does not exist.
222      * @return The property's value as a double, or the default value provided.
223      */
224     double GetDouble (const std::string &name, double defaultValue = 0.0);
225
226
227     /**
228      * Get a string value for a property.
229      *
230      * This method is convenient but inefficient.  It should be used
231      * infrequently (i.e. for initializing, loading, saving, etc.),
232      * not in the main loop.  If you need to get a value frequently,
233      * it is better to look up the node itself using GetNode and then
234      * use the node's getStringValue() method, to avoid the lookup overhead.
235      *
236      * @param name The property name.
237      * @param defaultValue The default value to return if the property
238      *        does not exist.
239      * @return The property's value as a string, or the default value provided.
240      */
241     std::string GetString (const std::string &name, std::string defaultValue = "");
242
243
244     /**
245      * Set a bool value for a property.
246      *
247      * Assign a bool value to a property.  If the property does not
248      * yet exist, it will be created and its type will be set to
249      * BOOL; if it has a type of UNKNOWN, the type will also be set to
250      * BOOL; otherwise, the bool value will be converted to the property's
251      * type.
252      *
253      * @param name The property name.
254      * @param val The new value for the property.
255      * @return true if the assignment succeeded, false otherwise.
256      */
257     bool SetBool (const std::string &name, bool val);
258
259
260     /**
261      * Set an int value for a property.
262      *
263      * Assign an int value to a property.  If the property does not
264      * yet exist, it will be created and its type will be set to
265      * INT; if it has a type of UNKNOWN, the type will also be set to
266      * INT; otherwise, the bool value will be converted to the property's
267      * type.
268      *
269      * @param name The property name.
270      * @param val The new value for the property.
271      * @return true if the assignment succeeded, false otherwise.
272      */
273     bool SetInt (const std::string &name, int val);
274
275
276     /**
277      * Set a long value for a property.
278      *
279      * Assign a long value to a property.  If the property does not
280      * yet exist, it will be created and its type will be set to
281      * LONG; if it has a type of UNKNOWN, the type will also be set to
282      * LONG; otherwise, the bool value will be converted to the property's
283      * type.
284      *
285      * @param name The property name.
286      * @param val The new value for the property.
287      * @return true if the assignment succeeded, false otherwise.
288      */
289     bool SetLong (const std::string &name, long val);
290
291
292     /**
293      * Set a float value for a property.
294      *
295      * Assign a float value to a property.  If the property does not
296      * yet exist, it will be created and its type will be set to
297      * FLOAT; if it has a type of UNKNOWN, the type will also be set to
298      * FLOAT; otherwise, the bool value will be converted to the property's
299      * type.
300      *
301      * @param name The property name.
302      * @param val The new value for the property.
303      * @return true if the assignment succeeded, false otherwise.
304      */
305     bool SetFloat (const std::string &name, float val);
306
307
308     /**
309      * Set a double value for a property.
310      *
311      * Assign a double value to a property.  If the property does not
312      * yet exist, it will be created and its type will be set to
313      * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
314      * DOUBLE; otherwise, the double value will be converted to the property's
315      * type.
316      *
317      * @param name The property name.
318      * @param val The new value for the property.
319      * @return true if the assignment succeeded, false otherwise.
320      */
321     bool SetDouble (const std::string &name, double val);
322
323
324     /**
325      * Set a string value for a property.
326      *
327      * Assign a string value to a property.  If the property does not
328      * yet exist, it will be created and its type will be set to
329      * STRING; if it has a type of UNKNOWN, the type will also be set to
330      * STRING; otherwise, the string value will be converted to the property's
331      * type.
332      *
333      * @param name The property name.
334      * @param val The new value for the property.
335      * @return true if the assignment succeeded, false otherwise.
336      */
337     bool SetString (const std::string &name, const std::string &val);
338
339
340     ////////////////////////////////////////////////////////////////////////
341     // Convenience functions for setting property attributes.
342     ////////////////////////////////////////////////////////////////////////
343
344
345     /**
346      * Set the state of the archive attribute for a property.
347      *
348      * If the archive attribute is true, the property will be written
349      * when a flight is saved; if it is false, the property will be
350      * skipped.
351      *
352      * A warning message will be printed if the property does not exist.
353      *
354      * @param name The property name.
355      * @param state The state of the archive attribute (defaults to true).
356      */
357     void SetArchivable (const std::string &name, bool state = true);
358
359
360     /**
361      * Set the state of the read attribute for a property.
362      *
363      * If the read attribute is true, the property value will be readable;
364      * if it is false, the property value will always be the default value
365      * for its type.
366      *
367      * A warning message will be printed if the property does not exist.
368      *
369      * @param name The property name.
370      * @param state The state of the read attribute (defaults to true).
371      */
372     void SetReadable (const std::string &name, bool state = true);
373
374
375     /**
376      * Set the state of the write attribute for a property.
377      *
378      * If the write attribute is true, the property value may be modified
379      * (depending on how it is tied); if the write attribute is false, the
380      * property value may not be modified.
381      *
382      * A warning message will be printed if the property does not exist.
383      *
384      * @param name The property name.
385      * @param state The state of the write attribute (defaults to true).
386      */
387     void SetWritable (const std::string &name, bool state = true);
388
389
390     ////////////////////////////////////////////////////////////////////////
391     // Convenience functions for tying properties, with logging.
392     ////////////////////////////////////////////////////////////////////////
393
394
395     /**
396      * Untie a property from an external data source.
397      *
398      * Classes should use this function to release control of any
399      * properties they are managing.
400      */
401     void Untie (const std::string &name);
402
403     /**
404      * Unbind all properties bound by this manager to an external data source.
405      *
406      * Classes should use this function to release control of any
407      * properties they have bound using this property manager.
408      */
409     void Unbind (void);
410
411         // Templates cause ambiguity here
412
413     /**
414      * Tie a property to an external bool variable.
415      *
416      * The property's value will automatically mirror the variable's
417      * value, and vice-versa, until the property is untied.
418      *
419      * @param name The property name to tie (full path).
420      * @param pointer A pointer to the variable.
421      * @param useDefault true if any existing property value should be
422      *        copied to the variable; false if the variable should not
423      *        be modified; defaults to true.
424      */
425     void
426     Tie (const std::string &name, bool *pointer, bool useDefault = true);
427
428
429     /**
430      * Tie a property to an external int variable.
431      *
432      * The property's value will automatically mirror the variable's
433      * value, and vice-versa, until the property is untied.
434      *
435      * @param name The property name to tie (full path).
436      * @param pointer A pointer to the variable.
437      * @param useDefault true if any existing property value should be
438      *        copied to the variable; false if the variable should not
439      *        be modified; defaults to true.
440      */
441     void
442     Tie (const std::string &name, int *pointer, bool useDefault = true);
443
444
445     /**
446      * Tie a property to an external long variable.
447      *
448      * The property's value will automatically mirror the variable's
449      * value, and vice-versa, until the property is untied.
450      *
451      * @param name The property name to tie (full path).
452      * @param pointer A pointer to the variable.
453      * @param useDefault true if any existing property value should be
454      *        copied to the variable; false if the variable should not
455      *        be modified; defaults to true.
456      */
457     void
458     Tie (const std::string &name, long *pointer, bool useDefault = true);
459
460
461     /**
462      * Tie a property to an external float variable.
463      *
464      * The property's value will automatically mirror the variable's
465      * value, and vice-versa, until the property is untied.
466      *
467      * @param name The property name to tie (full path).
468      * @param pointer A pointer to the variable.
469      * @param useDefault true if any existing property value should be
470      *        copied to the variable; false if the variable should not
471      *        be modified; defaults to true.
472      */
473     void
474     Tie (const std::string &name, float *pointer, bool useDefault = true);
475
476     /**
477      * Tie a property to an external double variable.
478      *
479      * The property's value will automatically mirror the variable's
480      * value, and vice-versa, until the property is untied.
481      *
482      * @param name The property name to tie (full path).
483      * @param pointer A pointer to the variable.
484      * @param useDefault true if any existing property value should be
485      *        copied to the variable; false if the variable should not
486      *        be modified; defaults to true.
487      */
488     void
489     Tie (const std::string &name, double *pointer, bool useDefault = true);
490
491 //============================================================================
492 //
493 //  All of the following functions *must* be inlined, otherwise linker
494 //  errors will result
495 //
496 //============================================================================
497
498     /* template <class V> void
499     Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0,
500            bool useDefault = true);
501
502     template <class V> void
503     Tie (const std::string &name, int index, V (*getter)(int),
504            void (*setter)(int, V) = 0, bool useDefault = true);
505
506     template <class T, class V> void
507     Tie (const std::string &name, T * obj, V (T::*getter)() const,
508            void (T::*setter)(V) = 0, bool useDefault = true);
509
510     template <class T, class V> void
511     Tie (const std::string &name, T * obj, int index,
512            V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
513            bool useDefault = true); */
514
515      /**
516      * Tie a property to a pair of simple functions.
517      *
518      * Every time the property value is queried, the getter (if any) will
519      * be invoked; every time the property value is modified, the setter
520      * (if any) will be invoked.  The getter can be 0 to make the property
521      * unreadable, and the setter can be 0 to make the property
522      * unmodifiable.
523      *
524      * @param name The property name to tie (full path).
525      * @param getter The getter function, or 0 if the value is unreadable.
526      * @param setter The setter function, or 0 if the value is unmodifiable.
527      * @param useDefault true if the setter should be invoked with any existing
528      *        property value should be; false if the old value should be
529      *        discarded; defaults to true.
530      */
531
532     template <class V> inline void
533     Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
534     {
535       if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
536         std::cout << "Failed to tie property " << name << " to functions" << std::endl;
537       else {
538         tied_properties.push_back(name);
539         if (debug_lvl & 0x20) std::cout << name << std::endl;
540       }
541     }
542
543
544     /**
545      * Tie a property to a pair of indexed functions.
546      *
547      * Every time the property value is queried, the getter (if any) will
548      * be invoked with the index provided; every time the property value
549      * is modified, the setter (if any) will be invoked with the index
550      * provided.  The getter can be 0 to make the property unreadable, and
551      * the setter can be 0 to make the property unmodifiable.
552      *
553      * @param name The property name to tie (full path).
554      * @param index The integer argument to pass to the getter and
555      *        setter functions.
556      * @param getter The getter function, or 0 if the value is unreadable.
557      * @param setter The setter function, or 0 if the value is unmodifiable.
558      * @param useDefault true if the setter should be invoked with any existing
559      *        property value should there be one; false if the old value should be
560      *        discarded; defaults to true.
561      */
562     template <class V> inline void Tie (const std::string &name, int index, V (*getter)(int),
563                                 void (*setter)(int, V) = 0, bool useDefault = true)
564     {
565       if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
566         std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl;
567       else {
568         tied_properties.push_back(name);
569         if (debug_lvl & 0x20) std::cout << name << std::endl;
570       }
571     }
572
573
574     /**
575      * Tie a property to a pair of object methods.
576      *
577      * Every time the property value is queried, the getter (if any) will
578      * be invoked; every time the property value is modified, the setter
579      * (if any) will be invoked.  The getter can be 0 to make the property
580      * unreadable, and the setter can be 0 to make the property
581      * unmodifiable.
582      *
583      * @param name The property name to tie (full path).
584      * @param obj The object whose methods should be invoked.
585      * @param getter The object's getter method, or 0 if the value is
586      *        unreadable.
587      * @param setter The object's setter method, or 0 if the value is
588      *        unmodifiable.
589      * @param useDefault true if the setter should be invoked with any existing
590      *        property value should there be one; false if the old value should be
591      *        discarded; defaults to true.
592      */
593     template <class T, class V> inline void
594     Tie (const std::string &name, T * obj, V (T::*getter)() const,
595            void (T::*setter)(V) = 0, bool useDefault = true)
596     {
597       if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
598         std::cout << "Failed to tie property " << name << " to object methods" << std::endl;
599       else {
600         tied_properties.push_back(name);
601         if (debug_lvl & 0x20) std::cout << name << std::endl;
602       }
603     }
604
605     /**
606      * Tie a property to a pair of indexed object methods.
607      *
608      * Every time the property value is queried, the getter (if any) will
609      * be invoked with the index provided; every time the property value
610      * is modified, the setter (if any) will be invoked with the index
611      * provided.  The getter can be 0 to make the property unreadable, and
612      * the setter can be 0 to make the property unmodifiable.
613      *
614      * @param name The property name to tie (full path).
615      * @param obj The object whose methods should be invoked.
616      * @param index The integer argument to pass to the getter and
617      *        setter methods.
618      * @param getter The getter method, or 0 if the value is unreadable.
619      * @param setter The setter method, or 0 if the value is unmodifiable.
620      * @param useDefault true if the setter should be invoked with any existing
621      *        property value should be; false if the old value should be
622      *        discarded; defaults to true.
623      */
624     template <class T, class V> inline void
625     Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const,
626                          void (T::*setter)(int, V) = 0, bool useDefault = true)
627     {
628       if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
629         std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl;
630       else {
631         tied_properties.push_back(name);
632         if (debug_lvl & 0x20) std::cout << name << std::endl;
633       }
634    }
635 };
636 }
637 #endif // FGPROPERTYMANAGER_H
638