X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Ffg_props.hxx;h=023d4dbbff4c1f42db65f3f935b5e01c832c7b0b;hb=3b6c2c426d8fa1b72b7563383cecbba8eb0ff018;hp=32eff25cc49c6b9d9fe8ddd3722b187f507794ba;hpb=1f4788fbb5987e56664d24c2e0898c56323f32aa;p=flightgear.git diff --git a/src/Main/fg_props.hxx b/src/Main/fg_props.hxx index 32eff25cc..023d4dbbf 100644 --- a/src/Main/fg_props.hxx +++ b/src/Main/fg_props.hxx @@ -6,34 +6,31 @@ #ifndef __FG_PROPS_HXX #define __FG_PROPS_HXX 1 -#include -#include -#include "globals.hxx" +#include + +#include +#include + +#include
- //////////////////////////////////////////////////////////////////////// // Property management. //////////////////////////////////////////////////////////////////////// +class FGProperties : public SGSubsystem +{ +public: + FGProperties (); + virtual ~FGProperties (); -/** - * Initialize the default FlightGear properties. - * - * These are mostly properties that haven't been claimed by a - * specific module yet. This function should be invoked once, - * while the program is starting (and after the global property - * tree has been created). - */ -extern void fgInitProps (); // fixme: how are they untied? - + void init (); + void bind (); + void unbind (); + void update (double dt); -/** - * Update the default FlightGear properties. - * - * This function should be invoked once in each loop to update all - * of the default properties. - */ -extern void fgUpdateProps (); +private: + simgear::TiedPropertyList _tiedProperties; +}; /** @@ -43,9 +40,11 @@ extern void fgUpdateProps (); * so that the current flight can be restored later. * * @param output The output stream to write the XML save file to. + * @param write_all If true, write all properties rather than + * just the ones flagged as archivable. * @return true if the flight was saved successfully. */ -extern bool fgSaveFlight (ostream &output); +extern bool fgSaveFlight (std::ostream &output, bool write_all = false); /** @@ -57,14 +56,39 @@ extern bool fgSaveFlight (ostream &output); * @param input The input stream to read the XML from. * @return true if the flight was restored successfully. */ -extern bool fgLoadFlight (istream &input); +extern bool fgLoadFlight (std::istream &input); +/** + * Load properties from a file. + * + * @param file The relative or absolute filename. + * @param props The property node to load the properties into. + * @param in_fg_root If true, look for the file relative to + * $FG_ROOT; otherwise, look for the file relative to the + * current working directory. + * @return true if the properties loaded successfully, false + * otherwise. + */ +extern bool fgLoadProps (const char * path, SGPropertyNode * props, + bool in_fg_root = true, int default_mode = 0); + +void setLoggingClasses (const char * c); +void setLoggingPriority (const char * p); + //////////////////////////////////////////////////////////////////////// // Convenience functions for getting property values. //////////////////////////////////////////////////////////////////////// +/** + * Get a property node. + * + * @param path The path of the node, relative to root. + * @param create true to create the node if it doesn't exist. + * @return The node, or 0 if none exists and none was created. + */ +extern SGPropertyNode * fgGetNode (const char * path, bool create = false); /** * Get a property node. @@ -73,23 +97,119 @@ extern bool fgLoadFlight (istream &input); * @param create true to create the node if it doesn't exist. * @return The node, or 0 if none exists and none was created. */ -inline SGPropertyNode * -fgGetNode (const string &path, bool create = false) +inline SGPropertyNode * fgGetNode (const std::string & path, bool create = false) { - return globals->get_props()->getNode(path, create); + return fgGetNode(path.c_str(), create ); } +/** + * Get a property node with separate index. + * + * This method separates the index from the path string, to make it + * easier to iterate through multiple components without using sprintf + * to add indices. For example, fgGetNode("foo[1]/bar", 3) will + * return the same result as fgGetNode("foo[1]/bar[3]"). + * + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + * @param create true to create the node if it doesn't exist. + * @return The node, or 0 if none exists and none was created. + */ +extern SGPropertyNode * fgGetNode (const char * path, + int index, bool create = false); + +/** + * Get a property node with separate index. + * + * This method separates the index from the path string, to make it + * easier to iterate through multiple components without using sprintf + * to add indices. For example, fgGetNode("foo[1]/bar", 3) will + * return the same result as fgGetNode("foo[1]/bar[3]"). + * + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + * @param create true to create the node if it doesn't exist. + * @return The node, or 0 if none exists and none was created. + */ +inline SGPropertyNode * fgGetNode (const std::string & path, + int index, bool create = false) +{ + return fgGetNode(path.c_str(), index, create ); +} + + +/** + * Test whether a given node exists. + * + * @param path The path of the node, relative to root. + * @return true if the node exists, false otherwise. + */ +extern bool fgHasNode (const char * path); + /** * Test whether a given node exists. * * @param path The path of the node, relative to root. * @return true if the node exists, false otherwise. */ -inline bool -fgHasNode (const string &path) +inline bool fgHasNode (const std::string & path) +{ + return fgHasNode( path.c_str() ); +} + + +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +extern void fgAddChangeListener (SGPropertyChangeListener * listener, + const char * path); + +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +inline void fgAddChangeListener (SGPropertyChangeListener * listener, + const std::string & path) { - return (fgGetNode(path, false) != 0); + fgAddChangeListener( listener, path.c_str() ); +} + + +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +extern void fgAddChangeListener (SGPropertyChangeListener * listener, + const char * path, int index); + +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +inline void fgAddChangeListener (SGPropertyChangeListener * listener, + const std::string & path, int index) +{ + fgAddChangeListener( listener, path.c_str(), index ); } @@ -107,9 +227,25 @@ fgHasNode (const string &path) * does not exist. * @return The property's value as a bool, or the default value provided. */ -inline bool fgGetBool (const string &name, bool defaultValue = false) +extern bool fgGetBool (const char * name, bool defaultValue = false); + +/** + * Get a bool value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getBoolValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a bool, or the default value provided. + */ +inline bool fgGetBool (const std::string & name, bool defaultValue = false) { - return globals->get_props()->getBoolValue(name, defaultValue); + return fgGetBool( name.c_str(), defaultValue ); } @@ -127,9 +263,25 @@ inline bool fgGetBool (const string &name, bool defaultValue = false) * does not exist. * @return The property's value as an int, or the default value provided. */ -inline int fgGetInt (const string &name, int defaultValue = 0) +extern int fgGetInt (const char * name, int defaultValue = 0); + +/** + * Get an int value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getIntValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as an int, or the default value provided. + */ +inline int fgGetInt (const std::string & name, int defaultValue = 0) { - return globals->get_props()->getIntValue(name, defaultValue); + return fgGetInt( name.c_str(), defaultValue ); } @@ -147,9 +299,25 @@ inline int fgGetInt (const string &name, int defaultValue = 0) * does not exist. * @return The property's value as a long, or the default value provided. */ -inline int fgGetLong (const string &name, long defaultValue = 0L) +extern long fgGetLong (const char * name, long defaultValue = 0L); + +/** + * Get a long value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getLongValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a long, or the default value provided. + */ +inline long fgGetLong (const std::string & name, long defaultValue = 0L) { - return globals->get_props()->getLongValue(name, defaultValue); + return fgGetLong( name.c_str(), defaultValue ); } @@ -167,9 +335,25 @@ inline int fgGetLong (const string &name, long defaultValue = 0L) * does not exist. * @return The property's value as a float, or the default value provided. */ -inline float fgGetFloat (const string &name, float defaultValue = 0.0) +extern float fgGetFloat (const char * name, float defaultValue = 0.0); + +/** + * Get a float value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getFloatValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a float, or the default value provided. + */ +inline float fgGetFloat (const std::string & name, float defaultValue = 0.0) { - return globals->get_props()->getFloatValue(name, defaultValue); + return fgGetFloat( name.c_str(), defaultValue ); } @@ -187,9 +371,25 @@ inline float fgGetFloat (const string &name, float defaultValue = 0.0) * does not exist. * @return The property's value as a double, or the default value provided. */ -inline double fgGetDouble (const string &name, double defaultValue = 0.0) +extern double fgGetDouble (const char * name, double defaultValue = 0.0); + +/** + * Get a double value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getDoubleValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a double, or the default value provided. + */ +inline double fgGetDouble (const std::string & name, double defaultValue = 0.0) { - return globals->get_props()->getDoubleValue(name, defaultValue); + return fgGetDouble( name.c_str(), defaultValue ); } @@ -207,9 +407,27 @@ inline double fgGetDouble (const string &name, double defaultValue = 0.0) * does not exist. * @return The property's value as a string, or the default value provided. */ -inline string fgGetString (const string &name, string defaultValue = "") +extern const char * fgGetString (const char * name, + const char * defaultValue = ""); + +/** + * Get a string value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getStringValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a string, or the default value provided. + */ +inline const char * fgGetString (const std::string & name, + const std::string & defaultValue = std::string("")) { - return globals->get_props()->getStringValue(name, defaultValue); + return fgGetString( name.c_str(), defaultValue.c_str() ); } @@ -226,9 +444,24 @@ inline string fgGetString (const string &name, string defaultValue = "") * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetBool (const string &name, bool val) +extern bool fgSetBool (const char * name, bool val); + +/** + * Set a bool value for a property. + * + * Assign a bool value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * BOOL; if it has a type of UNKNOWN, the type will also be set to + * BOOL; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetBool (const std::string & name, bool val) { - return globals->get_props()->setBoolValue(name, val); + return fgSetBool( name.c_str(), val ); } @@ -245,11 +478,40 @@ inline bool fgSetBool (const string &name, bool val) * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetInt (const string &name, int val) +extern bool fgSetInt (const char * name, int val); + +/** + * Set an int value for a property. + * + * Assign an int value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * INT; if it has a type of UNKNOWN, the type will also be set to + * INT; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetInt (const std::string & name, int val) { - return globals->get_props()->setIntValue(name, val); + return fgSetInt( name.c_str(), val ); } +/** + * Set a long value for a property. + * + * Assign a long value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * LONG; if it has a type of UNKNOWN, the type will also be set to + * LONG; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +extern bool fgSetLong (const char * name, long val); /** * Set a long value for a property. @@ -264,9 +526,9 @@ inline bool fgSetInt (const string &name, int val) * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetLong (const string &name, long val) +inline bool fgSetLong (const std::string & name, long val) { - return globals->get_props()->setLongValue(name, val); + return fgSetLong( name.c_str(), val ); } @@ -283,9 +545,24 @@ inline bool fgSetLong (const string &name, long val) * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetFloat (const string &name, float val) +extern bool fgSetFloat (const char * name, float val); + +/** + * Set a float value for a property. + * + * Assign a float value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * FLOAT; if it has a type of UNKNOWN, the type will also be set to + * FLOAT; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetFloat (const std::string & name, float val) { - return globals->get_props()->setFloatValue(name, val); + return fgSetFloat( name.c_str(), val ); } @@ -302,9 +579,24 @@ inline bool fgSetFloat (const string &name, float val) * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetDouble (const string &name, double val) +extern bool fgSetDouble (const char * name, double val); + +/** + * Set a double value for a property. + * + * Assign a double value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * DOUBLE; if it has a type of UNKNOWN, the type will also be set to + * DOUBLE; otherwise, the double value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetDouble (const std::string & name, double val) { - return globals->get_props()->setDoubleValue(name, val); + return fgSetDouble( name.c_str(), val ); } @@ -321,9 +613,24 @@ inline bool fgSetDouble (const string &name, double val) * @param val The new value for the property. * @return true if the assignment succeeded, false otherwise. */ -inline bool fgSetString (const string &name, const string &val) +extern bool fgSetString (const char * name, const char * val); + +/** + * Set a string value for a property. + * + * Assign a string value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * STRING; if it has a type of UNKNOWN, the type will also be set to + * STRING; otherwise, the string value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetString (const std::string & name, const std::string & val) { - return globals->get_props()->setStringValue(name, val); + return fgSetString( name.c_str(), val.c_str() ); } @@ -345,17 +652,7 @@ inline bool fgSetString (const string &name, const string &val) * @param name The property name. * @param state The state of the archive attribute (defaults to true). */ -inline void -fgSetArchivable (const string &name, bool state = true) -{ - SGPropertyNode * node = globals->get_props()->getNode(name); - if (node == 0) - SG_LOG(SG_GENERAL, SG_ALERT, - "Attempt to set archive flag for non-existant property " - << name); - else - node->setAttribute(SGPropertyNode::ARCHIVE, state); -} +extern void fgSetArchivable (const char * name, bool state = true); /** @@ -370,17 +667,7 @@ fgSetArchivable (const string &name, bool state = true) * @param name The property name. * @param state The state of the read attribute (defaults to true). */ -inline void -fgSetReadable (const string &name, bool state = true) -{ - SGPropertyNode * node = globals->get_props()->getNode(name); - if (node == 0) - SG_LOG(SG_GENERAL, SG_ALERT, - "Attempt to set read flag for non-existant property " - << name); - else - node->setAttribute(SGPropertyNode::READ, state); -} +extern void fgSetReadable (const char * name, bool state = true); /** @@ -395,17 +682,7 @@ fgSetReadable (const string &name, bool state = true) * @param name The property name. * @param state The state of the write attribute (defaults to true). */ -inline void -fgSetWritable (const string &name, bool state = true) -{ - SGPropertyNode * node = globals->get_props()->getNode(name); - if (node == 0) - SG_LOG(SG_GENERAL, SG_ALERT, - "Attempt to set write flag for non-existant property " - << name); - else - node->setAttribute(SGPropertyNode::WRITE, state); -} +extern void fgSetWritable (const char * name, bool state = true); @@ -420,146 +697,7 @@ fgSetWritable (const string &name, bool state = true) * Classes should use this function to release control of any * properties they are managing. */ -inline void -fgUntie (const string &name) -{ - if (!globals->get_props()->untie(name)) - SG_LOG(SG_GENERAL, SG_WARN, "Failed to untie property " << name); -} - - - // Templates cause ambiguity here - -/** - * Tie a property to an external bool variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, bool *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} - - -/** - * Tie a property to an external int variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, int *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} - - -/** - * Tie a property to an external long variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, long *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} - - -/** - * Tie a property to an external float variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, float *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} - - -/** - * Tie a property to an external double variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, double *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} - - -/** - * Tie a property to an external string variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ -inline void -fgTie (const string &name, string *pointer, bool useDefault = true) -{ - if (!globals->get_props()->tie(name, SGRawValuePointer(pointer), - useDefault)) - SG_LOG(SG_GENERAL, SG_WARN, - "Failed to tie property " << name << " to a pointer"); -} +extern void fgUntie (const char * name); /** @@ -580,7 +718,7 @@ fgTie (const string &name, string *pointer, bool useDefault = true) */ template inline void -fgTie (const string &name, V (*getter)(), void (*setter)(V) = 0, +fgTie (const char * name, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true) { if (!globals->get_props()->tie(name, SGRawValueFunctions(getter, setter), @@ -610,7 +748,7 @@ fgTie (const string &name, V (*getter)(), void (*setter)(V) = 0, */ template inline void -fgTie (const string &name, int index, V (*getter)(int), +fgTie (const char * name, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) { if (!globals->get_props()->tie(name, @@ -644,7 +782,7 @@ fgTie (const string &name, int index, V (*getter)(int), */ template inline void -fgTie (const string &name, T * obj, V (T::*getter)() const, +fgTie (const char * name, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) { if (!globals->get_props()->tie(name, @@ -676,7 +814,7 @@ fgTie (const string &name, T * obj, V (T::*getter)() const, */ template inline void -fgTie (const string &name, T * obj, int index, +fgTie (const char * name, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) { @@ -691,162 +829,18 @@ fgTie (const string &name, T * obj, int index, } - -//////////////////////////////////////////////////////////////////////// -// Conditions. -//////////////////////////////////////////////////////////////////////// - - -/** - * An encoded condition. - * - * This class encodes a single condition of some sort, possibly - * connected with properties. - * - * This class should migrate to somewhere more general. - */ -class FGCondition -{ -public: - FGCondition (); - virtual ~FGCondition (); - virtual bool test () const = 0; -}; - - -/** - * Condition for a single property. - * - * This condition is true only if the property returns a boolean - * true value. - */ -class FGPropertyCondition : public FGCondition -{ +class FGMakeUpperCase : public SGPropertyChangeListener { public: - FGPropertyCondition (const string &propname); - virtual ~FGPropertyCondition (); - virtual bool test () const { return _node->getBoolValue(); } -private: - const SGPropertyNode * _node; + void valueChanged(SGPropertyNode *node) { + if (node->getType() != simgear::props::STRING) + return; + + char *s = const_cast(node->getStringValue()); + for (; *s; s++) + *s = toupper(*s); + } }; -/** - * Condition for a 'not' operator. - * - * This condition is true only if the child condition is false. - */ -class FGNotCondition : public FGCondition -{ -public: - // transfer pointer ownership - FGNotCondition (FGCondition * condition); - virtual ~FGNotCondition (); - virtual bool test () const; -private: - FGCondition * _condition; -}; - - -/** - * Condition for an 'and' group. - * - * This condition is true only if all of the conditions - * in the group are true. - */ -class FGAndCondition : public FGCondition -{ -public: - FGAndCondition (); - virtual ~FGAndCondition (); - virtual bool test () const; - // transfer pointer ownership - virtual void addCondition (FGCondition * condition); -private: - vector _conditions; -}; - - -/** - * Condition for an 'or' group. - * - * This condition is true if at least one of the conditions in the - * group is true. - */ -class FGOrCondition : public FGCondition -{ -public: - FGOrCondition (); - virtual ~FGOrCondition (); - virtual bool test () const; - // transfer pointer ownership - virtual void addCondition (FGCondition * condition); -private: - vector _conditions; -}; - - -/** - * Abstract base class for property comparison conditions. - */ -class FGComparisonCondition : public FGCondition -{ -public: - enum Type { - LESS_THAN, - GREATER_THAN, - EQUALS - }; - FGComparisonCondition (Type type, bool reverse = false); - virtual ~FGComparisonCondition (); - virtual bool test () const; - virtual void setLeftProperty (const string &propname); - virtual void setRightProperty (const string &propname); - // will make a local copy - virtual void setRightValue (const SGPropertyNode * value); -private: - Type _type; - bool _reverse; - const SGPropertyNode * _left_property; - const SGPropertyNode * _right_property; - const SGPropertyNode * _right_value; -}; - - -/** - * Base class for a conditional components. - * - * This class manages the conditions and tests; the component should - * invoke the test() method whenever it needs to decide whether to - * active itself, draw itself, and so on. - */ -class FGConditional -{ -public: - FGConditional (); - virtual ~FGConditional (); - // transfer pointer ownership - virtual void setCondition (FGCondition * condition); - virtual const FGCondition * getCondition () const { return _condition; } - virtual bool test () const; -private: - FGCondition * _condition; -}; - - -/** - * Global function to make a condition out of properties. - * - * The top-level is always an implicit 'and' group, whatever the - * node's name (it should usually be "condition"). - * - * @param node The top-level condition node (usually named "condition"). - * @return A pointer to a newly-allocated condition; it is the - * responsibility of the caller to delete the condition when - * it is no longer needed. - */ -FGCondition * fgReadCondition (const SGPropertyNode * node); - - #endif // __FG_PROPS_HXX