]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_props.hxx
Added fgAddChangeListener convenience functions.
[flightgear.git] / src / Main / fg_props.hxx
1 // fg_props.hxx - Declarations and inline methods for property handling.
2 // Written by David Megginson, started 2000.
3 //
4 // This file is in the Public Domain, and comes with no warranty.
5
6 #ifndef __FG_PROPS_HXX
7 #define __FG_PROPS_HXX 1
8
9 #include <simgear/debug/logstream.hxx>
10 #include <simgear/misc/props.hxx>
11 #include <simgear/misc/props_io.hxx>
12
13 #include "globals.hxx"
14
15 \f
16 ////////////////////////////////////////////////////////////////////////
17 // Property management.
18 ////////////////////////////////////////////////////////////////////////
19
20
21 /**
22  * Initialize the default FlightGear properties.
23  *
24  * These are mostly properties that haven't been claimed by a
25  * specific module yet.  This function should be invoked once,
26  * while the program is starting (and after the global property
27  * tree has been created).
28  */
29 extern void fgInitProps ();     // fixme: how are they untied?
30
31
32 /**
33  * Update the default FlightGear properties.
34  *
35  * This function should be invoked once in each loop to update all
36  * of the default properties.
37  */
38 extern void fgUpdateProps ();
39
40
41 /**
42  * Save a flight to disk.
43  *
44  * This function saves all of the archivable properties to a stream
45  * so that the current flight can be restored later.
46  *
47  * @param output The output stream to write the XML save file to.
48  * @param write_all If true, write all properties rather than
49  *        just the ones flagged as archivable.
50  * @return true if the flight was saved successfully.
51  */
52 extern bool fgSaveFlight (ostream &output, bool write_all = false);
53
54
55 /**
56  * Load a flight from disk.
57  *
58  * This function loads an XML save file from a stream to restore
59  * a flight.
60  *
61  * @param input The input stream to read the XML from.
62  * @return true if the flight was restored successfully.
63  */
64 extern bool fgLoadFlight (istream &input);
65
66
67 \f
68 ////////////////////////////////////////////////////////////////////////
69 // Convenience functions for getting property values.
70 ////////////////////////////////////////////////////////////////////////
71
72 /**
73  * Get a property node.
74  *
75  * @param path The path of the node, relative to root.
76  * @param create true to create the node if it doesn't exist.
77  * @return The node, or 0 if none exists and none was created.
78  */
79 extern SGPropertyNode * fgGetNode (const char * path, bool create = false);
80
81
82 /**
83  * Get a property node with separate index.
84  *
85  * This method separates the index from the path string, to make it
86  * easier to iterate through multiple components without using sprintf
87  * to add indices.  For example, fgGetNode("foo[1]/bar", 3) will
88  * return the same result as fgGetNode("foo[1]/bar[3]").
89  *
90  * @param path The path of the node, relative to root.
91  * @param index The index for the last member of the path (overrides
92  * any given in the string).
93  * @param create true to create the node if it doesn't exist.
94  * @return The node, or 0 if none exists and none was created.
95  */
96 extern SGPropertyNode * fgGetNode (const char * path,
97                                    int index, bool create = false);
98
99
100 /**
101  * Test whether a given node exists.
102  *
103  * @param path The path of the node, relative to root.
104  * @return true if the node exists, false otherwise.
105  */
106 extern bool fgHasNode (const char * path);
107
108
109 /**
110  * Add a listener to a node.
111  *
112  * @param listener The listener to add to the node.
113  * @param path The path of the node, relative to root.
114  * @param index The index for the last member of the path (overrides
115  * any given in the string).
116  */
117 extern void fgAddChangeListener (SGPropertyChangeListener * listener,
118                                  const char * path);
119
120
121 /**
122  * Add a listener to a node.
123  *
124  * @param listener The listener to add to the node.
125  * @param path The path of the node, relative to root.
126  * @param index The index for the last member of the path (overrides
127  * any given in the string).
128  */
129 extern void fgAddChangeListener (SGPropertyChangeListener * listener,
130                                  const char * path, int index);
131
132
133 /**
134  * Get a bool value for a property.
135  *
136  * This method is convenient but inefficient.  It should be used
137  * infrequently (i.e. for initializing, loading, saving, etc.),
138  * not in the main loop.  If you need to get a value frequently,
139  * it is better to look up the node itself using fgGetNode and then
140  * use the node's getBoolValue() method, to avoid the lookup overhead.
141  *
142  * @param name The property name.
143  * @param defaultValue The default value to return if the property
144  *        does not exist.
145  * @return The property's value as a bool, or the default value provided.
146  */
147 extern bool fgGetBool (const char * name, bool defaultValue = false);
148
149
150 /**
151  * Get an int value for a property.
152  *
153  * This method is convenient but inefficient.  It should be used
154  * infrequently (i.e. for initializing, loading, saving, etc.),
155  * not in the main loop.  If you need to get a value frequently,
156  * it is better to look up the node itself using fgGetNode and then
157  * use the node's getIntValue() method, to avoid the lookup overhead.
158  *
159  * @param name The property name.
160  * @param defaultValue The default value to return if the property
161  *        does not exist.
162  * @return The property's value as an int, or the default value provided.
163  */
164 extern int fgGetInt (const char * name, int defaultValue = 0);
165
166
167 /**
168  * Get a long value for a property.
169  *
170  * This method is convenient but inefficient.  It should be used
171  * infrequently (i.e. for initializing, loading, saving, etc.),
172  * not in the main loop.  If you need to get a value frequently,
173  * it is better to look up the node itself using fgGetNode and then
174  * use the node's getLongValue() method, to avoid the lookup overhead.
175  *
176  * @param name The property name.
177  * @param defaultValue The default value to return if the property
178  *        does not exist.
179  * @return The property's value as a long, or the default value provided.
180  */
181 extern int fgGetLong (const char * name, long defaultValue = 0L);
182
183
184 /**
185  * Get a float value for a property.
186  *
187  * This method is convenient but inefficient.  It should be used
188  * infrequently (i.e. for initializing, loading, saving, etc.),
189  * not in the main loop.  If you need to get a value frequently,
190  * it is better to look up the node itself using fgGetNode and then
191  * use the node's getFloatValue() method, to avoid the lookup overhead.
192  *
193  * @param name The property name.
194  * @param defaultValue The default value to return if the property
195  *        does not exist.
196  * @return The property's value as a float, or the default value provided.
197  */
198 extern float fgGetFloat (const char * name, float defaultValue = 0.0);
199
200
201 /**
202  * Get a double value for a property.
203  *
204  * This method is convenient but inefficient.  It should be used
205  * infrequently (i.e. for initializing, loading, saving, etc.),
206  * not in the main loop.  If you need to get a value frequently,
207  * it is better to look up the node itself using fgGetNode and then
208  * use the node's getDoubleValue() method, to avoid the lookup overhead.
209  *
210  * @param name The property name.
211  * @param defaultValue The default value to return if the property
212  *        does not exist.
213  * @return The property's value as a double, or the default value provided.
214  */
215 extern double fgGetDouble (const char * name, double defaultValue = 0.0);
216
217
218 /**
219  * Get a string value for a property.
220  *
221  * This method is convenient but inefficient.  It should be used
222  * infrequently (i.e. for initializing, loading, saving, etc.),
223  * not in the main loop.  If you need to get a value frequently,
224  * it is better to look up the node itself using fgGetNode and then
225  * use the node's getStringValue() method, to avoid the lookup overhead.
226  *
227  * @param name The property name.
228  * @param defaultValue The default value to return if the property
229  *        does not exist.
230  * @return The property's value as a string, or the default value provided.
231  */
232 extern const char * fgGetString (const char * name,
233                                  const char * defaultValue = "");
234
235
236 /**
237  * Set a bool value for a property.
238  *
239  * Assign a bool value to a property.  If the property does not
240  * yet exist, it will be created and its type will be set to
241  * BOOL; if it has a type of UNKNOWN, the type will also be set to
242  * BOOL; otherwise, the bool value will be converted to the property's
243  * type.
244  *
245  * @param name The property name.
246  * @param val The new value for the property.
247  * @return true if the assignment succeeded, false otherwise.
248  */
249 extern bool fgSetBool (const char * name, bool val);
250
251
252 /**
253  * Set an int value for a property.
254  *
255  * Assign an int value to a property.  If the property does not
256  * yet exist, it will be created and its type will be set to
257  * INT; if it has a type of UNKNOWN, the type will also be set to
258  * INT; otherwise, the bool value will be converted to the property's
259  * type.
260  *
261  * @param name The property name.
262  * @param val The new value for the property.
263  * @return true if the assignment succeeded, false otherwise.
264  */
265 extern bool fgSetInt (const char * name, int val);
266
267
268 /**
269  * Set a long value for a property.
270  *
271  * Assign a long value to a property.  If the property does not
272  * yet exist, it will be created and its type will be set to
273  * LONG; if it has a type of UNKNOWN, the type will also be set to
274  * LONG; otherwise, the bool value will be converted to the property's
275  * type.
276  *
277  * @param name The property name.
278  * @param val The new value for the property.
279  * @return true if the assignment succeeded, false otherwise.
280  */
281 extern bool fgSetLong (const char * name, long val);
282
283
284 /**
285  * Set a float value for a property.
286  *
287  * Assign a float value to a property.  If the property does not
288  * yet exist, it will be created and its type will be set to
289  * FLOAT; if it has a type of UNKNOWN, the type will also be set to
290  * FLOAT; otherwise, the bool value will be converted to the property's
291  * type.
292  *
293  * @param name The property name.
294  * @param val The new value for the property.
295  * @return true if the assignment succeeded, false otherwise.
296  */
297 extern bool fgSetFloat (const char * name, float val);
298
299
300 /**
301  * Set a double value for a property.
302  *
303  * Assign a double value to a property.  If the property does not
304  * yet exist, it will be created and its type will be set to
305  * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
306  * DOUBLE; otherwise, the double value will be converted to the property's
307  * type.
308  *
309  * @param name The property name.
310  * @param val The new value for the property.
311  * @return true if the assignment succeeded, false otherwise.
312  */
313 extern bool fgSetDouble (const char * name, double val);
314
315
316 /**
317  * Set a string value for a property.
318  *
319  * Assign a string value to a property.  If the property does not
320  * yet exist, it will be created and its type will be set to
321  * STRING; if it has a type of UNKNOWN, the type will also be set to
322  * STRING; otherwise, the string value will be converted to the property's
323  * type.
324  *
325  * @param name The property name.
326  * @param val The new value for the property.
327  * @return true if the assignment succeeded, false otherwise.
328  */
329 extern bool fgSetString (const char * name, const char * val);
330
331
332 \f
333 ////////////////////////////////////////////////////////////////////////
334 // Convenience functions for setting property attributes.
335 ////////////////////////////////////////////////////////////////////////
336
337
338 /**
339  * Set the state of the archive attribute for a property.
340  *
341  * If the archive attribute is true, the property will be written
342  * when a flight is saved; if it is false, the property will be
343  * skipped.
344  *
345  * A warning message will be printed if the property does not exist.
346  *
347  * @param name The property name.
348  * @param state The state of the archive attribute (defaults to true).
349  */
350 extern void fgSetArchivable (const char * name, bool state = true);
351
352
353 /**
354  * Set the state of the read attribute for a property.
355  *
356  * If the read attribute is true, the property value will be readable;
357  * if it is false, the property value will always be the default value
358  * for its type.
359  *
360  * A warning message will be printed if the property does not exist.
361  *
362  * @param name The property name.
363  * @param state The state of the read attribute (defaults to true).
364  */
365 extern void fgSetReadable (const char * name, bool state = true);
366
367
368 /**
369  * Set the state of the write attribute for a property.
370  *
371  * If the write attribute is true, the property value may be modified
372  * (depending on how it is tied); if the write attribute is false, the
373  * property value may not be modified.
374  *
375  * A warning message will be printed if the property does not exist.
376  *
377  * @param name The property name.
378  * @param state The state of the write attribute (defaults to true).
379  */
380 extern void fgSetWritable (const char * name, bool state = true);
381
382
383 \f
384 ////////////////////////////////////////////////////////////////////////
385 // Convenience functions for tying properties, with logging.
386 ////////////////////////////////////////////////////////////////////////
387
388
389 /**
390  * Untie a property from an external data source.
391  *
392  * Classes should use this function to release control of any
393  * properties they are managing.
394  */
395 extern void fgUntie (const char * name);
396
397
398 /**
399  * Tie a property to a pair of simple functions.
400  *
401  * Every time the property value is queried, the getter (if any) will
402  * be invoked; every time the property value is modified, the setter
403  * (if any) will be invoked.  The getter can be 0 to make the property
404  * unreadable, and the setter can be 0 to make the property
405  * unmodifiable.
406  *
407  * @param name The property name to tie (full path).
408  * @param getter The getter function, or 0 if the value is unreadable.
409  * @param setter The setter function, or 0 if the value is unmodifiable.
410  * @param useDefault true if the setter should be invoked with any existing 
411  *        property value should be; false if the old value should be
412  *        discarded; defaults to true.
413  */
414 template <class V>
415 inline void
416 fgTie (const char * name, V (*getter)(), void (*setter)(V) = 0,
417        bool useDefault = true)
418 {
419   if (!globals->get_props()->tie(name, SGRawValueFunctions<V>(getter, setter),
420                                  useDefault))
421     SG_LOG(SG_GENERAL, SG_WARN,
422            "Failed to tie property " << name << " to functions");
423 }
424
425
426 /**
427  * Tie a property to a pair of indexed functions.
428  *
429  * Every time the property value is queried, the getter (if any) will
430  * be invoked with the index provided; every time the property value
431  * is modified, the setter (if any) will be invoked with the index
432  * provided.  The getter can be 0 to make the property unreadable, and
433  * the setter can be 0 to make the property unmodifiable.
434  *
435  * @param name The property name to tie (full path).
436  * @param index The integer argument to pass to the getter and
437  *        setter functions.
438  * @param getter The getter function, or 0 if the value is unreadable.
439  * @param setter The setter function, or 0 if the value is unmodifiable.
440  * @param useDefault true if the setter should be invoked with any existing 
441  *        property value should be; false if the old value should be
442  *        discarded; defaults to true.
443  */
444 template <class V>
445 inline void
446 fgTie (const char * name, int index, V (*getter)(int),
447        void (*setter)(int, V) = 0, bool useDefault = true)
448 {
449   if (!globals->get_props()->tie(name,
450                                  SGRawValueFunctionsIndexed<V>(index,
451                                                                getter,
452                                                                setter),
453                                  useDefault))
454     SG_LOG(SG_GENERAL, SG_WARN,
455            "Failed to tie property " << name << " to indexed functions");
456 }
457
458
459 /**
460  * Tie a property to a pair of object methods.
461  *
462  * Every time the property value is queried, the getter (if any) will
463  * be invoked; every time the property value is modified, the setter
464  * (if any) will be invoked.  The getter can be 0 to make the property
465  * unreadable, and the setter can be 0 to make the property
466  * unmodifiable.
467  *
468  * @param name The property name to tie (full path).
469  * @param obj The object whose methods should be invoked.
470  * @param getter The object's getter method, or 0 if the value is
471  *        unreadable.
472  * @param setter The object's setter method, or 0 if the value is
473  *        unmodifiable.
474  * @param useDefault true if the setter should be invoked with any existing 
475  *        property value should be; false if the old value should be
476  *        discarded; defaults to true.
477  */
478 template <class T, class V>
479 inline void
480 fgTie (const char * name, T * obj, V (T::*getter)() const,
481        void (T::*setter)(V) = 0, bool useDefault = true)
482 {
483   if (!globals->get_props()->tie(name,
484                                  SGRawValueMethods<T,V>(*obj, getter, setter),
485                                  useDefault))
486     SG_LOG(SG_GENERAL, SG_WARN,
487            "Failed to tie property " << name << " to object methods");
488 }
489
490
491 /**
492  * Tie a property to a pair of indexed object methods.
493  *
494  * Every time the property value is queried, the getter (if any) will
495  * be invoked with the index provided; every time the property value
496  * is modified, the setter (if any) will be invoked with the index
497  * provided.  The getter can be 0 to make the property unreadable, and
498  * the setter can be 0 to make the property unmodifiable.
499  *
500  * @param name The property name to tie (full path).
501  * @param obj The object whose methods should be invoked.
502  * @param index The integer argument to pass to the getter and
503  *        setter methods.
504  * @param getter The getter method, or 0 if the value is unreadable.
505  * @param setter The setter method, or 0 if the value is unmodifiable.
506  * @param useDefault true if the setter should be invoked with any existing 
507  *        property value should be; false if the old value should be
508  *        discarded; defaults to true.
509  */
510 template <class T, class V>
511 inline void 
512 fgTie (const char * name, T * obj, int index,
513        V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
514        bool useDefault = true)
515 {
516   if (!globals->get_props()->tie(name,
517                                  SGRawValueMethodsIndexed<T,V>(*obj,
518                                                                index,
519                                                                getter,
520                                                                setter),
521                                  useDefault))
522     SG_LOG(SG_GENERAL, SG_WARN,
523            "Failed to tie property " << name << " to indexed object methods");
524 }
525
526
527 \f
528 ////////////////////////////////////////////////////////////////////////
529 // Conditions.
530 ////////////////////////////////////////////////////////////////////////
531
532
533 /**
534  * An encoded condition.
535  *
536  * This class encodes a single condition of some sort, possibly
537  * connected with properties.
538  *
539  * This class should migrate to somewhere more general.
540  */
541 class FGCondition
542 {
543 public:
544   FGCondition ();
545   virtual ~FGCondition ();
546   virtual bool test () const = 0;
547 };
548
549
550 /**
551  * Condition for a single property.
552  *
553  * This condition is true only if the property returns a boolean
554  * true value.
555  */
556 class FGPropertyCondition : public FGCondition
557 {
558 public:
559   FGPropertyCondition (const char * propname);
560   virtual ~FGPropertyCondition ();
561   virtual bool test () const { return _node->getBoolValue(); }
562 private:
563   const SGPropertyNode * _node;
564 };
565
566
567 /**
568  * Condition for a 'not' operator.
569  *
570  * This condition is true only if the child condition is false.
571  */
572 class FGNotCondition : public FGCondition
573 {
574 public:
575                                 // transfer pointer ownership
576   FGNotCondition (FGCondition * condition);
577   virtual ~FGNotCondition ();
578   virtual bool test () const;
579 private:
580   FGCondition * _condition;
581 };
582
583
584 /**
585  * Condition for an 'and' group.
586  *
587  * This condition is true only if all of the conditions
588  * in the group are true.
589  */
590 class FGAndCondition : public FGCondition
591 {
592 public:
593   FGAndCondition ();
594   virtual ~FGAndCondition ();
595   virtual bool test () const;
596                                 // transfer pointer ownership
597   virtual void addCondition (FGCondition * condition);
598 private:
599   vector<FGCondition *> _conditions;
600 };
601
602
603 /**
604  * Condition for an 'or' group.
605  *
606  * This condition is true if at least one of the conditions in the
607  * group is true.
608  */
609 class FGOrCondition : public FGCondition
610 {
611 public:
612   FGOrCondition ();
613   virtual ~FGOrCondition ();
614   virtual bool test () const;
615                                 // transfer pointer ownership
616   virtual void addCondition (FGCondition * condition);
617 private:
618   vector<FGCondition *> _conditions;
619 };
620
621
622 /**
623  * Abstract base class for property comparison conditions.
624  */
625 class FGComparisonCondition : public FGCondition
626 {
627 public:
628   enum Type {
629     LESS_THAN,
630     GREATER_THAN,
631     EQUALS
632   };
633   FGComparisonCondition (Type type, bool reverse = false);
634   virtual ~FGComparisonCondition ();
635   virtual bool test () const;
636   virtual void setLeftProperty (const char * propname);
637   virtual void setRightProperty (const char * propname);
638                                 // will make a local copy
639   virtual void setRightValue (const SGPropertyNode * value);
640 private:
641   Type _type;
642   bool _reverse;
643   const SGPropertyNode * _left_property;
644   const SGPropertyNode * _right_property;
645   const SGPropertyNode * _right_value;
646 };
647
648
649 /**
650  * Base class for a conditional components.
651  *
652  * This class manages the conditions and tests; the component should
653  * invoke the test() method whenever it needs to decide whether to
654  * active itself, draw itself, and so on.
655  */
656 class FGConditional
657 {
658 public:
659   FGConditional ();
660   virtual ~FGConditional ();
661                                 // transfer pointer ownership
662   virtual void setCondition (FGCondition * condition);
663   virtual const FGCondition * getCondition () const { return _condition; }
664   virtual bool test () const;
665 private:
666   FGCondition * _condition;
667 };
668
669
670 /**
671  * Global function to make a condition out of properties.
672  *
673  * The top-level is always an implicit 'and' group, whatever the
674  * node's name (it should usually be "condition").
675  *
676  * @param node The top-level condition node (usually named "condition").
677  * @return A pointer to a newly-allocated condition; it is the
678  *         responsibility of the caller to delete the condition when
679  *         it is no longer needed.
680  */
681 FGCondition * fgReadCondition (const SGPropertyNode * node);
682
683
684 #endif // __FG_PROPS_HXX
685