-// props.hxx -- class to manage global FlightGear properties.
+// props.hxx -- declaration of SimGear Property Manager.
//
-// Copyright (C) 2000 David Megginson - david@megginson.com
+// Written by David Megginson - david@megginson.com
//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
+// This module is in the PUBLIC DOMAIN.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// See props.html for documentation [replace with URL when available].
//
// $Id$
-
#ifndef __PROPS_HXX
#define __PROPS_HXX
+#include <stdio.h>
+
#include <string>
#include <map>
+#include <iostream>
using std::string;
using std::map;
+using std::istream;
+using std::ostream;
+
+#ifdef UNKNOWN
+#pragma warn A sloppy coder has defined UNKNOWN as a macro!
+#undef UNKNOWN
+#endif
+
+#ifdef BOOL
+#pragma warn A sloppy coder has defined BOOL as a macro!
+#undef BOOL
+#endif
+
+#ifdef INT
+#pragma warn A sloppy coder has defined INT as a macro!
+#undef INT
+#endif
+
+#ifdef FLOAT
+#pragma warn A sloppy coder has defined FLOAT as a macro!
+#undef FLOAT
+#endif
+
+#ifdef DOUBLE
+#pragma warn A sloppy coder has defined DOUBLE as a macro!
+#undef DOUBLE
+#endif
+
+#ifdef STRING
+#pragma warn A sloppy coder has defined STRING as a macro!
+#undef STRING
+#endif
\f
* Values also have attributes that control whether they can be read
* from, written to, or archived (i.e. saved to disk).
*/
-class FGValue
+class SGValue
{
public:
STRING // text
};
- FGValue ();
- virtual ~FGValue ();
+ SGValue ();
+ virtual ~SGValue ();
// Meta information.
virtual Type getType () const { return _type; }
virtual int getIntValue () const;
virtual float getFloatValue () const;
virtual double getDoubleValue () const;
- virtual const string &getStringValue () const;
+ virtual const string & getStringValue () const;
// Setters.
virtual bool setBoolValue (bool value);
virtual bool setFloatValue (float value);
virtual bool setDoubleValue (double value);
virtual bool setStringValue (const string &value);
+ virtual bool setUnknownValue (const string &value);
// Tie to external variables.
virtual bool tieBool (bool_getter getter,
bool useDefault = true);
// Untie from external variables.
- virtual bool untieBool ();
- virtual bool untieInt ();
- virtual bool untieFloat ();
- virtual bool untieDouble ();
- virtual bool untieString ();
+ virtual bool untie ();
protected:
Type _type;
bool _tied;
+ mutable string string_val;
+
// The value is one of the following...
union {
int int_val;
float float_val;
double double_val;
- string * string_val;
struct {
bool_setter setter;
* A list of FlightGear properties.
*
* This list associates names (conventional written as paths,
- * i.e. "/foo/bar/hack") with FGValue classes. Once an FGValue
+ * i.e. "/foo/bar/hack") with SGValue classes. Once an SGValue
* object is associated with the name, the association is
* permanent -- it is safe to keep a pointer or reference.
* however, that the type of a value may change if it is tied
*
* When iterating through the list, the value type is
*
- * pair<string,FGValue>
+ * pair<string,SGValue>
*
* To get the name from a const_iterator, use
*
*
* it->second
*/
-class FGPropertyList
+class SGPropertyList
{
public:
- typedef map<string, FGValue> value_map;
+ typedef map<string, SGValue> value_map;
- typedef FGValue::bool_getter bool_getter;
- typedef FGValue::int_getter int_getter;
- typedef FGValue::float_getter float_getter;
- typedef FGValue::double_getter double_getter;
- typedef FGValue::string_getter string_getter;
+ typedef SGValue::bool_getter bool_getter;
+ typedef SGValue::int_getter int_getter;
+ typedef SGValue::float_getter float_getter;
+ typedef SGValue::double_getter double_getter;
+ typedef SGValue::string_getter string_getter;
- typedef FGValue::bool_setter bool_setter;
- typedef FGValue::int_setter int_setter;
- typedef FGValue::float_setter float_setter;
- typedef FGValue::double_setter double_setter;
- typedef FGValue::string_setter string_setter;
+ typedef SGValue::bool_setter bool_setter;
+ typedef SGValue::int_setter int_setter;
+ typedef SGValue::float_setter float_setter;
+ typedef SGValue::double_setter double_setter;
+ typedef SGValue::string_setter string_setter;
typedef value_map::value_type value_type;
typedef value_map::size_type size_type;
typedef value_map::const_iterator const_iterator;
- FGPropertyList ();
- virtual ~FGPropertyList ();
+ SGPropertyList ();
+ virtual ~SGPropertyList ();
virtual size_type size () const { return _props.size(); }
virtual const_iterator begin () const { return _props.begin(); }
virtual const_iterator end () const { return _props.end(); }
- virtual FGValue * getValue (const string &name, bool create = false);
- virtual const FGValue * getValue (const string &name) const;
+ virtual bool hasValue (const string &name) const;
+
+ virtual SGValue * getValue (const string &name, bool create = false);
+ virtual const SGValue * getValue (const string &name) const;
- virtual bool getBoolValue (const string &name) const;
- virtual int getIntValue (const string &name) const;
- virtual float getFloatValue (const string &name) const;
- virtual double getDoubleValue (const string &name) const;
- virtual const string &getStringValue (const string &name) const;
+ virtual bool getBoolValue (const string &name,
+ bool defaultValue = false) const;
+ virtual int getIntValue (const string &name,
+ int defaultValue = 0) const;
+ virtual float getFloatValue (const string &name,
+ float defaultValue = 0.0) const;
+ virtual double getDoubleValue (const string &name,
+ double defaultValue = 0.0L) const;
+ virtual const string & getStringValue (const string &name,
+ const string &defaultValue = "")
+ const;
virtual bool setBoolValue (const string &name, bool value);
virtual bool setIntValue (const string &name, int value);
virtual bool setFloatValue (const string &name, float value);
virtual bool setDoubleValue (const string &name, double value);
virtual bool setStringValue (const string &name, const string &value);
+ virtual bool setUnknownValue (const string &name, const string &value);
virtual bool tieBool (const string &name,
bool_getter getter,
string_setter setter = 0,
bool useDefault = true);
- virtual bool untieBool (const string &name);
- virtual bool untieInt (const string &name);
- virtual bool untieFloat (const string &name);
- virtual bool untieDouble (const string &name);
- virtual bool untieString (const string &name);
-
- virtual void dumpToLog () const;
+ virtual bool untie (const string &name);
private:
value_map _props;
};
+\f
+////////////////////////////////////////////////////////////////////////
+// Tree/node/directory view.
+////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Tree view of a property list.
+ *
+ * This class provides a virtual tree view of a property list, without
+ * actually constructing a tree -- the view always stays in sync with
+ * the property list itself.
+ *
+ * This class is designed to be used for setup and configuration; it is
+ * optimized for ease of use rather than performance, and shouldn't be
+ * used inside a tight loop.
+ *
+ * Every node is actually just a path together with a pointer to
+ * the real property list and a few convenient operations; to the
+ * user, however, it looks like a node in a tree or a file system,
+ * with the regular operations such as getChild and getParent.
+ *
+ * Note that a node may be both a branch and a leaf -- that is, it
+ * may have a value itself and it may have children. Here is a simple
+ * example that prints the names of all of the different nodes inside
+ * "/controls":
+ *
+ * SGPropertyNode controls("/controls", current_property_list);
+ * SGPropertyNode child;
+ * int size = controls.size();
+ * for (int i = 0; i < size; i++) {
+ * if (controls.getChild(child, i))
+ * cout << child.getName() << endl;
+ * else
+ * cerr << "Failed to read child " << i << endl;
+ * }
+ */
+class SGPropertyNode
+{
+public:
+ // Constructor and destructor
+ SGPropertyNode (const string &path = "", SGPropertyList * props = 0);
+ virtual ~SGPropertyNode ();
+
+ // Accessor and setter for the internal
+ // path.
+ virtual const string &getPath () const { return _path; }
+ virtual void setPath (const string &path);
+
+ // Accessor and setter for the real
+ // property list.
+ virtual SGPropertyList * getPropertyList () { return _props; }
+ virtual void setPropertyList (SGPropertyList * props) {
+ _props = props;
+ }
+
+ // Accessors for derived information.
+ virtual int size () const;
+ virtual const string &getName () const;
+ virtual SGPropertyNode &getParent () const;
+ virtual SGPropertyNode &getChild (int n) const;
+ virtual SGPropertyNode &getSubNode (const string &subpath) const;
+
+ // Check for a value.
+ virtual bool hasValue (const string &subpath = "") const;
+
+ // Get values directly.
+ virtual SGValue * getValue (const string &subpath = "");
+ virtual bool getBoolValue (const string &subpath = "",
+ bool defaultValue = false) const;
+ virtual int getIntValue (const string &subpath = "",
+ int defaultValue = 0) const;
+ virtual float getFloatValue (const string &subpath = "",
+ float defaultValue = 0.0) const;
+ virtual double getDoubleValue (const string &subpath = "",
+ double defaultValue = 0.0L) const;
+ virtual const string &
+ getStringValue (const string &subpath = "",
+ const string &defaultValue = "") const;
+
+private:
+ string _path;
+ SGPropertyList * _props;
+ // for pointer persistence...
+ // NOT THREAD SAFE!!!
+ // (each thread must have its own node
+ // object)
+ mutable string _name;
+ mutable SGPropertyNode * _node;
+};
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Input and output.
+////////////////////////////////////////////////////////////////////////
+
+extern bool readPropertyList (istream &input, SGPropertyList * props);
+extern bool readPropertyList (const string &file, SGPropertyList * props);
+extern bool writePropertyList (ostream &output, const SGPropertyList * props);
+extern bool writePropertyList (const string &file,
+ const SGPropertyList * props);
+
+
\f
////////////////////////////////////////////////////////////////////////
// Global property manager.
////////////////////////////////////////////////////////////////////////
-extern FGPropertyList current_properties;
+extern SGPropertyList current_properties;
+
+#endif // __PROPS_HXX
-#endif __PROPS_HXX
+// end of props.hxx