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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 # include <simgear/props/props.hxx>
43 # include "simgear/props/props.hxx"
46 #include "FGJSBBase.h"
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
52 #define ID_PROPERTYMANAGER "$Id$"
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
66 /** Class wrapper for property handling.
67 @author David Megginson, Tony Peden
70 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
74 class FGPropertyManager : public SGPropertyNode, public FGJSBBase
77 static bool suppress_warning;
80 FGPropertyManager(void) {suppress_warning = false;}
82 virtual ~FGPropertyManager(void) {}
84 /** Property-ify a name
85 * replaces spaces with '-' and, optionally, makes name all lower case
86 * @param name string to change
87 * @param lowercase true to change all upper case chars to lower
88 * NOTE: this function changes its argument and thus relies
91 string mkPropertyName(string name, bool lowercase);
94 * Get a property node.
96 * @param path The path of the node, relative to root.
97 * @param create true to create the node if it doesn't exist.
98 * @return The node, or 0 if none exists and none was created.
101 GetNode (const string &path, bool create = false);
104 GetNode (const string &relpath, int index, bool create = false);
107 * Test whether a given node exists.
109 * @param path The path of the node, relative to root.
110 * @return true if the node exists, false otherwise.
112 bool HasNode (const string &path);
115 * Get the name of a node
117 string GetName( void );
120 * Get the name of a node without underscores, etc.
122 string GetPrintableName( void );
125 * Get the fully qualified name of a node
126 * This function is very slow, so is probably useful for debugging only.
128 string GetFullyQualifiedName(void);
131 * Get a bool value for a property.
133 * This method is convenient but inefficient. It should be used
134 * infrequently (i.e. for initializing, loading, saving, etc.),
135 * not in the main loop. If you need to get a value frequently,
136 * it is better to look up the node itself using GetNode and then
137 * use the node's getBoolValue() method, to avoid the lookup overhead.
139 * @param name The property name.
140 * @param defaultValue The default value to return if the property
142 * @return The property's value as a bool, or the default value provided.
144 bool GetBool (const string &name, bool defaultValue = false);
148 * Get an int value for a property.
150 * This method is convenient but inefficient. It should be used
151 * infrequently (i.e. for initializing, loading, saving, etc.),
152 * not in the main loop. If you need to get a value frequently,
153 * it is better to look up the node itself using GetNode and then
154 * use the node's getIntValue() method, to avoid the lookup overhead.
156 * @param name The property name.
157 * @param defaultValue The default value to return if the property
159 * @return The property's value as an int, or the default value provided.
161 int GetInt (const string &name, int defaultValue = 0);
165 * Get a long value for a property.
167 * This method is convenient but inefficient. It should be used
168 * infrequently (i.e. for initializing, loading, saving, etc.),
169 * not in the main loop. If you need to get a value frequently,
170 * it is better to look up the node itself using GetNode and then
171 * use the node's getLongValue() method, to avoid the lookup overhead.
173 * @param name The property name.
174 * @param defaultValue The default value to return if the property
176 * @return The property's value as a long, or the default value provided.
178 int GetLong (const string &name, long defaultValue = 0L);
182 * Get a float value for a property.
184 * This method is convenient but inefficient. It should be used
185 * infrequently (i.e. for initializing, loading, saving, etc.),
186 * not in the main loop. If you need to get a value frequently,
187 * it is better to look up the node itself using GetNode and then
188 * use the node's getFloatValue() method, to avoid the lookup overhead.
190 * @param name The property name.
191 * @param defaultValue The default value to return if the property
193 * @return The property's value as a float, or the default value provided.
195 float GetFloat (const string &name, float defaultValue = 0.0);
199 * Get a double value for a property.
201 * This method is convenient but inefficient. It should be used
202 * infrequently (i.e. for initializing, loading, saving, etc.),
203 * not in the main loop. If you need to get a value frequently,
204 * it is better to look up the node itself using GetNode and then
205 * use the node's getDoubleValue() method, to avoid the lookup overhead.
207 * @param name The property name.
208 * @param defaultValue The default value to return if the property
210 * @return The property's value as a double, or the default value provided.
212 double GetDouble (const string &name, double defaultValue = 0.0);
216 * Get a string value for a property.
218 * This method is convenient but inefficient. It should be used
219 * infrequently (i.e. for initializing, loading, saving, etc.),
220 * not in the main loop. If you need to get a value frequently,
221 * it is better to look up the node itself using GetNode and then
222 * use the node's getStringValue() method, to avoid the lookup overhead.
224 * @param name The property name.
225 * @param defaultValue The default value to return if the property
227 * @return The property's value as a string, or the default value provided.
229 string GetString (const string &name, string defaultValue = "");
233 * Set a bool value for a property.
235 * Assign a bool value to a property. If the property does not
236 * yet exist, it will be created and its type will be set to
237 * BOOL; if it has a type of UNKNOWN, the type will also be set to
238 * BOOL; otherwise, the bool value will be converted to the property's
241 * @param name The property name.
242 * @param val The new value for the property.
243 * @return true if the assignment succeeded, false otherwise.
245 bool SetBool (const string &name, bool val);
249 * Set an int value for a property.
251 * Assign an int value to a property. If the property does not
252 * yet exist, it will be created and its type will be set to
253 * INT; if it has a type of UNKNOWN, the type will also be set to
254 * INT; otherwise, the bool value will be converted to the property's
257 * @param name The property name.
258 * @param val The new value for the property.
259 * @return true if the assignment succeeded, false otherwise.
261 bool SetInt (const string &name, int val);
265 * Set a long value for a property.
267 * Assign a long value to a property. If the property does not
268 * yet exist, it will be created and its type will be set to
269 * LONG; if it has a type of UNKNOWN, the type will also be set to
270 * LONG; otherwise, the bool value will be converted to the property's
273 * @param name The property name.
274 * @param val The new value for the property.
275 * @return true if the assignment succeeded, false otherwise.
277 bool SetLong (const string &name, long val);
281 * Set a float value for a property.
283 * Assign a float value to a property. If the property does not
284 * yet exist, it will be created and its type will be set to
285 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
286 * FLOAT; otherwise, the bool value will be converted to the property's
289 * @param name The property name.
290 * @param val The new value for the property.
291 * @return true if the assignment succeeded, false otherwise.
293 bool SetFloat (const string &name, float val);
297 * Set a double value for a property.
299 * Assign a double value to a property. If the property does not
300 * yet exist, it will be created and its type will be set to
301 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
302 * DOUBLE; otherwise, the double value will be converted to the property's
305 * @param name The property name.
306 * @param val The new value for the property.
307 * @return true if the assignment succeeded, false otherwise.
309 bool SetDouble (const string &name, double val);
313 * Set a string value for a property.
315 * Assign a string value to a property. If the property does not
316 * yet exist, it will be created and its type will be set to
317 * STRING; if it has a type of UNKNOWN, the type will also be set to
318 * STRING; otherwise, the string value will be converted to the property's
321 * @param name The property name.
322 * @param val The new value for the property.
323 * @return true if the assignment succeeded, false otherwise.
325 bool SetString (const string &name, const string &val);
328 ////////////////////////////////////////////////////////////////////////
329 // Convenience functions for setting property attributes.
330 ////////////////////////////////////////////////////////////////////////
334 * Set the state of the archive attribute for a property.
336 * If the archive attribute is true, the property will be written
337 * when a flight is saved; if it is false, the property will be
340 * A warning message will be printed if the property does not exist.
342 * @param name The property name.
343 * @param state The state of the archive attribute (defaults to true).
345 void SetArchivable (const string &name, bool state = true);
349 * Set the state of the read attribute for a property.
351 * If the read attribute is true, the property value will be readable;
352 * if it is false, the property value will always be the default value
355 * A warning message will be printed if the property does not exist.
357 * @param name The property name.
358 * @param state The state of the read attribute (defaults to true).
360 void SetReadable (const string &name, bool state = true);
364 * Set the state of the write attribute for a property.
366 * If the write attribute is true, the property value may be modified
367 * (depending on how it is tied); if the write attribute is false, the
368 * property value may not be modified.
370 * A warning message will be printed if the property does not exist.
372 * @param name The property name.
373 * @param state The state of the write attribute (defaults to true).
375 void SetWritable (const string &name, bool state = true);
378 ////////////////////////////////////////////////////////////////////////
379 // Convenience functions for tying properties, with logging.
380 ////////////////////////////////////////////////////////////////////////
384 * Untie a property from an external data source.
386 * Classes should use this function to release control of any
387 * properties they are managing.
389 void Untie (const string &name);
392 // Templates cause ambiguity here
395 * Tie a property to an external bool variable.
397 * The property's value will automatically mirror the variable's
398 * value, and vice-versa, until the property is untied.
400 * @param name The property name to tie (full path).
401 * @param pointer A pointer to the variable.
402 * @param useDefault true if any existing property value should be
403 * copied to the variable; false if the variable should not
404 * be modified; defaults to true.
407 Tie (const string &name, bool *pointer, bool useDefault = true);
411 * Tie a property to an external int variable.
413 * The property's value will automatically mirror the variable's
414 * value, and vice-versa, until the property is untied.
416 * @param name The property name to tie (full path).
417 * @param pointer A pointer to the variable.
418 * @param useDefault true if any existing property value should be
419 * copied to the variable; false if the variable should not
420 * be modified; defaults to true.
423 Tie (const string &name, int *pointer, bool useDefault = true);
427 * Tie a property to an external long variable.
429 * The property's value will automatically mirror the variable's
430 * value, and vice-versa, until the property is untied.
432 * @param name The property name to tie (full path).
433 * @param pointer A pointer to the variable.
434 * @param useDefault true if any existing property value should be
435 * copied to the variable; false if the variable should not
436 * be modified; defaults to true.
439 Tie (const string &name, long *pointer, bool useDefault = true);
443 * Tie a property to an external float 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, float *pointer, bool useDefault = true);
458 * Tie a property to an external double variable.
460 * The property's value will automatically mirror the variable's
461 * value, and vice-versa, until the property is untied.
463 * @param name The property name to tie (full path).
464 * @param pointer A pointer to the variable.
465 * @param useDefault true if any existing property value should be
466 * copied to the variable; false if the variable should not
467 * be modified; defaults to true.
470 Tie (const string &name, double *pointer, bool useDefault = true);
472 //============================================================================
474 // All of the following functions *must* be inlined, otherwise linker
475 // errors will result
477 //============================================================================
479 /* template <class V> void
480 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0,
481 bool useDefault = true);
483 template <class V> void
484 Tie (const string &name, int index, V (*getter)(int),
485 void (*setter)(int, V) = 0, bool useDefault = true);
487 template <class T, class V> void
488 Tie (const string &name, T * obj, V (T::*getter)() const,
489 void (T::*setter)(V) = 0, bool useDefault = true);
491 template <class T, class V> void
492 Tie (const string &name, T * obj, int index,
493 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
494 bool useDefault = true); */
497 * Tie a property to a pair of simple functions.
499 * Every time the property value is queried, the getter (if any) will
500 * be invoked; every time the property value is modified, the setter
501 * (if any) will be invoked. The getter can be 0 to make the property
502 * unreadable, and the setter can be 0 to make the property
505 * @param name The property name to tie (full path).
506 * @param getter The getter function, or 0 if the value is unreadable.
507 * @param setter The setter function, or 0 if the value is unmodifiable.
508 * @param useDefault true if the setter should be invoked with any existing
509 * property value should be; false if the old value should be
510 * discarded; defaults to true.
513 template <class V> inline void
514 Tie (const string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
516 if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
517 cout << "Failed to tie property " << name << " to functions" << endl;
518 else if (debug_lvl & 0x20)
519 cout << name << endl;
524 * Tie a property to a pair of indexed functions.
526 * Every time the property value is queried, the getter (if any) will
527 * be invoked with the index provided; every time the property value
528 * is modified, the setter (if any) will be invoked with the index
529 * provided. The getter can be 0 to make the property unreadable, and
530 * the setter can be 0 to make the property unmodifiable.
532 * @param name The property name to tie (full path).
533 * @param index The integer argument to pass to the getter and
535 * @param getter The getter function, or 0 if the value is unreadable.
536 * @param setter The setter function, or 0 if the value is unmodifiable.
537 * @param useDefault true if the setter should be invoked with any existing
538 * property value should there be one; false if the old value should be
539 * discarded; defaults to true.
541 template <class V> inline void Tie (const string &name, int index, V (*getter)(int),
542 void (*setter)(int, V) = 0, bool useDefault = true)
544 if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
545 cout << "Failed to tie property " << name << " to indexed functions" << endl;
546 else if (debug_lvl & 0x20)
547 cout << name << endl;
552 * Tie a property to a pair of object methods.
554 * Every time the property value is queried, the getter (if any) will
555 * be invoked; every time the property value is modified, the setter
556 * (if any) will be invoked. The getter can be 0 to make the property
557 * unreadable, and the setter can be 0 to make the property
560 * @param name The property name to tie (full path).
561 * @param obj The object whose methods should be invoked.
562 * @param getter The object's getter method, or 0 if the value is
564 * @param setter The object's setter method, or 0 if the value is
566 * @param useDefault true if the setter should be invoked with any existing
567 * property value should there be one; false if the old value should be
568 * discarded; defaults to true.
570 template <class T, class V> inline void
571 Tie (const string &name, T * obj, V (T::*getter)() const,
572 void (T::*setter)(V) = 0, bool useDefault = true)
574 if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
575 cout << "Failed to tie property " << name << " to object methods" << endl;
576 else if (debug_lvl & 0x20)
577 cout << name << endl;
581 * Tie a property to a pair of indexed object methods.
583 * Every time the property value is queried, the getter (if any) will
584 * be invoked with the index provided; every time the property value
585 * is modified, the setter (if any) will be invoked with the index
586 * provided. The getter can be 0 to make the property unreadable, and
587 * the setter can be 0 to make the property unmodifiable.
589 * @param name The property name to tie (full path).
590 * @param obj The object whose methods should be invoked.
591 * @param index The integer argument to pass to the getter and
593 * @param getter The getter method, or 0 if the value is unreadable.
594 * @param setter The setter method, or 0 if the value is unmodifiable.
595 * @param useDefault true if the setter should be invoked with any existing
596 * property value should be; false if the old value should be
597 * discarded; defaults to true.
599 template <class T, class V> inline void
600 Tie (const string &name, T * obj, int index, V (T::*getter)(int) const,
601 void (T::*setter)(int, V) = 0, bool useDefault = true)
603 if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
604 cout << "Failed to tie property " << name << " to indexed object methods" << endl;
605 else if (debug_lvl & 0x20)
606 cout << name << endl;
610 #endif // FGPROPERTYMANAGER_H