2 // Class wrapper for property handling.
3 // based on FlightGear source src/Main/fg_props.hxx
4 // Originally written by David Megginson, started 2000.
6 // This file is in the Public Domain, and comes with no warranty.
8 #ifndef FGPROPERTYMANAGER_H
9 #define FGPROPERTYMANAGER_H
11 #include <simgear/misc/props.hxx>
15 class FGPropertyManager:public SGPropertyNode {
17 FGPropertyManager(void) {
21 ~FGPropertyManager(void) {
25 * Get a property node.
27 * @param path The path of the node, relative to root.
28 * @param create true to create the node if it doesn't exist.
29 * @return The node, or 0 if none exists and none was created.
31 inline FGPropertyManager*
32 GetNode (const string &path, bool create = false)
34 SGPropertyNode* node=this->getNode(path.c_str(), create);
36 cout << "FGPropertyManager::GetNode() No node found for "
38 return (FGPropertyManager*)node;
41 inline FGPropertyManager*
42 GetNode (const string &relpath, int index, bool create = false)
44 return (FGPropertyManager*)getNode(relpath.c_str(),index,create);
49 * Test whether a given node exists.
51 * @param path The path of the node, relative to root.
52 * @return true if the node exists, false otherwise.
55 HasNode (const string &path)
57 return (GetNode(path, false) != 0);
62 * Get a bool value for a property.
64 * This method is convenient but inefficient. It should be used
65 * infrequently (i.e. for initializing, loading, saving, etc.),
66 * not in the main loop. If you need to get a value frequently,
67 * it is better to look up the node itself using GetNode and then
68 * use the node's getBoolValue() method, to avoid the lookup overhead.
70 * @param name The property name.
71 * @param defaultValue The default value to return if the property
73 * @return The property's value as a bool, or the default value provided.
75 inline bool GetBool (const string &name, bool defaultValue = false)
77 return getBoolValue(name.c_str(), defaultValue);
82 * Get an int value for a property.
84 * This method is convenient but inefficient. It should be used
85 * infrequently (i.e. for initializing, loading, saving, etc.),
86 * not in the main loop. If you need to get a value frequently,
87 * it is better to look up the node itself using GetNode and then
88 * use the node's getIntValue() method, to avoid the lookup overhead.
90 * @param name The property name.
91 * @param defaultValue The default value to return if the property
93 * @return The property's value as an int, or the default value provided.
95 inline int GetInt (const string &name, int defaultValue = 0)
97 return getIntValue(name.c_str(), defaultValue);
102 * Get a long value for a property.
104 * This method is convenient but inefficient. It should be used
105 * infrequently (i.e. for initializing, loading, saving, etc.),
106 * not in the main loop. If you need to get a value frequently,
107 * it is better to look up the node itself using GetNode and then
108 * use the node's getLongValue() method, to avoid the lookup overhead.
110 * @param name The property name.
111 * @param defaultValue The default value to return if the property
113 * @return The property's value as a long, or the default value provided.
115 inline int GetLong (const string &name, long defaultValue = 0L)
117 return getLongValue(name.c_str(), defaultValue);
122 * Get a float value for a property.
124 * This method is convenient but inefficient. It should be used
125 * infrequently (i.e. for initializing, loading, saving, etc.),
126 * not in the main loop. If you need to get a value frequently,
127 * it is better to look up the node itself using GetNode and then
128 * use the node's getFloatValue() method, to avoid the lookup overhead.
130 * @param name The property name.
131 * @param defaultValue The default value to return if the property
133 * @return The property's value as a float, or the default value provided.
135 inline float GetFloat (const string &name, float defaultValue = 0.0)
137 return getFloatValue(name.c_str(), defaultValue);
142 * Get a double value for a property.
144 * This method is convenient but inefficient. It should be used
145 * infrequently (i.e. for initializing, loading, saving, etc.),
146 * not in the main loop. If you need to get a value frequently,
147 * it is better to look up the node itself using GetNode and then
148 * use the node's getDoubleValue() method, to avoid the lookup overhead.
150 * @param name The property name.
151 * @param defaultValue The default value to return if the property
153 * @return The property's value as a double, or the default value provided.
155 inline double GetDouble (const string &name, double defaultValue = 0.0)
157 return getDoubleValue(name.c_str(), defaultValue);
162 * Get a string value for a property.
164 * This method is convenient but inefficient. It should be used
165 * infrequently (i.e. for initializing, loading, saving, etc.),
166 * not in the main loop. If you need to get a value frequently,
167 * it is better to look up the node itself using GetNode and then
168 * use the node's getStringValue() method, to avoid the lookup overhead.
170 * @param name The property name.
171 * @param defaultValue The default value to return if the property
173 * @return The property's value as a string, or the default value provided.
175 inline string GetString (const string &name, string defaultValue = "")
177 return string(getStringValue(name.c_str(), defaultValue.c_str()));
182 * Set a bool value for a property.
184 * Assign a bool value to a property. If the property does not
185 * yet exist, it will be created and its type will be set to
186 * BOOL; if it has a type of UNKNOWN, the type will also be set to
187 * BOOL; otherwise, the bool value will be converted to the property's
190 * @param name The property name.
191 * @param val The new value for the property.
192 * @return true if the assignment succeeded, false otherwise.
194 inline bool SetBool (const string &name, bool val)
196 return setBoolValue(name.c_str(), val);
201 * Set an int value for a property.
203 * Assign an int value to a property. If the property does not
204 * yet exist, it will be created and its type will be set to
205 * INT; if it has a type of UNKNOWN, the type will also be set to
206 * INT; otherwise, the bool value will be converted to the property's
209 * @param name The property name.
210 * @param val The new value for the property.
211 * @return true if the assignment succeeded, false otherwise.
213 inline bool SetInt (const string &name, int val)
215 return setIntValue(name.c_str(), val);
220 * Set a long value for a property.
222 * Assign a long value to a property. If the property does not
223 * yet exist, it will be created and its type will be set to
224 * LONG; if it has a type of UNKNOWN, the type will also be set to
225 * LONG; otherwise, the bool value will be converted to the property's
228 * @param name The property name.
229 * @param val The new value for the property.
230 * @return true if the assignment succeeded, false otherwise.
232 inline bool SetLong (const string &name, long val)
234 return setLongValue(name.c_str(), val);
239 * Set a float value for a property.
241 * Assign a float value to a property. If the property does not
242 * yet exist, it will be created and its type will be set to
243 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
244 * FLOAT; otherwise, the bool value will be converted to the property's
247 * @param name The property name.
248 * @param val The new value for the property.
249 * @return true if the assignment succeeded, false otherwise.
251 inline bool SetFloat (const string &name, float val)
253 return setFloatValue(name.c_str(), val);
258 * Set a double value for a property.
260 * Assign a double value to a property. If the property does not
261 * yet exist, it will be created and its type will be set to
262 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
263 * DOUBLE; otherwise, the double value will be converted to the property's
266 * @param name The property name.
267 * @param val The new value for the property.
268 * @return true if the assignment succeeded, false otherwise.
270 inline bool SetDouble (const string &name, double val)
272 return setDoubleValue(name.c_str(), val);
277 * Set a string value for a property.
279 * Assign a string value to a property. If the property does not
280 * yet exist, it will be created and its type will be set to
281 * STRING; if it has a type of UNKNOWN, the type will also be set to
282 * STRING; otherwise, the string value will be converted to the property's
285 * @param name The property name.
286 * @param val The new value for the property.
287 * @return true if the assignment succeeded, false otherwise.
289 inline bool SetString (const string &name, const string &val)
291 return setStringValue(name.c_str(), val.c_str());
296 ////////////////////////////////////////////////////////////////////////
297 // Convenience functions for setting property attributes.
298 ////////////////////////////////////////////////////////////////////////
302 * Set the state of the archive attribute for a property.
304 * If the archive attribute is true, the property will be written
305 * when a flight is saved; if it is false, the property will be
308 * A warning message will be printed if the property does not exist.
310 * @param name The property name.
311 * @param state The state of the archive attribute (defaults to true).
314 SetArchivable (const string &name, bool state = true)
316 SGPropertyNode * node = getNode(name.c_str());
319 "Attempt to set archive flag for non-existant property "
322 node->setAttribute(SGPropertyNode::ARCHIVE, state);
327 * Set the state of the read attribute for a property.
329 * If the read attribute is true, the property value will be readable;
330 * if it is false, the property value will always be the default value
333 * A warning message will be printed if the property does not exist.
335 * @param name The property name.
336 * @param state The state of the read attribute (defaults to true).
339 SetReadable (const string &name, bool state = true)
341 SGPropertyNode * node = getNode(name.c_str());
344 "Attempt to set read flag for non-existant property "
347 node->setAttribute(SGPropertyNode::READ, state);
352 * Set the state of the write attribute for a property.
354 * If the write attribute is true, the property value may be modified
355 * (depending on how it is tied); if the write attribute is false, the
356 * property value may not be modified.
358 * A warning message will be printed if the property does not exist.
360 * @param name The property name.
361 * @param state The state of the write attribute (defaults to true).
364 SetWritable (const string &name, bool state = true)
366 SGPropertyNode * node = getNode(name.c_str());
369 "Attempt to set write flag for non-existant property "
372 node->setAttribute(SGPropertyNode::WRITE, state);
377 ////////////////////////////////////////////////////////////////////////
378 // Convenience functions for tying properties, with logging.
379 ////////////////////////////////////////////////////////////////////////
383 * Untie a property from an external data source.
385 * Classes should use this function to release control of any
386 * properties they are managing.
389 Untie (const string &name)
391 if (!untie(name.c_str()))
392 cout << "Failed to untie property " << name;
396 // Templates cause ambiguity here
399 * Tie a property to an external bool variable.
401 * The property's value will automatically mirror the variable's
402 * value, and vice-versa, until the property is untied.
404 * @param name The property name to tie (full path).
405 * @param pointer A pointer to the variable.
406 * @param useDefault true if any existing property value should be
407 * copied to the variable; false if the variable should not
408 * be modified; defaults to true.
411 Tie (const string &name, bool *pointer, bool useDefault = true)
413 if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer),
416 "Failed to tie property " << name << " to a pointer";
421 * Tie a property to an external int variable.
423 * The property's value will automatically mirror the variable's
424 * value, and vice-versa, until the property is untied.
426 * @param name The property name to tie (full path).
427 * @param pointer A pointer to the variable.
428 * @param useDefault true if any existing property value should be
429 * copied to the variable; false if the variable should not
430 * be modified; defaults to true.
433 Tie (const string &name, int *pointer, bool useDefault = true)
435 if (!tie(name.c_str(), SGRawValuePointer<int>(pointer),
438 "Failed to tie property " << name << " to a pointer";
443 * Tie a property to an external long variable.
445 * The property's value will automatically mirror the variable's
446 * value, and vice-versa, until the property is untied.
448 * @param name The property name to tie (full path).
449 * @param pointer A pointer to the variable.
450 * @param useDefault true if any existing property value should be
451 * copied to the variable; false if the variable should not
452 * be modified; defaults to true.
455 Tie (const string &name, long *pointer, bool useDefault = true)
457 if (!tie(name.c_str(), SGRawValuePointer<long>(pointer),
460 "Failed to tie property " << name << " to a pointer";
465 * Tie a property to an external float variable.
467 * The property's value will automatically mirror the variable's
468 * value, and vice-versa, until the property is untied.
470 * @param name The property name to tie (full path).
471 * @param pointer A pointer to the variable.
472 * @param useDefault true if any existing property value should be
473 * copied to the variable; false if the variable should not
474 * be modified; defaults to true.
477 Tie (const string &name, float *pointer, bool useDefault = true)
479 if (!tie(name.c_str(), SGRawValuePointer<float>(pointer),
482 "Failed to tie property " << name << " to a pointer";
487 * Tie a property to an external double variable.
489 * The property's value will automatically mirror the variable's
490 * value, and vice-versa, until the property is untied.
492 * @param name The property name to tie (full path).
493 * @param pointer A pointer to the variable.
494 * @param useDefault true if any existing property value should be
495 * copied to the variable; false if the variable should not
496 * be modified; defaults to true.
499 Tie (const string &name, double *pointer, bool useDefault = true)
501 if (!tie(name.c_str(), SGRawValuePointer<double>(pointer),
504 "Failed to tie property " << name << " to a pointer";
507 /* template <class V> void
508 FGPropertyManager::Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
509 bool useDefault = true);
511 template <class V> void
512 FGPropertyManager::Tie (const string &name, int index, V (*getter)(int),
513 void (*setter)(int, V) = 0, bool useDefault = true);
515 template <class T, class V> void
516 FGPropertyManager::Tie (const string &name, T * obj, V (T::*getter)() const,
517 void (T::*setter)(V) = 0, bool useDefault = true);
519 template <class T, class V> void
520 FGPropertyManager::Tie (const string &name, T * obj, int index,
521 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
522 bool useDefault = true); */
525 * Tie a property to a pair of simple functions.
527 * Every time the property value is queried, the getter (if any) will
528 * be invoked; every time the property value is modified, the setter
529 * (if any) will be invoked. The getter can be 0 to make the property
530 * unreadable, and the setter can be 0 to make the property
533 * @param name The property name to tie (full path).
534 * @param getter The getter function, or 0 if the value is unreadable.
535 * @param setter The setter function, or 0 if the value is unmodifiable.
536 * @param useDefault true if the setter should be invoked with any existing
537 * property value should be; false if the old value should be
538 * discarded; defaults to true.
542 FGPropertyManager::Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
543 bool useDefault = true)
545 if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter),
548 "Failed to tie property " << name << " to functions";
553 * Tie a property to a pair of indexed functions.
555 * Every time the property value is queried, the getter (if any) will
556 * be invoked with the index provided; every time the property value
557 * is modified, the setter (if any) will be invoked with the index
558 * provided. The getter can be 0 to make the property unreadable, and
559 * the setter can be 0 to make the property unmodifiable.
561 * @param name The property name to tie (full path).
562 * @param index The integer argument to pass to the getter and
564 * @param getter The getter function, or 0 if the value is unreadable.
565 * @param setter The setter function, or 0 if the value is unmodifiable.
566 * @param useDefault true if the setter should be invoked with any existing
567 * property value should be; false if the old value should be
568 * discarded; defaults to true.
572 FGPropertyManager::Tie (const string &name, int index, V (*getter)(int),
573 void (*setter)(int, V) = 0, bool useDefault = true)
575 if (!tie(name.c_str(),
576 SGRawValueFunctionsIndexed<V>(index,
581 "Failed to tie property " << name << " to indexed functions";
586 * Tie a property to a pair of object methods.
588 * Every time the property value is queried, the getter (if any) will
589 * be invoked; every time the property value is modified, the setter
590 * (if any) will be invoked. The getter can be 0 to make the property
591 * unreadable, and the setter can be 0 to make the property
594 * @param name The property name to tie (full path).
595 * @param obj The object whose methods should be invoked.
596 * @param getter The object's getter method, or 0 if the value is
598 * @param setter The object's setter method, or 0 if the value is
600 * @param useDefault true if the setter should be invoked with any existing
601 * property value should be; false if the old value should be
602 * discarded; defaults to true.
604 template <class T, class V>
606 FGPropertyManager::Tie (const string &name, T * obj, V (T::*getter)() const,
607 void (T::*setter)(V) = 0, bool useDefault = true)
609 if (!tie(name.c_str(),
610 SGRawValueMethods<T,V>(*obj, getter, setter),
613 "Failed to tie property " << name << " to object methods";
618 * Tie a property to a pair of indexed object methods.
620 * Every time the property value is queried, the getter (if any) will
621 * be invoked with the index provided; every time the property value
622 * is modified, the setter (if any) will be invoked with the index
623 * provided. The getter can be 0 to make the property unreadable, and
624 * the setter can be 0 to make the property unmodifiable.
626 * @param name The property name to tie (full path).
627 * @param obj The object whose methods should be invoked.
628 * @param index The integer argument to pass to the getter and
630 * @param getter The getter method, or 0 if the value is unreadable.
631 * @param setter The setter method, or 0 if the value is unmodifiable.
632 * @param useDefault true if the setter should be invoked with any existing
633 * property value should be; false if the old value should be
634 * discarded; defaults to true.
636 template <class T, class V>
638 FGPropertyManager::Tie (const string &name, T * obj, int index,
639 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
640 bool useDefault = true)
642 if (!tie(name.c_str(),
643 SGRawValueMethodsIndexed<T,V>(*obj,
649 "Failed to tie property " << name << " to indexed object methods";
655 #endif // FGPROPERTYMANAGER_H