1 // fg_props.hxx - Declarations and inline methods for property handling.
2 // Written by David Megginson, started 2000.
4 // This file is in the Public Domain, and comes with no warranty.
7 #define __FG_PROPS_HXX 1
11 #include <simgear/structure/subsystem_mgr.hxx>
12 #include <simgear/math/SGMath.hxx>
14 #include <Main/globals.hxx>
16 ////////////////////////////////////////////////////////////////////////
17 // Property management.
18 ////////////////////////////////////////////////////////////////////////
20 class FGProperties : public SGSubsystem
24 virtual ~FGProperties ();
29 void update (double dt);
34 * Save a flight to disk.
36 * This function saves all of the archivable properties to a stream
37 * so that the current flight can be restored later.
39 * @param output The output stream to write the XML save file to.
40 * @param write_all If true, write all properties rather than
41 * just the ones flagged as archivable.
42 * @return true if the flight was saved successfully.
44 extern bool fgSaveFlight (std::ostream &output, bool write_all = false);
48 * Load a flight from disk.
50 * This function loads an XML save file from a stream to restore
53 * @param input The input stream to read the XML from.
54 * @return true if the flight was restored successfully.
56 extern bool fgLoadFlight (std::istream &input);
60 * Load properties from a file.
62 * @param file The relative or absolute filename.
63 * @param props The property node to load the properties into.
64 * @param in_fg_root If true, look for the file relative to
65 * $FG_ROOT; otherwise, look for the file relative to the
66 * current working directory.
67 * @return true if the properties loaded successfully, false
70 extern bool fgLoadProps (const char * path, SGPropertyNode * props,
71 bool in_fg_root = true, int default_mode = 0);
73 void setLoggingClasses (const char * c);
74 void setLoggingPriority (const char * p);
77 ////////////////////////////////////////////////////////////////////////
78 // Convenience functions for getting property values.
79 ////////////////////////////////////////////////////////////////////////
82 * Get a property node.
84 * @param path The path of the node, relative to root.
85 * @param create true to create the node if it doesn't exist.
86 * @return The node, or 0 if none exists and none was created.
88 extern SGPropertyNode * fgGetNode (const char * path, bool create = false);
91 * Get a property node.
93 * @param path The path of the node, relative to root.
94 * @param create true to create the node if it doesn't exist.
95 * @return The node, or 0 if none exists and none was created.
97 inline SGPropertyNode * fgGetNode (const std::string & path, bool create = false)
99 return fgGetNode(path.c_str(), create );
104 * Get a property node with separate index.
106 * This method separates the index from the path string, to make it
107 * easier to iterate through multiple components without using sprintf
108 * to add indices. For example, fgGetNode("foo[1]/bar", 3) will
109 * return the same result as fgGetNode("foo[1]/bar[3]").
111 * @param path The path of the node, relative to root.
112 * @param index The index for the last member of the path (overrides
113 * any given in the string).
114 * @param create true to create the node if it doesn't exist.
115 * @return The node, or 0 if none exists and none was created.
117 extern SGPropertyNode * fgGetNode (const char * path,
118 int index, bool create = false);
121 * Get a property node with separate index.
123 * This method separates the index from the path string, to make it
124 * easier to iterate through multiple components without using sprintf
125 * to add indices. For example, fgGetNode("foo[1]/bar", 3) will
126 * return the same result as fgGetNode("foo[1]/bar[3]").
128 * @param path The path of the node, relative to root.
129 * @param index The index for the last member of the path (overrides
130 * any given in the string).
131 * @param create true to create the node if it doesn't exist.
132 * @return The node, or 0 if none exists and none was created.
134 inline SGPropertyNode * fgGetNode (const std::string & path,
135 int index, bool create = false)
137 return fgGetNode(path.c_str(), index, create );
142 * Test whether a given node exists.
144 * @param path The path of the node, relative to root.
145 * @return true if the node exists, false otherwise.
147 extern bool fgHasNode (const char * path);
150 * Test whether a given node exists.
152 * @param path The path of the node, relative to root.
153 * @return true if the node exists, false otherwise.
155 inline bool fgHasNode (const std::string & path)
157 return fgHasNode( path.c_str() );
162 * Add a listener to a node.
164 * @param listener The listener to add to the node.
165 * @param path The path of the node, relative to root.
166 * @param index The index for the last member of the path (overrides
167 * any given in the string).
169 extern void fgAddChangeListener (SGPropertyChangeListener * listener,
173 * Add a listener to a node.
175 * @param listener The listener to add to the node.
176 * @param path The path of the node, relative to root.
177 * @param index The index for the last member of the path (overrides
178 * any given in the string).
180 inline void fgAddChangeListener (SGPropertyChangeListener * listener,
181 const std::string & path)
183 fgAddChangeListener( listener, path.c_str() );
188 * Add a listener to a node.
190 * @param listener The listener to add to the node.
191 * @param path The path of the node, relative to root.
192 * @param index The index for the last member of the path (overrides
193 * any given in the string).
195 extern void fgAddChangeListener (SGPropertyChangeListener * listener,
196 const char * path, int index);
199 * Add a listener to a node.
201 * @param listener The listener to add to the node.
202 * @param path The path of the node, relative to root.
203 * @param index The index for the last member of the path (overrides
204 * any given in the string).
206 inline void fgAddChangeListener (SGPropertyChangeListener * listener,
207 const std::string & path, int index)
209 fgAddChangeListener( listener, path.c_str(), index );
214 * Get a bool value for a property.
216 * This method is convenient but inefficient. It should be used
217 * infrequently (i.e. for initializing, loading, saving, etc.),
218 * not in the main loop. If you need to get a value frequently,
219 * it is better to look up the node itself using fgGetNode and then
220 * use the node's getBoolValue() method, to avoid the lookup overhead.
222 * @param name The property name.
223 * @param defaultValue The default value to return if the property
225 * @return The property's value as a bool, or the default value provided.
227 extern bool fgGetBool (const char * name, bool defaultValue = false);
230 * Get a bool value for a property.
232 * This method is convenient but inefficient. It should be used
233 * infrequently (i.e. for initializing, loading, saving, etc.),
234 * not in the main loop. If you need to get a value frequently,
235 * it is better to look up the node itself using fgGetNode and then
236 * use the node's getBoolValue() method, to avoid the lookup overhead.
238 * @param name The property name.
239 * @param defaultValue The default value to return if the property
241 * @return The property's value as a bool, or the default value provided.
243 inline bool fgGetBool (const std::string & name, bool defaultValue = false)
245 return fgGetBool( name.c_str(), defaultValue );
250 * Get an int value for a property.
252 * This method is convenient but inefficient. It should be used
253 * infrequently (i.e. for initializing, loading, saving, etc.),
254 * not in the main loop. If you need to get a value frequently,
255 * it is better to look up the node itself using fgGetNode and then
256 * use the node's getIntValue() method, to avoid the lookup overhead.
258 * @param name The property name.
259 * @param defaultValue The default value to return if the property
261 * @return The property's value as an int, or the default value provided.
263 extern int fgGetInt (const char * name, int defaultValue = 0);
266 * Get an int value for a property.
268 * This method is convenient but inefficient. It should be used
269 * infrequently (i.e. for initializing, loading, saving, etc.),
270 * not in the main loop. If you need to get a value frequently,
271 * it is better to look up the node itself using fgGetNode and then
272 * use the node's getIntValue() method, to avoid the lookup overhead.
274 * @param name The property name.
275 * @param defaultValue The default value to return if the property
277 * @return The property's value as an int, or the default value provided.
279 inline int fgGetInt (const std::string & name, int defaultValue = 0)
281 return fgGetInt( name.c_str(), defaultValue );
286 * Get a long value for a property.
288 * This method is convenient but inefficient. It should be used
289 * infrequently (i.e. for initializing, loading, saving, etc.),
290 * not in the main loop. If you need to get a value frequently,
291 * it is better to look up the node itself using fgGetNode and then
292 * use the node's getLongValue() method, to avoid the lookup overhead.
294 * @param name The property name.
295 * @param defaultValue The default value to return if the property
297 * @return The property's value as a long, or the default value provided.
299 extern int fgGetLong (const char * name, long defaultValue = 0L);
302 * Get a long value for a property.
304 * This method is convenient but inefficient. It should be used
305 * infrequently (i.e. for initializing, loading, saving, etc.),
306 * not in the main loop. If you need to get a value frequently,
307 * it is better to look up the node itself using fgGetNode and then
308 * use the node's getLongValue() method, to avoid the lookup overhead.
310 * @param name The property name.
311 * @param defaultValue The default value to return if the property
313 * @return The property's value as a long, or the default value provided.
315 inline int fgGetLong (const std::string & name, long defaultValue = 0L)
317 return fgGetLong( name.c_str(), defaultValue );
322 * Get a float value for a property.
324 * This method is convenient but inefficient. It should be used
325 * infrequently (i.e. for initializing, loading, saving, etc.),
326 * not in the main loop. If you need to get a value frequently,
327 * it is better to look up the node itself using fgGetNode and then
328 * use the node's getFloatValue() method, to avoid the lookup overhead.
330 * @param name The property name.
331 * @param defaultValue The default value to return if the property
333 * @return The property's value as a float, or the default value provided.
335 extern float fgGetFloat (const char * name, float defaultValue = 0.0);
338 * Get a float value for a property.
340 * This method is convenient but inefficient. It should be used
341 * infrequently (i.e. for initializing, loading, saving, etc.),
342 * not in the main loop. If you need to get a value frequently,
343 * it is better to look up the node itself using fgGetNode and then
344 * use the node's getFloatValue() method, to avoid the lookup overhead.
346 * @param name The property name.
347 * @param defaultValue The default value to return if the property
349 * @return The property's value as a float, or the default value provided.
351 inline float fgGetFloat (const std::string & name, float defaultValue = 0.0)
353 return fgGetFloat( name.c_str(), defaultValue );
358 * Get a double value for a property.
360 * This method is convenient but inefficient. It should be used
361 * infrequently (i.e. for initializing, loading, saving, etc.),
362 * not in the main loop. If you need to get a value frequently,
363 * it is better to look up the node itself using fgGetNode and then
364 * use the node's getDoubleValue() method, to avoid the lookup overhead.
366 * @param name The property name.
367 * @param defaultValue The default value to return if the property
369 * @return The property's value as a double, or the default value provided.
371 extern double fgGetDouble (const char * name, double defaultValue = 0.0);
374 * Get a double value for a property.
376 * This method is convenient but inefficient. It should be used
377 * infrequently (i.e. for initializing, loading, saving, etc.),
378 * not in the main loop. If you need to get a value frequently,
379 * it is better to look up the node itself using fgGetNode and then
380 * use the node's getDoubleValue() method, to avoid the lookup overhead.
382 * @param name The property name.
383 * @param defaultValue The default value to return if the property
385 * @return The property's value as a double, or the default value provided.
387 inline double fgGetDouble (const std::string & name, double defaultValue = 0.0)
389 return fgGetDouble( name.c_str(), defaultValue );
394 * Get a string value for a property.
396 * This method is convenient but inefficient. It should be used
397 * infrequently (i.e. for initializing, loading, saving, etc.),
398 * not in the main loop. If you need to get a value frequently,
399 * it is better to look up the node itself using fgGetNode and then
400 * use the node's getStringValue() method, to avoid the lookup overhead.
402 * @param name The property name.
403 * @param defaultValue The default value to return if the property
405 * @return The property's value as a string, or the default value provided.
407 extern const char * fgGetString (const char * name,
408 const char * defaultValue = "");
411 * Get a string value for a property.
413 * This method is convenient but inefficient. It should be used
414 * infrequently (i.e. for initializing, loading, saving, etc.),
415 * not in the main loop. If you need to get a value frequently,
416 * it is better to look up the node itself using fgGetNode and then
417 * use the node's getStringValue() method, to avoid the lookup overhead.
419 * @param name The property name.
420 * @param defaultValue The default value to return if the property
422 * @return The property's value as a string, or the default value provided.
424 inline const char * fgGetString (const std::string & name,
425 const std::string & defaultValue = std::string(""))
427 return fgGetString( name.c_str(), defaultValue.c_str() );
432 * Set a bool value for a property.
434 * Assign a bool value to a property. If the property does not
435 * yet exist, it will be created and its type will be set to
436 * BOOL; if it has a type of UNKNOWN, the type will also be set to
437 * BOOL; otherwise, the bool value will be converted to the property's
440 * @param name The property name.
441 * @param val The new value for the property.
442 * @return true if the assignment succeeded, false otherwise.
444 extern bool fgSetBool (const char * name, bool val);
447 * Set a bool value for a property.
449 * Assign a bool value to a property. If the property does not
450 * yet exist, it will be created and its type will be set to
451 * BOOL; if it has a type of UNKNOWN, the type will also be set to
452 * BOOL; otherwise, the bool value will be converted to the property's
455 * @param name The property name.
456 * @param val The new value for the property.
457 * @return true if the assignment succeeded, false otherwise.
459 inline bool fgSetBool (const std::string & name, bool val)
461 return fgSetBool( name.c_str(), val );
466 * Set an int value for a property.
468 * Assign an int value to a property. If the property does not
469 * yet exist, it will be created and its type will be set to
470 * INT; if it has a type of UNKNOWN, the type will also be set to
471 * INT; otherwise, the bool value will be converted to the property's
474 * @param name The property name.
475 * @param val The new value for the property.
476 * @return true if the assignment succeeded, false otherwise.
478 extern bool fgSetInt (const char * name, int val);
481 * Set an int value for a property.
483 * Assign an int value to a property. If the property does not
484 * yet exist, it will be created and its type will be set to
485 * INT; if it has a type of UNKNOWN, the type will also be set to
486 * INT; otherwise, the bool value will be converted to the property's
489 * @param name The property name.
490 * @param val The new value for the property.
491 * @return true if the assignment succeeded, false otherwise.
493 inline bool fgSetInt (const std::string & name, int val)
495 return fgSetInt( name.c_str(), val );
499 * Set a long value for a property.
501 * Assign a long value to a property. If the property does not
502 * yet exist, it will be created and its type will be set to
503 * LONG; if it has a type of UNKNOWN, the type will also be set to
504 * LONG; otherwise, the bool value will be converted to the property's
507 * @param name The property name.
508 * @param val The new value for the property.
509 * @return true if the assignment succeeded, false otherwise.
511 extern bool fgSetLong (const char * name, long val);
514 * Set a long value for a property.
516 * Assign a long value to a property. If the property does not
517 * yet exist, it will be created and its type will be set to
518 * LONG; if it has a type of UNKNOWN, the type will also be set to
519 * LONG; otherwise, the bool value will be converted to the property's
522 * @param name The property name.
523 * @param val The new value for the property.
524 * @return true if the assignment succeeded, false otherwise.
526 inline bool fgSetLong (const std::string & name, long val)
528 return fgSetLong( name.c_str(), val );
533 * Set a float value for a property.
535 * Assign a float value to a property. If the property does not
536 * yet exist, it will be created and its type will be set to
537 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
538 * FLOAT; otherwise, the bool value will be converted to the property's
541 * @param name The property name.
542 * @param val The new value for the property.
543 * @return true if the assignment succeeded, false otherwise.
545 extern bool fgSetFloat (const char * name, float val);
548 * Set a float value for a property.
550 * Assign a float value to a property. If the property does not
551 * yet exist, it will be created and its type will be set to
552 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
553 * FLOAT; otherwise, the bool value will be converted to the property's
556 * @param name The property name.
557 * @param val The new value for the property.
558 * @return true if the assignment succeeded, false otherwise.
560 inline bool fgSetFloat (const std::string & name, float val)
562 return fgSetFloat( name.c_str(), val );
567 * Set a double value for a property.
569 * Assign a double value to a property. If the property does not
570 * yet exist, it will be created and its type will be set to
571 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
572 * DOUBLE; otherwise, the double value will be converted to the property's
575 * @param name The property name.
576 * @param val The new value for the property.
577 * @return true if the assignment succeeded, false otherwise.
579 extern bool fgSetDouble (const char * name, double val);
582 * Set a double value for a property.
584 * Assign a double value to a property. If the property does not
585 * yet exist, it will be created and its type will be set to
586 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
587 * DOUBLE; otherwise, the double value will be converted to the property's
590 * @param name The property name.
591 * @param val The new value for the property.
592 * @return true if the assignment succeeded, false otherwise.
594 inline bool fgSetDouble (const std::string & name, double val)
596 return fgSetDouble( name.c_str(), val );
601 * Set a string value for a property.
603 * Assign a string value to a property. If the property does not
604 * yet exist, it will be created and its type will be set to
605 * STRING; if it has a type of UNKNOWN, the type will also be set to
606 * STRING; otherwise, the string value will be converted to the property's
609 * @param name The property name.
610 * @param val The new value for the property.
611 * @return true if the assignment succeeded, false otherwise.
613 extern bool fgSetString (const char * name, const char * val);
616 * Set a string value for a property.
618 * Assign a string value to a property. If the property does not
619 * yet exist, it will be created and its type will be set to
620 * STRING; if it has a type of UNKNOWN, the type will also be set to
621 * STRING; otherwise, the string value will be converted to the property's
624 * @param name The property name.
625 * @param val The new value for the property.
626 * @return true if the assignment succeeded, false otherwise.
628 inline bool fgSetString (const std::string & name, const std::string & val)
630 return fgSetString( name.c_str(), val.c_str() );
635 ////////////////////////////////////////////////////////////////////////
636 // Convenience functions for setting property attributes.
637 ////////////////////////////////////////////////////////////////////////
641 * Set the state of the archive attribute for a property.
643 * If the archive attribute is true, the property will be written
644 * when a flight is saved; if it is false, the property will be
647 * A warning message will be printed if the property does not exist.
649 * @param name The property name.
650 * @param state The state of the archive attribute (defaults to true).
652 extern void fgSetArchivable (const char * name, bool state = true);
656 * Set the state of the read attribute for a property.
658 * If the read attribute is true, the property value will be readable;
659 * if it is false, the property value will always be the default value
662 * A warning message will be printed if the property does not exist.
664 * @param name The property name.
665 * @param state The state of the read attribute (defaults to true).
667 extern void fgSetReadable (const char * name, bool state = true);
671 * Set the state of the write attribute for a property.
673 * If the write attribute is true, the property value may be modified
674 * (depending on how it is tied); if the write attribute is false, the
675 * property value may not be modified.
677 * A warning message will be printed if the property does not exist.
679 * @param name The property name.
680 * @param state The state of the write attribute (defaults to true).
682 extern void fgSetWritable (const char * name, bool state = true);
686 ////////////////////////////////////////////////////////////////////////
687 // Convenience functions for tying properties, with logging.
688 ////////////////////////////////////////////////////////////////////////
692 * Untie a property from an external data source.
694 * Classes should use this function to release control of any
695 * properties they are managing.
697 extern void fgUntie (const char * name);
701 * Tie a property to a pair of simple functions.
703 * Every time the property value is queried, the getter (if any) will
704 * be invoked; every time the property value is modified, the setter
705 * (if any) will be invoked. The getter can be 0 to make the property
706 * unreadable, and the setter can be 0 to make the property
709 * @param name The property name to tie (full path).
710 * @param getter The getter function, or 0 if the value is unreadable.
711 * @param setter The setter function, or 0 if the value is unmodifiable.
712 * @param useDefault true if the setter should be invoked with any existing
713 * property value should be; false if the old value should be
714 * discarded; defaults to true.
718 fgTie (const char * name, V (*getter)(), void (*setter)(V) = 0,
719 bool useDefault = true)
721 if (!globals->get_props()->tie(name, SGRawValueFunctions<V>(getter, setter),
723 SG_LOG(SG_GENERAL, SG_WARN,
724 "Failed to tie property " << name << " to functions");
729 * Tie a property to a pair of indexed functions.
731 * Every time the property value is queried, the getter (if any) will
732 * be invoked with the index provided; every time the property value
733 * is modified, the setter (if any) will be invoked with the index
734 * provided. The getter can be 0 to make the property unreadable, and
735 * the setter can be 0 to make the property unmodifiable.
737 * @param name The property name to tie (full path).
738 * @param index The integer argument to pass to the getter and
740 * @param getter The getter function, or 0 if the value is unreadable.
741 * @param setter The setter function, or 0 if the value is unmodifiable.
742 * @param useDefault true if the setter should be invoked with any existing
743 * property value should be; false if the old value should be
744 * discarded; defaults to true.
748 fgTie (const char * name, int index, V (*getter)(int),
749 void (*setter)(int, V) = 0, bool useDefault = true)
751 if (!globals->get_props()->tie(name,
752 SGRawValueFunctionsIndexed<V>(index,
756 SG_LOG(SG_GENERAL, SG_WARN,
757 "Failed to tie property " << name << " to indexed functions");
762 * Tie a property to a pair of object methods.
764 * Every time the property value is queried, the getter (if any) will
765 * be invoked; every time the property value is modified, the setter
766 * (if any) will be invoked. The getter can be 0 to make the property
767 * unreadable, and the setter can be 0 to make the property
770 * @param name The property name to tie (full path).
771 * @param obj The object whose methods should be invoked.
772 * @param getter The object's getter method, or 0 if the value is
774 * @param setter The object's setter method, or 0 if the value is
776 * @param useDefault true if the setter should be invoked with any existing
777 * property value should be; false if the old value should be
778 * discarded; defaults to true.
780 template <class T, class V>
782 fgTie (const char * name, T * obj, V (T::*getter)() const,
783 void (T::*setter)(V) = 0, bool useDefault = true)
785 if (!globals->get_props()->tie(name,
786 SGRawValueMethods<T,V>(*obj, getter, setter),
788 SG_LOG(SG_GENERAL, SG_WARN,
789 "Failed to tie property " << name << " to object methods");
794 * Tie a property to a pair of indexed object methods.
796 * Every time the property value is queried, the getter (if any) will
797 * be invoked with the index provided; every time the property value
798 * is modified, the setter (if any) will be invoked with the index
799 * provided. The getter can be 0 to make the property unreadable, and
800 * the setter can be 0 to make the property unmodifiable.
802 * @param name The property name to tie (full path).
803 * @param obj The object whose methods should be invoked.
804 * @param index The integer argument to pass to the getter and
806 * @param getter The getter method, or 0 if the value is unreadable.
807 * @param setter The setter method, or 0 if the value is unmodifiable.
808 * @param useDefault true if the setter should be invoked with any existing
809 * property value should be; false if the old value should be
810 * discarded; defaults to true.
812 template <class T, class V>
814 fgTie (const char * name, T * obj, int index,
815 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
816 bool useDefault = true)
818 if (!globals->get_props()->tie(name,
819 SGRawValueMethodsIndexed<T,V>(*obj,
824 SG_LOG(SG_GENERAL, SG_WARN,
825 "Failed to tie property " << name << " to indexed object methods");
829 class FGMakeUpperCase : public SGPropertyChangeListener {
831 void valueChanged(SGPropertyNode *node) {
832 if (node->getType() != simgear::props::STRING)
835 char *s = const_cast<char *>(node->getStringValue());
842 #endif // __FG_PROPS_HXX