2001-07-12 23:36:04 +00:00
|
|
|
|
// fg_props.hxx - Declarations and inline methods for property handling.
|
|
|
|
|
// Written by David Megginson, started 2000.
|
|
|
|
|
//
|
|
|
|
|
// This file is in the Public Domain, and comes with no warranty.
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
#ifndef __FG_PROPS_HXX
|
|
|
|
|
#define __FG_PROPS_HXX 1
|
|
|
|
|
|
|
|
|
|
#include <simgear/debug/logstream.hxx>
|
|
|
|
|
#include <simgear/misc/props.hxx>
|
2002-03-16 00:18:38 +00:00
|
|
|
|
#include <simgear/misc/props_io.hxx>
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
#include "globals.hxx"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
2001-06-05 22:13:26 +00:00
|
|
|
|
// Property management.
|
2001-01-05 17:37:59 +00:00
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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).
|
|
|
|
|
*/
|
2001-06-05 22:13:26 +00:00
|
|
|
|
extern void fgInitProps (); // fixme: how are they untied?
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update the default FlightGear properties.
|
|
|
|
|
*
|
|
|
|
|
* This function should be invoked once in each loop to update all
|
|
|
|
|
* of the default properties.
|
|
|
|
|
*/
|
2001-06-05 22:13:26 +00:00
|
|
|
|
extern void fgUpdateProps ();
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Save a flight to disk.
|
|
|
|
|
*
|
|
|
|
|
* This function saves all of the archivable properties to a stream
|
|
|
|
|
* so that the current flight can be restored later.
|
|
|
|
|
*
|
|
|
|
|
* @param output The output stream to write the XML save file to.
|
2002-03-03 22:48:40 +00:00
|
|
|
|
* @param write_all If true, write all properties rather than
|
|
|
|
|
* just the ones flagged as archivable.
|
2001-07-12 23:36:04 +00:00
|
|
|
|
* @return true if the flight was saved successfully.
|
|
|
|
|
*/
|
2002-03-03 22:48:40 +00:00
|
|
|
|
extern bool fgSaveFlight (ostream &output, bool write_all = false);
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Load a flight from disk.
|
|
|
|
|
*
|
|
|
|
|
* This function loads an XML save file from a stream to restore
|
|
|
|
|
* a flight.
|
|
|
|
|
*
|
|
|
|
|
* @param input The input stream to read the XML from.
|
|
|
|
|
* @return true if the flight was restored successfully.
|
|
|
|
|
*/
|
2001-01-05 17:37:59 +00:00
|
|
|
|
extern bool fgLoadFlight (istream &input);
|
|
|
|
|
|
|
|
|
|
|
2002-11-06 18:57:31 +00:00
|
|
|
|
/**
|
|
|
|
|
* Load properties from a file relative to $FG_ROOT.
|
|
|
|
|
*
|
|
|
|
|
* @param file The file name relative to $FG_ROOT.
|
|
|
|
|
*/
|
|
|
|
|
extern void fgLoadProps (const char * path, SGPropertyNode * props);
|
|
|
|
|
|
|
|
|
|
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Convenience functions for getting property values.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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.
|
2001-06-12 16:25:36 +00:00
|
|
|
|
* @return The node, or 0 if none exists and none was created.
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern SGPropertyNode * fgGetNode (const char * path, bool create = false);
|
I'm attaching diffs to add a new FGInput module to FlightGear
(src/Input). So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.
The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance). I have not managed to move all keybindings into this file
yet, but I've made a good start. I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.
This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.
Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.
2001-05-23 23:01:15 +00:00
|
|
|
|
|
|
|
|
|
|
2002-01-19 05:34:03 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern SGPropertyNode * fgGetNode (const char * path,
|
|
|
|
|
int index, bool create = false);
|
2002-01-19 05:34:03 +00:00
|
|
|
|
|
|
|
|
|
|
2001-01-13 22:06:39 +00:00
|
|
|
|
/**
|
2001-06-12 16:25:36 +00:00
|
|
|
|
* Test whether a given node exists.
|
2001-01-13 22:06:39 +00:00
|
|
|
|
*
|
2001-06-12 16:25:36 +00:00
|
|
|
|
* @param path The path of the node, relative to root.
|
|
|
|
|
* @return true if the node exists, false otherwise.
|
2001-01-13 22:06:39 +00:00
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgHasNode (const char * path);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
|
|
|
|
|
2002-06-18 03:27:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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).
|
|
|
|
|
*/
|
|
|
|
|
extern void fgAddChangeListener (SGPropertyChangeListener * listener,
|
|
|
|
|
const char * path, int index);
|
|
|
|
|
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgGetBool (const char * name, bool defaultValue = false);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern int fgGetInt (const char * name, int defaultValue = 0);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern int fgGetLong (const char * name, long defaultValue = 0L);
|
2001-03-29 03:49:02 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern float fgGetFloat (const char * name, float defaultValue = 0.0);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern double fgGetDouble (const char * name, double defaultValue = 0.0);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern const char * fgGetString (const char * name,
|
|
|
|
|
const char * defaultValue = "");
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetBool (const char * name, bool val);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetInt (const char * name, int val);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetLong (const char * name, long val);
|
2001-03-29 03:49:02 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetFloat (const char * name, float val);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetDouble (const char * name, double val);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern bool fgSetString (const char * name, const char * val);
|
2001-01-13 22:06:39 +00:00
|
|
|
|
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Convenience functions for setting property attributes.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the state of the archive attribute for a property.
|
|
|
|
|
*
|
|
|
|
|
* If the archive attribute is true, the property will be written
|
|
|
|
|
* when a flight is saved; if it is false, the property will be
|
|
|
|
|
* skipped.
|
|
|
|
|
*
|
|
|
|
|
* A warning message will be printed if the property does not exist.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name.
|
|
|
|
|
* @param state The state of the archive attribute (defaults to true).
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern void fgSetArchivable (const char * name, bool state = true);
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the state of the read attribute for a property.
|
|
|
|
|
*
|
|
|
|
|
* If the read attribute is true, the property value will be readable;
|
|
|
|
|
* if it is false, the property value will always be the default value
|
|
|
|
|
* for its type.
|
|
|
|
|
*
|
|
|
|
|
* A warning message will be printed if the property does not exist.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name.
|
|
|
|
|
* @param state The state of the read attribute (defaults to true).
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern void fgSetReadable (const char * name, bool state = true);
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the state of the write attribute for a property.
|
|
|
|
|
*
|
|
|
|
|
* If the write attribute is true, the property value may be modified
|
|
|
|
|
* (depending on how it is tied); if the write attribute is false, the
|
|
|
|
|
* property value may not be modified.
|
|
|
|
|
*
|
|
|
|
|
* A warning message will be printed if the property does not exist.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name.
|
|
|
|
|
* @param state The state of the write attribute (defaults to true).
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern void fgSetWritable (const char * name, bool state = true);
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Convenience functions for tying properties, with logging.
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Untie a property from an external data source.
|
|
|
|
|
*
|
|
|
|
|
* Classes should use this function to release control of any
|
|
|
|
|
* properties they are managing.
|
|
|
|
|
*/
|
2002-03-19 17:12:13 +00:00
|
|
|
|
extern void fgUntie (const char * name);
|
2001-01-05 17:37:59 +00:00
|
|
|
|
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* Tie a property to a pair of simple functions.
|
|
|
|
|
*
|
|
|
|
|
* Every time the property value is queried, the getter (if any) will
|
|
|
|
|
* be invoked; every time the property value is modified, the setter
|
|
|
|
|
* (if any) will be invoked. The getter can be 0 to make the property
|
|
|
|
|
* unreadable, and the setter can be 0 to make the property
|
|
|
|
|
* unmodifiable.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name to tie (full path).
|
|
|
|
|
* @param getter The getter function, or 0 if the value is unreadable.
|
|
|
|
|
* @param setter The setter function, or 0 if the value is unmodifiable.
|
|
|
|
|
* @param useDefault true if the setter should be invoked with any existing
|
|
|
|
|
* property value should be; false if the old value should be
|
|
|
|
|
* discarded; defaults to true.
|
|
|
|
|
*/
|
2001-01-05 17:37:59 +00:00
|
|
|
|
template <class V>
|
|
|
|
|
inline void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
fgTie (const char * name, V (*getter)(), void (*setter)(V) = 0,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
bool useDefault = true)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
2001-01-19 22:57:24 +00:00
|
|
|
|
if (!globals->get_props()->tie(name, SGRawValueFunctions<V>(getter, setter),
|
|
|
|
|
useDefault))
|
2001-03-24 06:03:11 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN,
|
2001-01-05 17:37:59 +00:00
|
|
|
|
"Failed to tie property " << name << " to functions");
|
|
|
|
|
}
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tie a property to a pair of indexed functions.
|
|
|
|
|
*
|
|
|
|
|
* Every time the property value is queried, the getter (if any) will
|
|
|
|
|
* be invoked with the index provided; every time the property value
|
|
|
|
|
* is modified, the setter (if any) will be invoked with the index
|
|
|
|
|
* provided. The getter can be 0 to make the property unreadable, and
|
|
|
|
|
* the setter can be 0 to make the property unmodifiable.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name to tie (full path).
|
|
|
|
|
* @param index The integer argument to pass to the getter and
|
|
|
|
|
* setter functions.
|
|
|
|
|
* @param getter The getter function, or 0 if the value is unreadable.
|
|
|
|
|
* @param setter The setter function, or 0 if the value is unmodifiable.
|
|
|
|
|
* @param useDefault true if the setter should be invoked with any existing
|
|
|
|
|
* property value should be; false if the old value should be
|
|
|
|
|
* discarded; defaults to true.
|
|
|
|
|
*/
|
2001-01-05 17:37:59 +00:00
|
|
|
|
template <class V>
|
|
|
|
|
inline void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
fgTie (const char * name, int index, V (*getter)(int),
|
2001-01-19 22:57:24 +00:00
|
|
|
|
void (*setter)(int, V) = 0, bool useDefault = true)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
|
|
|
|
if (!globals->get_props()->tie(name,
|
|
|
|
|
SGRawValueFunctionsIndexed<V>(index,
|
|
|
|
|
getter,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
setter),
|
|
|
|
|
useDefault))
|
2001-03-24 06:03:11 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN,
|
2001-01-05 17:37:59 +00:00
|
|
|
|
"Failed to tie property " << name << " to indexed functions");
|
|
|
|
|
}
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tie a property to a pair of object methods.
|
|
|
|
|
*
|
|
|
|
|
* Every time the property value is queried, the getter (if any) will
|
|
|
|
|
* be invoked; every time the property value is modified, the setter
|
|
|
|
|
* (if any) will be invoked. The getter can be 0 to make the property
|
|
|
|
|
* unreadable, and the setter can be 0 to make the property
|
|
|
|
|
* unmodifiable.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name to tie (full path).
|
|
|
|
|
* @param obj The object whose methods should be invoked.
|
|
|
|
|
* @param getter The object's getter method, or 0 if the value is
|
|
|
|
|
* unreadable.
|
|
|
|
|
* @param setter The object's setter method, or 0 if the value is
|
|
|
|
|
* unmodifiable.
|
|
|
|
|
* @param useDefault true if the setter should be invoked with any existing
|
|
|
|
|
* property value should be; false if the old value should be
|
|
|
|
|
* discarded; defaults to true.
|
|
|
|
|
*/
|
2001-01-05 17:37:59 +00:00
|
|
|
|
template <class T, class V>
|
|
|
|
|
inline void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
fgTie (const char * name, T * obj, V (T::*getter)() const,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
void (T::*setter)(V) = 0, bool useDefault = true)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
|
|
|
|
if (!globals->get_props()->tie(name,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
SGRawValueMethods<T,V>(*obj, getter, setter),
|
|
|
|
|
useDefault))
|
2001-03-24 06:03:11 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN,
|
2001-01-05 17:37:59 +00:00
|
|
|
|
"Failed to tie property " << name << " to object methods");
|
|
|
|
|
}
|
|
|
|
|
|
2001-07-12 23:36:04 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tie a property to a pair of indexed object methods.
|
|
|
|
|
*
|
|
|
|
|
* Every time the property value is queried, the getter (if any) will
|
|
|
|
|
* be invoked with the index provided; every time the property value
|
|
|
|
|
* is modified, the setter (if any) will be invoked with the index
|
|
|
|
|
* provided. The getter can be 0 to make the property unreadable, and
|
|
|
|
|
* the setter can be 0 to make the property unmodifiable.
|
|
|
|
|
*
|
|
|
|
|
* @param name The property name to tie (full path).
|
|
|
|
|
* @param obj The object whose methods should be invoked.
|
|
|
|
|
* @param index The integer argument to pass to the getter and
|
|
|
|
|
* setter methods.
|
|
|
|
|
* @param getter The getter method, or 0 if the value is unreadable.
|
|
|
|
|
* @param setter The setter method, or 0 if the value is unmodifiable.
|
|
|
|
|
* @param useDefault true if the setter should be invoked with any existing
|
|
|
|
|
* property value should be; false if the old value should be
|
|
|
|
|
* discarded; defaults to true.
|
|
|
|
|
*/
|
2001-01-05 17:37:59 +00:00
|
|
|
|
template <class T, class V>
|
|
|
|
|
inline void
|
2002-03-19 17:12:13 +00:00
|
|
|
|
fgTie (const char * name, T * obj, int index,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
V (T::*getter)(int) const, void (T::*setter)(int, V) = 0,
|
|
|
|
|
bool useDefault = true)
|
2001-01-05 17:37:59 +00:00
|
|
|
|
{
|
|
|
|
|
if (!globals->get_props()->tie(name,
|
|
|
|
|
SGRawValueMethodsIndexed<T,V>(*obj,
|
|
|
|
|
index,
|
|
|
|
|
getter,
|
2001-01-19 22:57:24 +00:00
|
|
|
|
setter),
|
|
|
|
|
useDefault))
|
2001-03-24 06:03:11 +00:00
|
|
|
|
SG_LOG(SG_GENERAL, SG_WARN,
|
2001-01-05 17:37:59 +00:00
|
|
|
|
"Failed to tie property " << name << " to indexed object methods");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-08-03 00:19:59 +00:00
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// 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
|
|
|
|
|
{
|
|
|
|
|
public:
|
2002-03-19 17:12:13 +00:00
|
|
|
|
FGPropertyCondition (const char * propname);
|
2001-08-03 00:19:59 +00:00
|
|
|
|
virtual ~FGPropertyCondition ();
|
|
|
|
|
virtual bool test () const { return _node->getBoolValue(); }
|
|
|
|
|
private:
|
|
|
|
|
const SGPropertyNode * _node;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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<FGCondition *> _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<FGCondition *> _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;
|
2002-03-19 17:12:13 +00:00
|
|
|
|
virtual void setLeftProperty (const char * propname);
|
|
|
|
|
virtual void setRightProperty (const char * propname);
|
2001-08-03 00:19:59 +00:00
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
|
2001-01-05 17:37:59 +00:00
|
|
|
|
#endif // __FG_PROPS_HXX
|
|
|
|
|
|