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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 // This is needed by MSVC9 when included in FlightGear because of
39 // the new Vec4d class in props.hxx
40 #if defined( HAVE_CONFIG_H )
45 #include "simgear/props/props.hxx"
47 # include "simgear/math/SGMath.hxx"
50 #include "FGJSBBase.h"
52 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
56 #define ID_PROPERTYMANAGER "$Id: FGPropertyManager.h,v 1.17 2010/07/08 11:36:28 jberndt Exp $"
58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68 /** Class wrapper for property handling.
69 @author David Megginson, Tony Peden
72 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
76 class FGPropertyManager : public SGPropertyNode, public FGJSBBase
79 static bool suppress_warning;
80 static std::vector<std::string> tied_properties;
83 FGPropertyManager(void) {suppress_warning = false;}
85 virtual ~FGPropertyManager(void) {}
87 /** Property-ify a name
88 * replaces spaces with '-' and, optionally, makes name all lower case
89 * @param name string to change
90 * @param lowercase true to change all upper case chars to lower
91 * NOTE: this function changes its argument and thus relies
94 std::string mkPropertyName(std::string name, bool lowercase);
97 * Get a property node.
99 * @param path The path of the node, relative to root.
100 * @param create true to create the node if it doesn't exist.
101 * @return The node, or 0 if none exists and none was created.
104 GetNode (const std::string &path, bool create = false);
107 GetNode (const std::string &relpath, int index, bool create = false);
110 * Test whether a given node exists.
112 * @param path The path of the node, relative to root.
113 * @return true if the node exists, false otherwise.
115 bool HasNode (const std::string &path);
118 * Get the name of a node
120 std::string GetName( void );
123 * Get the name of a node without underscores, etc.
125 std::string GetPrintableName( void );
128 * Get the fully qualified name of a node
129 * This function is very slow, so is probably useful for debugging only.
131 std::string GetFullyQualifiedName(void);
134 * Get the qualified name of a node relative to given base path,
135 * otherwise the fully qualified name.
136 * This function is very slow, so is probably useful for debugging only.
138 * @param path The path to strip off, if found.
140 std::string GetRelativeName( const std::string &path = "/fdm/jsbsim/" );
143 * Get a bool value for a property.
145 * This method is convenient but inefficient. It should be used
146 * infrequently (i.e. for initializing, loading, saving, etc.),
147 * not in the main loop. If you need to get a value frequently,
148 * it is better to look up the node itself using GetNode and then
149 * use the node's getBoolValue() method, to avoid the lookup overhead.
151 * @param name The property name.
152 * @param defaultValue The default value to return if the property
154 * @return The property's value as a bool, or the default value provided.
156 bool GetBool (const std::string &name, bool defaultValue = false);
160 * Get an int value for a property.
162 * This method is convenient but inefficient. It should be used
163 * infrequently (i.e. for initializing, loading, saving, etc.),
164 * not in the main loop. If you need to get a value frequently,
165 * it is better to look up the node itself using GetNode and then
166 * use the node's getIntValue() method, to avoid the lookup overhead.
168 * @param name The property name.
169 * @param defaultValue The default value to return if the property
171 * @return The property's value as an int, or the default value provided.
173 int GetInt (const std::string &name, int defaultValue = 0);
177 * Get a long value for a property.
179 * This method is convenient but inefficient. It should be used
180 * infrequently (i.e. for initializing, loading, saving, etc.),
181 * not in the main loop. If you need to get a value frequently,
182 * it is better to look up the node itself using GetNode and then
183 * use the node's getLongValue() method, to avoid the lookup overhead.
185 * @param name The property name.
186 * @param defaultValue The default value to return if the property
188 * @return The property's value as a long, or the default value provided.
190 int GetLong (const std::string &name, long defaultValue = 0L);
194 * Get a float value for a property.
196 * This method is convenient but inefficient. It should be used
197 * infrequently (i.e. for initializing, loading, saving, etc.),
198 * not in the main loop. If you need to get a value frequently,
199 * it is better to look up the node itself using GetNode and then
200 * use the node's getFloatValue() method, to avoid the lookup overhead.
202 * @param name The property name.
203 * @param defaultValue The default value to return if the property
205 * @return The property's value as a float, or the default value provided.
207 float GetFloat (const std::string &name, float defaultValue = 0.0);
211 * Get a double value for a property.
213 * This method is convenient but inefficient. It should be used
214 * infrequently (i.e. for initializing, loading, saving, etc.),
215 * not in the main loop. If you need to get a value frequently,
216 * it is better to look up the node itself using GetNode and then
217 * use the node's getDoubleValue() method, to avoid the lookup overhead.
219 * @param name The property name.
220 * @param defaultValue The default value to return if the property
222 * @return The property's value as a double, or the default value provided.
224 double GetDouble (const std::string &name, double defaultValue = 0.0);
228 * Get a string value for a property.
230 * This method is convenient but inefficient. It should be used
231 * infrequently (i.e. for initializing, loading, saving, etc.),
232 * not in the main loop. If you need to get a value frequently,
233 * it is better to look up the node itself using GetNode and then
234 * use the node's getStringValue() method, to avoid the lookup overhead.
236 * @param name The property name.
237 * @param defaultValue The default value to return if the property
239 * @return The property's value as a string, or the default value provided.
241 std::string GetString (const std::string &name, std::string defaultValue = "");
245 * Set a bool value for a property.
247 * Assign a bool value to a property. If the property does not
248 * yet exist, it will be created and its type will be set to
249 * BOOL; if it has a type of UNKNOWN, the type will also be set to
250 * BOOL; 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 SetBool (const std::string &name, bool val);
261 * Set an int value for a property.
263 * Assign an int value to a property. If the property does not
264 * yet exist, it will be created and its type will be set to
265 * INT; if it has a type of UNKNOWN, the type will also be set to
266 * INT; 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 SetInt (const std::string &name, int val);
277 * Set a long value for a property.
279 * Assign a long value to a property. If the property does not
280 * yet exist, it will be created and its type will be set to
281 * LONG; if it has a type of UNKNOWN, the type will also be set to
282 * LONG; 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 SetLong (const std::string &name, long val);
293 * Set a float value for a property.
295 * Assign a float value to a property. If the property does not
296 * yet exist, it will be created and its type will be set to
297 * FLOAT; if it has a type of UNKNOWN, the type will also be set to
298 * FLOAT; otherwise, the bool 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 SetFloat (const std::string &name, float val);
309 * Set a double value for a property.
311 * Assign a double value to a property. If the property does not
312 * yet exist, it will be created and its type will be set to
313 * DOUBLE; if it has a type of UNKNOWN, the type will also be set to
314 * DOUBLE; otherwise, the double 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 SetDouble (const std::string &name, double val);
325 * Set a string value for a property.
327 * Assign a string value to a property. If the property does not
328 * yet exist, it will be created and its type will be set to
329 * STRING; if it has a type of UNKNOWN, the type will also be set to
330 * STRING; otherwise, the string value will be converted to the property's
333 * @param name The property name.
334 * @param val The new value for the property.
335 * @return true if the assignment succeeded, false otherwise.
337 bool SetString (const std::string &name, const std::string &val);
340 ////////////////////////////////////////////////////////////////////////
341 // Convenience functions for setting property attributes.
342 ////////////////////////////////////////////////////////////////////////
346 * Set the state of the archive attribute for a property.
348 * If the archive attribute is true, the property will be written
349 * when a flight is saved; if it is false, the property will be
352 * A warning message will be printed if the property does not exist.
354 * @param name The property name.
355 * @param state The state of the archive attribute (defaults to true).
357 void SetArchivable (const std::string &name, bool state = true);
361 * Set the state of the read attribute for a property.
363 * If the read attribute is true, the property value will be readable;
364 * if it is false, the property value will always be the default value
367 * A warning message will be printed if the property does not exist.
369 * @param name The property name.
370 * @param state The state of the read attribute (defaults to true).
372 void SetReadable (const std::string &name, bool state = true);
376 * Set the state of the write attribute for a property.
378 * If the write attribute is true, the property value may be modified
379 * (depending on how it is tied); if the write attribute is false, the
380 * property value may not be modified.
382 * A warning message will be printed if the property does not exist.
384 * @param name The property name.
385 * @param state The state of the write attribute (defaults to true).
387 void SetWritable (const std::string &name, bool state = true);
390 ////////////////////////////////////////////////////////////////////////
391 // Convenience functions for tying properties, with logging.
392 ////////////////////////////////////////////////////////////////////////
396 * Untie a property from an external data source.
398 * Classes should use this function to release control of any
399 * properties they are managing.
401 void Untie (const std::string &name);
404 * Unbind all properties bound by this manager to an external data source.
406 * Classes should use this function to release control of any
407 * properties they have bound using this property manager.
411 // Templates cause ambiguity here
414 * Tie a property to an external bool variable.
416 * The property's value will automatically mirror the variable's
417 * value, and vice-versa, until the property is untied.
419 * @param name The property name to tie (full path).
420 * @param pointer A pointer to the variable.
421 * @param useDefault true if any existing property value should be
422 * copied to the variable; false if the variable should not
423 * be modified; defaults to true.
426 Tie (const std::string &name, bool *pointer, bool useDefault = true);
430 * Tie a property to an external int variable.
432 * The property's value will automatically mirror the variable's
433 * value, and vice-versa, until the property is untied.
435 * @param name The property name to tie (full path).
436 * @param pointer A pointer to the variable.
437 * @param useDefault true if any existing property value should be
438 * copied to the variable; false if the variable should not
439 * be modified; defaults to true.
442 Tie (const std::string &name, int *pointer, bool useDefault = true);
446 * Tie a property to an external long variable.
448 * The property's value will automatically mirror the variable's
449 * value, and vice-versa, until the property is untied.
451 * @param name The property name to tie (full path).
452 * @param pointer A pointer to the variable.
453 * @param useDefault true if any existing property value should be
454 * copied to the variable; false if the variable should not
455 * be modified; defaults to true.
458 Tie (const std::string &name, long *pointer, bool useDefault = true);
462 * Tie a property to an external float variable.
464 * The property's value will automatically mirror the variable's
465 * value, and vice-versa, until the property is untied.
467 * @param name The property name to tie (full path).
468 * @param pointer A pointer to the variable.
469 * @param useDefault true if any existing property value should be
470 * copied to the variable; false if the variable should not
471 * be modified; defaults to true.
474 Tie (const std::string &name, float *pointer, bool useDefault = true);
477 * Tie a property to an external double 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 std::string &name, double *pointer, bool useDefault = true);
491 //============================================================================
493 // All of the following functions *must* be inlined, otherwise linker
494 // errors will result
496 //============================================================================
498 /* template <class V> void
499 Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0,
500 bool useDefault = true);
502 template <class V> void
503 Tie (const std::string &name, int index, V (*getter)(int),
504 void (*setter)(int, V) = 0, bool useDefault = true);
506 template <class T, class V> void
507 Tie (const std::string &name, T * obj, V (T::*getter)() const,
508 void (T::*setter)(V) = 0, bool useDefault = true);
510 template <class T, class V> void
511 Tie (const std::string &name, T * obj, int index,
512 V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
513 bool useDefault = true); */
516 * Tie a property to a pair of simple functions.
518 * Every time the property value is queried, the getter (if any) will
519 * be invoked; every time the property value is modified, the setter
520 * (if any) will be invoked. The getter can be 0 to make the property
521 * unreadable, and the setter can be 0 to make the property
524 * @param name The property name to tie (full path).
525 * @param getter The getter function, or 0 if the value is unreadable.
526 * @param setter The setter function, or 0 if the value is unmodifiable.
527 * @param useDefault true if the setter should be invoked with any existing
528 * property value should be; false if the old value should be
529 * discarded; defaults to true.
532 template <class V> inline void
533 Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true)
535 if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
536 std::cout << "Failed to tie property " << name << " to functions" << std::endl;
538 tied_properties.push_back(name);
539 if (debug_lvl & 0x20) std::cout << name << std::endl;
545 * Tie a property to a pair of indexed functions.
547 * Every time the property value is queried, the getter (if any) will
548 * be invoked with the index provided; every time the property value
549 * is modified, the setter (if any) will be invoked with the index
550 * provided. The getter can be 0 to make the property unreadable, and
551 * the setter can be 0 to make the property unmodifiable.
553 * @param name The property name to tie (full path).
554 * @param index The integer argument to pass to the getter and
556 * @param getter The getter function, or 0 if the value is unreadable.
557 * @param setter The setter function, or 0 if the value is unmodifiable.
558 * @param useDefault true if the setter should be invoked with any existing
559 * property value should there be one; false if the old value should be
560 * discarded; defaults to true.
562 template <class V> inline void Tie (const std::string &name, int index, V (*getter)(int),
563 void (*setter)(int, V) = 0, bool useDefault = true)
565 if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
566 std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl;
568 tied_properties.push_back(name);
569 if (debug_lvl & 0x20) std::cout << name << std::endl;
575 * Tie a property to a pair of object methods.
577 * Every time the property value is queried, the getter (if any) will
578 * be invoked; every time the property value is modified, the setter
579 * (if any) will be invoked. The getter can be 0 to make the property
580 * unreadable, and the setter can be 0 to make the property
583 * @param name The property name to tie (full path).
584 * @param obj The object whose methods should be invoked.
585 * @param getter The object's getter method, or 0 if the value is
587 * @param setter The object's setter method, or 0 if the value is
589 * @param useDefault true if the setter should be invoked with any existing
590 * property value should there be one; false if the old value should be
591 * discarded; defaults to true.
593 template <class T, class V> inline void
594 Tie (const std::string &name, T * obj, V (T::*getter)() const,
595 void (T::*setter)(V) = 0, bool useDefault = true)
597 if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
598 std::cout << "Failed to tie property " << name << " to object methods" << std::endl;
600 tied_properties.push_back(name);
601 if (debug_lvl & 0x20) std::cout << name << std::endl;
606 * Tie a property to a pair of indexed object methods.
608 * Every time the property value is queried, the getter (if any) will
609 * be invoked with the index provided; every time the property value
610 * is modified, the setter (if any) will be invoked with the index
611 * provided. The getter can be 0 to make the property unreadable, and
612 * the setter can be 0 to make the property unmodifiable.
614 * @param name The property name to tie (full path).
615 * @param obj The object whose methods should be invoked.
616 * @param index The integer argument to pass to the getter and
618 * @param getter The getter method, or 0 if the value is unreadable.
619 * @param setter The setter method, or 0 if the value is unmodifiable.
620 * @param useDefault true if the setter should be invoked with any existing
621 * property value should be; false if the old value should be
622 * discarded; defaults to true.
624 template <class T, class V> inline void
625 Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const,
626 void (T::*setter)(int, V) = 0, bool useDefault = true)
628 if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
629 std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl;
631 tied_properties.push_back(name);
632 if (debug_lvl & 0x20) std::cout << name << std::endl;
637 #endif // FGPROPERTYMANAGER_H