]> git.mxchange.org Git - simgear.git/blob - simgear/misc/props.hxx
Updates from David Megginson.
[simgear.git] / simgear / misc / props.hxx
1 // props.hxx -- declaration of SimGear Property Manager.
2 //
3 // Written by David Megginson - david@megginson.com
4 //
5 // This module is in the PUBLIC DOMAIN.
6 //
7 // This program is distributed in the hope that it will be useful, but
8 // WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 //
11 // See props.html for documentation [replace with URL when available].
12 //
13 // $Id$
14
15 #ifndef __PROPS_HXX
16 #define __PROPS_HXX
17
18 #include <stdio.h>
19
20 #include <string>
21 #include <map>
22
23 using std::string;
24 using std::map;
25
26
27 \f
28 ////////////////////////////////////////////////////////////////////////
29 // Values.
30 ////////////////////////////////////////////////////////////////////////
31
32 /**
33  * Abstract representation of a FlightGear value.
34  *
35  * This value is designed to be fairly robust -- it can exist without
36  * a specified value, it can be any of several types, and it can
37  * be tied to an external variable without disrupting any existing
38  * pointers or references to the value.  Some basic type conversions
39  * are also handled automatically.
40  *
41  * Values also have attributes that control whether they can be read
42  * from, written to, or archived (i.e. saved to disk).
43  */
44 class FGValue
45 {
46 public:
47
48                                 // External getters
49   typedef bool (*bool_getter)();
50   typedef int (*int_getter)();
51   typedef float (*float_getter)();
52   typedef double (*double_getter)();
53   typedef const string &(*string_getter)();
54
55                                 // External setters
56   typedef void (*bool_setter)(bool);
57   typedef void (*int_setter)(int);
58   typedef void (*float_setter)(float);
59   typedef void (*double_setter)(double);
60   typedef void (*string_setter)(const string &);
61
62   enum Type {
63     UNKNOWN,                    // no value assigned yet
64     BOOL,                       // boolean
65     INT,                        // integer
66     FLOAT,                      // floating point
67     DOUBLE,                     // double precision
68     STRING                      // text
69   };
70
71   FGValue ();
72   virtual ~FGValue ();
73
74                                 // Meta information.
75   virtual Type getType () const { return _type; }
76   virtual bool isTied () const { return _tied; }
77
78                                 // Accessors.
79   virtual bool getBoolValue () const;
80   virtual int getIntValue () const;
81   virtual float getFloatValue () const;
82   virtual double getDoubleValue () const;
83   virtual const string &getStringValue () const;
84
85                                 // Setters.
86   virtual bool setBoolValue (bool value);
87   virtual bool setIntValue (int value);
88   virtual bool setFloatValue (float value);
89   virtual bool setDoubleValue (double value);
90   virtual bool setStringValue (const string &value);
91   virtual bool setUnknownValue (const string &value);
92
93                                 // Tie to external variables.
94   virtual bool tieBool (bool_getter getter,
95                         bool_setter setter = 0,
96                         bool useDefault = true);
97   virtual bool tieInt (int_getter getter,
98                        int_setter setter = 0,
99                        bool useDefault = true);
100   virtual bool tieFloat (float_getter getter,
101                          float_setter setter = 0,
102                          bool useDefault = true);
103   virtual bool tieDouble (double_getter getter,
104                           double_setter setter = 0,
105                           bool useDefault = true);
106   virtual bool tieString (string_getter getter,
107                           string_setter setter = 0,
108                           bool useDefault = true);
109
110                                 // Untie from external variables.
111   virtual bool untie ();
112
113 protected:
114
115   bool getRawBool () const;
116   int getRawInt () const;
117   float getRawFloat () const;
118   double getRawDouble () const;
119   const string &getRawString () const;
120
121   bool setRawBool (bool value);
122   bool setRawInt (int value);
123   bool setRawFloat (float value);
124   bool setRawDouble (double value);
125   bool setRawString (const string & value);
126
127 private:
128
129   Type _type;
130   bool _tied;
131
132   mutable string string_val;
133
134                                 // The value is one of the following...
135   union {
136
137     bool bool_val;
138     int int_val;
139     float float_val;
140     double double_val;
141
142     struct {
143       bool_setter setter;
144       bool_getter getter;
145     } bool_func;
146
147     struct {
148       int_setter setter;
149       int_getter getter;
150     } int_func;
151
152     struct {
153       void * obj;
154       float_setter setter;
155       float_getter getter;
156     } float_func;
157
158     struct {
159       void * obj;
160       double_setter setter;
161       double_getter getter;
162     } double_func;
163
164     struct {
165       string_setter setter;
166       string_getter getter;
167     } string_func;
168
169   } _value;
170
171 };
172
173
174 \f
175 ////////////////////////////////////////////////////////////////////////
176 // Top-level manager.
177 ////////////////////////////////////////////////////////////////////////
178
179
180 /**
181  * A list of FlightGear properties.
182  *
183  * This list associates names (conventional written as paths,
184  * i.e. "/foo/bar/hack") with FGValue classes.  Once an FGValue
185  * object is associated with the name, the association is
186  * permanent -- it is safe to keep a pointer or reference.
187  * however, that the type of a value may change if it is tied
188  * to a variable.
189  *
190  * When iterating through the list, the value type is
191  *
192  *   pair<string,FGValue>
193  *
194  * To get the name from a const_iterator, use
195  *
196  *   it->first
197  *
198  * and to get the value from a const_iterator, use
199  *
200  *   it->second
201  */
202 class FGPropertyList
203 {
204 public:
205   typedef map<string, FGValue> value_map;
206
207   typedef FGValue::bool_getter bool_getter;
208   typedef FGValue::int_getter int_getter;
209   typedef FGValue::float_getter float_getter;
210   typedef FGValue::double_getter double_getter;
211   typedef FGValue::string_getter string_getter;
212
213   typedef FGValue::bool_setter bool_setter;
214   typedef FGValue::int_setter int_setter;
215   typedef FGValue::float_setter float_setter;
216   typedef FGValue::double_setter double_setter;
217   typedef FGValue::string_setter string_setter;
218
219   typedef value_map::value_type value_type;
220   typedef value_map::size_type size_type;
221   typedef value_map::const_iterator const_iterator;
222
223   FGPropertyList ();
224   virtual ~FGPropertyList ();
225
226   virtual size_type size () const { return _props.size(); }
227
228   virtual const_iterator begin () const { return _props.begin(); }
229   virtual const_iterator end () const { return _props.end(); }
230
231   virtual FGValue * getValue (const string &name, bool create = false);
232   virtual const FGValue * getValue (const string &name) const;
233
234   virtual bool getBoolValue (const string &name) const;
235   virtual int getIntValue (const string &name) const;
236   virtual float getFloatValue (const string &name) const;
237   virtual double getDoubleValue (const string &name) const;
238   virtual const string &getStringValue (const string &name) const;
239
240   virtual bool setBoolValue (const string &name, bool value);
241   virtual bool setIntValue (const string &name, int value);
242   virtual bool setFloatValue (const string &name, float value);
243   virtual bool setDoubleValue (const string &name, double value);
244   virtual bool setStringValue (const string &name, const string &value);
245   virtual bool setUnknownValue (const string &name, const string &value);
246
247   virtual bool tieBool (const string &name,
248                         bool_getter getter,
249                         bool_setter setter = 0,
250                         bool useDefault = true);
251   virtual bool tieInt (const string &name,
252                        int_getter getter,
253                        int_setter setter = 0,
254                        bool useDefault = true);
255   virtual bool tieFloat (const string &name,
256                          float_getter getter,
257                          float_setter setter = 0,
258                          bool useDefault = true);
259   virtual bool tieDouble (const string &name,
260                           double_getter getter,
261                           double_setter setter = 0,
262                           bool useDefault = true);
263   virtual bool tieString (const string &name,
264                           string_getter getter,
265                           string_setter setter = 0,
266                           bool useDefault = true);
267
268   virtual bool untie (const string &name);
269
270 private:
271   value_map _props;
272 };
273
274
275 \f
276 ////////////////////////////////////////////////////////////////////////
277 // Tree/node/directory view.
278 ////////////////////////////////////////////////////////////////////////
279
280
281 /**
282  * Tree view of a property list.
283  *
284  * This class provides a virtual tree view of a property list, without
285  * actually constructing a tree -- the view always stays in sync with
286  * the property list itself.
287  *
288  * This class is designed to be used for setup and configuration; it is
289  * optimized for ease of use rather than performance, and shouldn't be
290  * used inside a tight loop.
291  *
292  * Every node is actually just a path together with a pointer to
293  * the real property list and a few convenient operations; to the
294  * user, however, it looks like a node in a tree or a file system,
295  * with the regular operations such as getChild and getParent.
296  *
297  * Note that a node may be both a branch and a leaf -- that is, it
298  * may have a value itself and it may have children.  Here is a simple
299  * example that prints the names of all of the different nodes inside 
300  * "/controls":
301  *
302  *   FGPropertyNode controls("/controls", current_property_list);
303  *   FGPropertyNode child;
304  *   int size = controls.size();
305  *   for (int i = 0; i < size; i++) {
306  *     if (controls.getChild(child, i))
307  *       cout << child.getName() << endl;
308  *     else
309  *       cerr << "Failed to read child " << i << endl;
310  *   }
311  */
312 class FGPropertyNode
313 {
314 public:
315                                 // Constructor and destructor
316   FGPropertyNode (const string &path = "", FGPropertyList * props = 0);
317   virtual ~FGPropertyNode ();
318
319                                 // Accessor and setter for the internal
320                                 // path.
321   virtual const string &getPath () const { return _path; }
322   virtual void setPath (const string &path);
323
324                                 // Accessor and setter for the real
325                                 // property list.
326   virtual FGPropertyList * getPropertyList () { return _props; }
327   virtual void setPropertyList (FGPropertyList * props) {
328     _props = props;
329   }
330
331                                 // Accessors for derived information.
332   virtual int size () const;
333   virtual const string &getName () const;
334   virtual FGValue * getValue ();
335   virtual bool getParent (FGPropertyNode &parent) const;
336   virtual bool getChild (FGPropertyNode &child, int n) const;
337
338 private:
339   string _path;
340   mutable string _name;         // for pointer persistence only
341   FGPropertyList * _props;
342 };
343
344
345 \f
346 ////////////////////////////////////////////////////////////////////////
347 // Global property manager.
348 ////////////////////////////////////////////////////////////////////////
349
350 extern FGPropertyList current_properties;
351
352
353 #endif __PROPS_HXX
354
355 // end of props.hxx