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 Lesser 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 Lesser General Public License for more
20 You should have received a copy of the GNU Lesser General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 Place - Suite 330, Boston, MA 02111-1307, USA.
24 Further information about the GNU Lesser General Public License can also be found on
25 the world wide web at http://www.gnu.org.
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
31 #ifndef FGPROPERTYMANAGER_H
32 #define FGPROPERTYMANAGER_H
34 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40 #include "simgear/props/props.hxx"
42 #include "FGJSBBase.h"
44 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48 #define ID_PROPERTYMANAGER "$Id$"
50 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62 /** Class wrapper for property handling.
63 @author David Megginson, Tony Peden
66 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
70 class FGPropertyManager : public SGPropertyNode, public FGJSBBase
73 static bool suppress_warning;
76 FGPropertyManager(void) {suppress_warning = false;}
78 virtual ~FGPropertyManager(void) {}
80 /** Property-ify a name
81 * replaces spaces with '-' and, optionally, makes name all lower case
82 * @param name string to change
83 * @param lowercase true to change all upper case chars to lower
84 * NOTE: this function changes its argument and thus relies
87 string mkPropertyName(string name, bool lowercase);
90 * Get a property node.
92 * @param path The path of the node, relative to root.
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.
97 GetNode (const string &path, bool create = false);
100 GetNode (const string &relpath, int index, bool create = false);
103 * Test whether a given node exists.
105 * @param path The path of the node, relative to root.
106 * @return true if the node exists, false otherwise.
108 bool HasNode (const string &path);
111 * Get the name of a node
113 string GetName( void );
116 * Get the name of a node without underscores, etc.
118 string GetPrintableName( void );
121 * Get the fully qualified name of a node
122 * This function is very slow, so is probably useful for debugging only.
124 string GetFullyQualifiedName(void);
127 * Get a bool value for a property.
129 * This method is convenient but inefficient. It should be used
130 * infrequently (i.e. for initializing, loading, saving, etc.),
131 * not in the main loop. If you need to get a value frequently,
132 * it is better to look up the node itself using GetNode and then
133 * use the node's getBoolValue() method, to avoid the lookup overhead.
135 * @param name The property name.
136 * @param defaultValue The default value to return if the property
138 * @return The property's value as a bool, or the default value provided.
140 bool GetBool (const string &name, bool defaultValue = false);
144 * Get an int value for a property.
146 * This method is convenient but inefficient. It should be used
147 * infrequently (i.e. for initializing, loading, saving, etc.),
148 * not in the main loop. If you need to get a value frequently,
149 * it is better to look up the node itself using GetNode and then
150 * use the node's getIntValue() method, to avoid the lookup overhead.
152 * @param name The property name.
153 * @param defaultValue The default value to return if the property
155 * @return The property's value as an int, or the default value provided.
157 int GetInt (const string &name, int defaultValue = 0);
161 * Get a long value for a property.
163 * This method is convenient but inefficient. It should be used
164 * infrequently (i.e. for initializing, loading, saving, etc.),
165 * not in the main loop. If you need to get a value frequently,
166 * it is better to look up the node itself using GetNode and then
167 * use the node's getLongValue() method, to avoid the lookup overhead.
169 * @param name The property name.
170 * @param defaultValue The default value to return if the property
172 * @return The property's value as a long, or the default value provided.
174 int GetLong (const string &name, long defaultValue = 0L);
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 float GetFloat (const string &name, float defaultValue = 0.0);
195 * Get a double value for a property.
197 * This method is convenient but inefficient. It should be used
198 * infrequently (i.e. for initializing, loading, saving, etc.),
199 * not in the main loop. If you need to get a value frequently,
200 * it is better to look up the node itself using GetNode and then
201 * use the node's getDoubleValue() method, to avoid the lookup overhead.
203 * @param name The property name.
204 * @param defaultValue The default value to return if the property
206 * @return The property's value as a double, or the default value provided.
208 double GetDouble (const string &name, double defaultValue = 0.0);
212 * Get a string value for a property.
214 * This method is convenient but inefficient. It should be used
215 * infrequently (i.e. for initializing, loading, saving, etc.),
216 * not in the main loop. If you need to get a value frequently,
217 * it is better to look up the node itself using GetNode and then
218 * use the node's getStringValue() method, to avoid the lookup overhead.
220 * @param name The property name.
221 * @param defaultValue The default value to return if the property
223 * @return The property's value as a string, or the default value provided.
225 string GetString (const string &name, string defaultValue = "");
229 * Set a bool value for a property.
231 * Assign a bool value to a property. If the property does not
232 * yet exist, it will be created and its type will be set to
233 * BOOL; if it has a type of UNKNOWN, the type will also be set to
234 * BOOL; otherwise, the bool value will be converted to the property's
237 * @param name The property name.
238 * @param val The new value for the property.
239 * @return true if the assignment succeeded, false otherwise.
241 bool SetBool (const string &name, bool val);
245 * Set an int value for a property.
247 * Assign an int value to a property. If the property does not
248 * yet exist, it will be created and its type will be set to
249 * INT; if it has a type of UNKNOWN, the type will also be set to
250 * INT; otherwise, the bool value will be converted to the property's
253 * @param name The property name.
254 * @param val The new value for the property.
255 * @return true if the assignment succeeded, false otherwise.
257 bool SetInt (const string &name, int val);
261 * Set a long value for a property.
263 * Assign a long value to a property. If the property does not
264 * yet exist, it will be created and its type will be set to
265 * LONG; if it has a type of UNKNOWN, the type will also be set to
266 * LONG; otherwise, the bool value will be converted to the property's
269 * @param name The property name.
270 * @param val The new value for the property.
271 * @return true if the assignment succeeded, false otherwise.
273 bool SetLong (const string &name, long val);
277 * Set a float value for a property.
279 * Assign a float value to a property. If the property does not
280 * yet exist, it will be created and its type will be set to
281 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
282 * FLOAT; otherwise, the bool 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 bool SetFloat (const string &name, float val);
293 * Set a double value for a property.
295 * Assign a double value to a property. If the property does not
296 * yet exist, it will be created and its type will be set to
297 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
298 * DOUBLE; otherwise, the double value will be converted to the property's
301 * @param name The property name.
302 * @param val The new value for the property.
303 * @return true if the assignment succeeded, false otherwise.
305 bool SetDouble (const string &name, double val);
309 * Set a string value for a property.
311 * Assign a string value to a property. If the property does not
312 * yet exist, it will be created and its type will be set to
313 * STRING; if it has a type of UNKNOWN, the type will also be set to
314 * STRING; otherwise, the string value will be converted to the property's
317 * @param name The property name.
318 * @param val The new value for the property.
319 * @return true if the assignment succeeded, false otherwise.
321 bool SetString (const string &name, const string &val);
324 ////////////////////////////////////////////////////////////////////////
325 // Convenience functions for setting property attributes.
326 ////////////////////////////////////////////////////////////////////////
330 * Set the state of the archive attribute for a property.
332 * If the archive attribute is true, the property will be written
333 * when a flight is saved; if it is false, the property will be
336 * A warning message will be printed if the property does not exist.
338 * @param name The property name.
339 * @param state The state of the archive attribute (defaults to true).
341 void SetArchivable (const string &name, bool state = true);
345 * Set the state of the read attribute for a property.
347 * If the read attribute is true, the property value will be readable;
348 * if it is false, the property value will always be the default value
351 * A warning message will be printed if the property does not exist.
353 * @param name The property name.
354 * @param state The state of the read attribute (defaults to true).
356 void SetReadable (const string &name, bool state = true);
360 * Set the state of the write attribute for a property.
362 * If the write attribute is true, the property value may be modified
363 * (depending on how it is tied); if the write attribute is false, the
364 * property value may not be modified.
366 * A warning message will be printed if the property does not exist.
368 * @param name The property name.
369 * @param state The state of the write attribute (defaults to true).
371 void SetWritable (const string &name, bool state = true);
374 ////////////////////////////////////////////////////////////////////////
375 // Convenience functions for tying properties, with logging.
376 ////////////////////////////////////////////////////////////////////////
380 * Untie a property from an external data source.
382 * Classes should use this function to release control of any
383 * properties they are managing.
385 void Untie (const string &name);
388 // Templates cause ambiguity here
391 * Tie a property to an external bool variable.
393 * The property's value will automatically mirror the variable's
394 * value, and vice-versa, until the property is untied.
396 * @param name The property name to tie (full path).
397 * @param pointer A pointer to the variable.
398 * @param useDefault true if any existing property value should be
399 * copied to the variable; false if the variable should not
400 * be modified; defaults to true.
403 Tie (const string &name, bool *pointer, bool useDefault = true);
407 * Tie a property to an external int variable.
409 * The property's value will automatically mirror the variable's
410 * value, and vice-versa, until the property is untied.
412 * @param name The property name to tie (full path).
413 * @param pointer A pointer to the variable.
414 * @param useDefault true if any existing property value should be
415 * copied to the variable; false if the variable should not
416 * be modified; defaults to true.
419 Tie (const string &name, int *pointer, bool useDefault = true);
423 * Tie a property to an external long variable.
425 * The property's value will automatically mirror the variable's
426 * value, and vice-versa, until the property is untied.
428 * @param name The property name to tie (full path).
429 * @param pointer A pointer to the variable.
430 * @param useDefault true if any existing property value should be
431 * copied to the variable; false if the variable should not
432 * be modified; defaults to true.
435 Tie (const string &name, long *pointer, bool useDefault = true);
439 * Tie a property to an external float variable.
441 * The property's value will automatically mirror the variable's
442 * value, and vice-versa, until the property is untied.
444 * @param name The property name to tie (full path).
445 * @param pointer A pointer to the variable.
446 * @param useDefault true if any existing property value should be
447 * copied to the variable; false if the variable should not
448 * be modified; defaults to true.
451 Tie (const string &name, float *pointer, bool useDefault = true);
454 * Tie a property to an external double variable.
456 * The property's value will automatically mirror the variable's
457 * value, and vice-versa, until the property is untied.
459 * @param name The property name to tie (full path).
460 * @param pointer A pointer to the variable.
461 * @param useDefault true if any existing property value should be
462 * copied to the variable; false if the variable should not
463 * be modified; defaults to true.
466 Tie (const string &name, double *pointer, bool useDefault = true);
468 //============================================================================
470 // All of the following functions *must* be inlined, otherwise linker
471 // errors will result
473 //============================================================================
475 /* template <class V> void
476 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
477 bool useDefault = true);
479 template <class V> void
480 Tie (const string &name, int index, V (*getter)(int),
481 void (*setter)(int, V) = 0, bool useDefault = true);
483 template <class T, class V> void
484 Tie (const string &name, T * obj, V (T::*getter)() const,
485 void (T::*setter)(V) = 0, bool useDefault = true);
487 template <class T, class V> void
488 Tie (const string &name, T * obj, int index,
489 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
490 bool useDefault = true); */
493 * Tie a property to a pair of simple functions.
495 * Every time the property value is queried, the getter (if any) will
496 * be invoked; every time the property value is modified, the setter
497 * (if any) will be invoked. The getter can be 0 to make the property
498 * unreadable, and the setter can be 0 to make the property
501 * @param name The property name to tie (full path).
502 * @param getter The getter function, or 0 if the value is unreadable.
503 * @param setter The setter function, or 0 if the value is unmodifiable.
504 * @param useDefault true if the setter should be invoked with any existing
505 * property value should be; false if the old value should be
506 * discarded; defaults to true.
509 template <class V> inline void
510 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
512 if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
513 cout << "Failed to tie property " << name << " to functions" << endl;
514 else if (debug_lvl & 0x20)
515 cout << name << endl;
520 * Tie a property to a pair of indexed functions.
522 * Every time the property value is queried, the getter (if any) will
523 * be invoked with the index provided; every time the property value
524 * is modified, the setter (if any) will be invoked with the index
525 * provided. The getter can be 0 to make the property unreadable, and
526 * the setter can be 0 to make the property unmodifiable.
528 * @param name The property name to tie (full path).
529 * @param index The integer argument to pass to the getter and
531 * @param getter The getter function, or 0 if the value is unreadable.
532 * @param setter The setter function, or 0 if the value is unmodifiable.
533 * @param useDefault true if the setter should be invoked with any existing
534 * property value should there be one; false if the old value should be
535 * discarded; defaults to true.
537 template <class V> inline void Tie (const string &name, int index, V (*getter)(int),
538 void (*setter)(int, V) = 0, bool useDefault = true)
540 if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
541 cout << "Failed to tie property " << name << " to indexed functions" << endl;
542 else if (debug_lvl & 0x20)
543 cout << name << endl;
548 * Tie a property to a pair of object methods.
550 * Every time the property value is queried, the getter (if any) will
551 * be invoked; every time the property value is modified, the setter
552 * (if any) will be invoked. The getter can be 0 to make the property
553 * unreadable, and the setter can be 0 to make the property
556 * @param name The property name to tie (full path).
557 * @param obj The object whose methods should be invoked.
558 * @param getter The object's getter method, or 0 if the value is
560 * @param setter The object's setter method, or 0 if the value is
562 * @param useDefault true if the setter should be invoked with any existing
563 * property value should there be one; false if the old value should be
564 * discarded; defaults to true.
566 template <class T, class V> inline void
567 Tie (const string &name, T * obj, V (T::*getter)() const,
568 void (T::*setter)(V) = 0, bool useDefault = true)
570 if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
571 cout << "Failed to tie property " << name << " to object methods" << endl;
572 else if (debug_lvl & 0x20)
573 cout << name << endl;
577 * Tie a property to a pair of indexed object methods.
579 * Every time the property value is queried, the getter (if any) will
580 * be invoked with the index provided; every time the property value
581 * is modified, the setter (if any) will be invoked with the index
582 * provided. The getter can be 0 to make the property unreadable, and
583 * the setter can be 0 to make the property unmodifiable.
585 * @param name The property name to tie (full path).
586 * @param obj The object whose methods should be invoked.
587 * @param index The integer argument to pass to the getter and
589 * @param getter The getter method, or 0 if the value is unreadable.
590 * @param setter The setter method, or 0 if the value is unmodifiable.
591 * @param useDefault true if the setter should be invoked with any existing
592 * property value should be; false if the old value should be
593 * discarded; defaults to true.
595 template <class T, class V> inline void
596 Tie (const string &name, T * obj, int index, V (T::*getter)(int) const,
597 void (T::*setter)(int, V) = 0, bool useDefault = true)
599 if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
600 cout << "Failed to tie property " << name << " to indexed object methods" << endl;
601 else if (debug_lvl & 0x20)
602 cout << name << endl;
606 #endif // FGPROPERTYMANAGER_H