1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Header: FGPropertyManager.h
5 Based on work originally by David Megginson
8 ------------- Copyright (C) 2002 -------------
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
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 General Public License for more
20 You should have received a copy of the GNU 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.
24 Further information about the GNU General Public License can also be found on
25 the world wide web at http://www.gnu.org.
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
31 #ifndef FGPROPERTYMANAGER_H
32 #define FGPROPERTYMANAGER_H
34 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 #include <simgear/misc/props.hxx>
40 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
44 #define ID_PROPERTYMANAGER "$Id$"
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60 /** Class wrapper for property handling.
61 @author David Megginson, Tony Peden
62 @see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGPropertyManager.h?rev=HEAD&content-type=text/vnd.viewcvs-markup">
66 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
70 class FGPropertyManager:public SGPropertyNode {
73 FGPropertyManager(void) {
77 ~FGPropertyManager(void) {
81 * Get a property node.
83 * @param path The path of the node, relative to root.
84 * @param create true to create the node if it doesn't exist.
85 * @return The node, or 0 if none exists and none was created.
87 inline FGPropertyManager*
88 GetNode (const string &path, bool create = false)
90 SGPropertyNode* node=this->getNode(path.c_str(), create);
92 cout << "FGPropertyManager::GetNode() No node found for "
94 return (FGPropertyManager*)node;
97 inline FGPropertyManager*
98 GetNode (const string &relpath, int index, bool create = false)
100 return (FGPropertyManager*)getNode(relpath.c_str(),index,create);
105 * Test whether a given node exists.
107 * @param path The path of the node, relative to root.
108 * @return true if the node exists, false otherwise.
111 HasNode (const string &path)
113 return (GetNode(path, false) != 0);
118 * Get a bool value for a property.
120 * This method is convenient but inefficient. It should be used
121 * infrequently (i.e. for initializing, loading, saving, etc.),
122 * not in the main loop. If you need to get a value frequently,
123 * it is better to look up the node itself using GetNode and then
124 * use the node's getBoolValue() method, to avoid the lookup overhead.
126 * @param name The property name.
127 * @param defaultValue The default value to return if the property
129 * @return The property's value as a bool, or the default value provided.
131 inline bool GetBool (const string &name, bool defaultValue = false)
133 return getBoolValue(name.c_str(), defaultValue);
138 * Get an int value for a property.
140 * This method is convenient but inefficient. It should be used
141 * infrequently (i.e. for initializing, loading, saving, etc.),
142 * not in the main loop. If you need to get a value frequently,
143 * it is better to look up the node itself using GetNode and then
144 * use the node's getIntValue() method, to avoid the lookup overhead.
146 * @param name The property name.
147 * @param defaultValue The default value to return if the property
149 * @return The property's value as an int, or the default value provided.
151 inline int GetInt (const string &name, int defaultValue = 0)
153 return getIntValue(name.c_str(), defaultValue);
158 * Get a long value for a property.
160 * This method is convenient but inefficient. It should be used
161 * infrequently (i.e. for initializing, loading, saving, etc.),
162 * not in the main loop. If you need to get a value frequently,
163 * it is better to look up the node itself using GetNode and then
164 * use the node's getLongValue() method, to avoid the lookup overhead.
166 * @param name The property name.
167 * @param defaultValue The default value to return if the property
169 * @return The property's value as a long, or the default value provided.
171 inline int GetLong (const string &name, long defaultValue = 0L)
173 return getLongValue(name.c_str(), defaultValue);
178 * Get a float value for a property.
180 * This method is convenient but inefficient. It should be used
181 * infrequently (i.e. for initializing, loading, saving, etc.),
182 * not in the main loop. If you need to get a value frequently,
183 * it is better to look up the node itself using GetNode and then
184 * use the node's getFloatValue() method, to avoid the lookup overhead.
186 * @param name The property name.
187 * @param defaultValue The default value to return if the property
189 * @return The property's value as a float, or the default value provided.
191 inline float GetFloat (const string &name, float defaultValue = 0.0)
193 return getFloatValue(name.c_str(), defaultValue);
198 * Get a double value for a property.
200 * This method is convenient but inefficient. It should be used
201 * infrequently (i.e. for initializing, loading, saving, etc.),
202 * not in the main loop. If you need to get a value frequently,
203 * it is better to look up the node itself using GetNode and then
204 * use the node's getDoubleValue() method, to avoid the lookup overhead.
206 * @param name The property name.
207 * @param defaultValue The default value to return if the property
209 * @return The property's value as a double, or the default value provided.
211 inline double GetDouble (const string &name, double defaultValue = 0.0)
213 return getDoubleValue(name.c_str(), defaultValue);
218 * Get a string value for a property.
220 * This method is convenient but inefficient. It should be used
221 * infrequently (i.e. for initializing, loading, saving, etc.),
222 * not in the main loop. If you need to get a value frequently,
223 * it is better to look up the node itself using GetNode and then
224 * use the node's getStringValue() method, to avoid the lookup overhead.
226 * @param name The property name.
227 * @param defaultValue The default value to return if the property
229 * @return The property's value as a string, or the default value provided.
231 inline string GetString (const string &name, string defaultValue = "")
233 return string(getStringValue(name.c_str(), defaultValue.c_str()));
238 * Set a bool value for a property.
240 * Assign a bool value to a property. If the property does not
241 * yet exist, it will be created and its type will be set to
242 * BOOL; if it has a type of UNKNOWN, the type will also be set to
243 * BOOL; otherwise, the bool value will be converted to the property's
246 * @param name The property name.
247 * @param val The new value for the property.
248 * @return true if the assignment succeeded, false otherwise.
250 inline bool SetBool (const string &name, bool val)
252 return setBoolValue(name.c_str(), val);
257 * Set an int value for a property.
259 * Assign an int value to a property. If the property does not
260 * yet exist, it will be created and its type will be set to
261 * INT; if it has a type of UNKNOWN, the type will also be set to
262 * INT; otherwise, the bool value will be converted to the property's
265 * @param name The property name.
266 * @param val The new value for the property.
267 * @return true if the assignment succeeded, false otherwise.
269 inline bool SetInt (const string &name, int val)
271 return setIntValue(name.c_str(), val);
276 * Set a long value for a property.
278 * Assign a long value to a property. If the property does not
279 * yet exist, it will be created and its type will be set to
280 * LONG; if it has a type of UNKNOWN, the type will also be set to
281 * LONG; otherwise, the bool value will be converted to the property's
284 * @param name The property name.
285 * @param val The new value for the property.
286 * @return true if the assignment succeeded, false otherwise.
288 inline bool SetLong (const string &name, long val)
290 return setLongValue(name.c_str(), val);
295 * Set a float value for a property.
297 * Assign a float value to a property. If the property does not
298 * yet exist, it will be created and its type will be set to
299 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
300 * FLOAT; otherwise, the bool value will be converted to the property's
303 * @param name The property name.
304 * @param val The new value for the property.
305 * @return true if the assignment succeeded, false otherwise.
307 inline bool SetFloat (const string &name, float val)
309 return setFloatValue(name.c_str(), val);
314 * Set a double value for a property.
316 * Assign a double value to a property. If the property does not
317 * yet exist, it will be created and its type will be set to
318 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
319 * DOUBLE; otherwise, the double value will be converted to the property's
322 * @param name The property name.
323 * @param val The new value for the property.
324 * @return true if the assignment succeeded, false otherwise.
326 inline bool SetDouble (const string &name, double val)
328 return setDoubleValue(name.c_str(), val);
333 * Set a string value for a property.
335 * Assign a string value to a property. If the property does not
336 * yet exist, it will be created and its type will be set to
337 * STRING; if it has a type of UNKNOWN, the type will also be set to
338 * STRING; otherwise, the string value will be converted to the property's
341 * @param name The property name.
342 * @param val The new value for the property.
343 * @return true if the assignment succeeded, false otherwise.
345 inline bool SetString (const string &name, const string &val)
347 return setStringValue(name.c_str(), val.c_str());
352 ////////////////////////////////////////////////////////////////////////
353 // Convenience functions for setting property attributes.
354 ////////////////////////////////////////////////////////////////////////
358 * Set the state of the archive attribute for a property.
360 * If the archive attribute is true, the property will be written
361 * when a flight is saved; if it is false, the property will be
364 * A warning message will be printed if the property does not exist.
366 * @param name The property name.
367 * @param state The state of the archive attribute (defaults to true).
370 SetArchivable (const string &name, bool state = true)
372 SGPropertyNode * node = getNode(name.c_str());
375 "Attempt to set archive flag for non-existant property "
378 node->setAttribute(SGPropertyNode::ARCHIVE, state);
383 * Set the state of the read attribute for a property.
385 * If the read attribute is true, the property value will be readable;
386 * if it is false, the property value will always be the default value
389 * A warning message will be printed if the property does not exist.
391 * @param name The property name.
392 * @param state The state of the read attribute (defaults to true).
395 SetReadable (const string &name, bool state = true)
397 SGPropertyNode * node = getNode(name.c_str());
400 "Attempt to set read flag for non-existant property "
403 node->setAttribute(SGPropertyNode::READ, state);
408 * Set the state of the write attribute for a property.
410 * If the write attribute is true, the property value may be modified
411 * (depending on how it is tied); if the write attribute is false, the
412 * property value may not be modified.
414 * A warning message will be printed if the property does not exist.
416 * @param name The property name.
417 * @param state The state of the write attribute (defaults to true).
420 SetWritable (const string &name, bool state = true)
422 SGPropertyNode * node = getNode(name.c_str());
425 "Attempt to set write flag for non-existant property "
428 node->setAttribute(SGPropertyNode::WRITE, state);
433 ////////////////////////////////////////////////////////////////////////
434 // Convenience functions for tying properties, with logging.
435 ////////////////////////////////////////////////////////////////////////
439 * Untie a property from an external data source.
441 * Classes should use this function to release control of any
442 * properties they are managing.
445 Untie (const string &name)
447 if (!untie(name.c_str()))
448 cout << "Failed to untie property " << name;
452 // Templates cause ambiguity here
455 * Tie a property to an external bool variable.
457 * The property's value will automatically mirror the variable's
458 * value, and vice-versa, until the property is untied.
460 * @param name The property name to tie (full path).
461 * @param pointer A pointer to the variable.
462 * @param useDefault true if any existing property value should be
463 * copied to the variable; false if the variable should not
464 * be modified; defaults to true.
467 Tie (const string &name, bool *pointer, bool useDefault = true)
469 if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer),
472 "Failed to tie property " << name << " to a pointer";
477 * Tie a property to an external int variable.
479 * The property's value will automatically mirror the variable's
480 * value, and vice-versa, until the property is untied.
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.
489 Tie (const string &name, int *pointer, bool useDefault = true)
491 if (!tie(name.c_str(), SGRawValuePointer<int>(pointer),
494 "Failed to tie property " << name << " to a pointer";
499 * Tie a property to an external long variable.
501 * The property's value will automatically mirror the variable's
502 * value, and vice-versa, until the property is untied.
504 * @param name The property name to tie (full path).
505 * @param pointer A pointer to the variable.
506 * @param useDefault true if any existing property value should be
507 * copied to the variable; false if the variable should not
508 * be modified; defaults to true.
511 Tie (const string &name, long *pointer, bool useDefault = true)
513 if (!tie(name.c_str(), SGRawValuePointer<long>(pointer),
516 "Failed to tie property " << name << " to a pointer";
521 * Tie a property to an external float variable.
523 * The property's value will automatically mirror the variable's
524 * value, and vice-versa, until the property is untied.
526 * @param name The property name to tie (full path).
527 * @param pointer A pointer to the variable.
528 * @param useDefault true if any existing property value should be
529 * copied to the variable; false if the variable should not
530 * be modified; defaults to true.
533 Tie (const string &name, float *pointer, bool useDefault = true)
535 if (!tie(name.c_str(), SGRawValuePointer<float>(pointer),
538 "Failed to tie property " << name << " to a pointer";
543 * Tie a property to an external double variable.
545 * The property's value will automatically mirror the variable's
546 * value, and vice-versa, until the property is untied.
548 * @param name The property name to tie (full path).
549 * @param pointer A pointer to the variable.
550 * @param useDefault true if any existing property value should be
551 * copied to the variable; false if the variable should not
552 * be modified; defaults to true.
555 Tie (const string &name, double *pointer, bool useDefault = true)
557 if (!tie(name.c_str(), SGRawValuePointer<double>(pointer),
560 "Failed to tie property " << name << " to a pointer";
563 /* template <class V> void
564 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
565 bool useDefault = true);
567 template <class V> void
568 Tie (const string &name, int index, V (*getter)(int),
569 void (*setter)(int, V) = 0, bool useDefault = true);
571 template <class T, class V> void
572 Tie (const string &name, T * obj, V (T::*getter)() const,
573 void (T::*setter)(V) = 0, bool useDefault = true);
575 template <class T, class V> void
576 Tie (const string &name, T * obj, int index,
577 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
578 bool useDefault = true); */
581 * Tie a property to a pair of simple functions.
583 * Every time the property value is queried, the getter (if any) will
584 * be invoked; every time the property value is modified, the setter
585 * (if any) will be invoked. The getter can be 0 to make the property
586 * unreadable, and the setter can be 0 to make the property
589 * @param name The property name to tie (full path).
590 * @param getter The getter function, or 0 if the value is unreadable.
591 * @param setter The setter function, or 0 if the value is unmodifiable.
592 * @param useDefault true if the setter should be invoked with any existing
593 * property value should be; false if the old value should be
594 * discarded; defaults to true.
598 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
599 bool useDefault = true)
601 if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter),
604 "Failed to tie property " << name << " to functions";
609 * Tie a property to a pair of indexed functions.
611 * Every time the property value is queried, the getter (if any) will
612 * be invoked with the index provided; every time the property value
613 * is modified, the setter (if any) will be invoked with the index
614 * provided. The getter can be 0 to make the property unreadable, and
615 * the setter can be 0 to make the property unmodifiable.
617 * @param name The property name to tie (full path).
618 * @param index The integer argument to pass to the getter and
620 * @param getter The getter function, or 0 if the value is unreadable.
621 * @param setter The setter function, or 0 if the value is unmodifiable.
622 * @param useDefault true if the setter should be invoked with any existing
623 * property value should be; false if the old value should be
624 * discarded; defaults to true.
628 Tie (const string &name, int index, V (*getter)(int),
629 void (*setter)(int, V) = 0, bool useDefault = true)
631 if (!tie(name.c_str(),
632 SGRawValueFunctionsIndexed<V>(index,
637 "Failed to tie property " << name << " to indexed functions";
642 * Tie a property to a pair of object methods.
644 * Every time the property value is queried, the getter (if any) will
645 * be invoked; every time the property value is modified, the setter
646 * (if any) will be invoked. The getter can be 0 to make the property
647 * unreadable, and the setter can be 0 to make the property
650 * @param name The property name to tie (full path).
651 * @param obj The object whose methods should be invoked.
652 * @param getter The object's getter method, or 0 if the value is
654 * @param setter The object's setter method, or 0 if the value is
656 * @param useDefault true if the setter should be invoked with any existing
657 * property value should be; false if the old value should be
658 * discarded; defaults to true.
660 template <class T, class V>
662 Tie (const string &name, T * obj, V (T::*getter)() const,
663 void (T::*setter)(V) = 0, bool useDefault = true)
665 if (!tie(name.c_str(),
666 SGRawValueMethods<T,V>(*obj, getter, setter),
669 "Failed to tie property " << name << " to object methods";
674 * Tie a property to a pair of indexed object methods.
676 * Every time the property value is queried, the getter (if any) will
677 * be invoked with the index provided; every time the property value
678 * is modified, the setter (if any) will be invoked with the index
679 * provided. The getter can be 0 to make the property unreadable, and
680 * the setter can be 0 to make the property unmodifiable.
682 * @param name The property name to tie (full path).
683 * @param obj The object whose methods should be invoked.
684 * @param index The integer argument to pass to the getter and
686 * @param getter The getter method, or 0 if the value is unreadable.
687 * @param setter The setter method, or 0 if the value is unmodifiable.
688 * @param useDefault true if the setter should be invoked with any existing
689 * property value should be; false if the old value should be
690 * discarded; defaults to true.
692 template <class T, class V>
694 Tie (const string &name, T * obj, int index,
695 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
696 bool useDefault = true)
698 if (!tie(name.c_str(),
699 SGRawValueMethodsIndexed<T,V>(*obj,
705 "Failed to tie property " << name << " to indexed object methods";
711 #endif // FGPROPERTYMANAGER_H