]> 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 #include <iostream>
23
24 using std::string;
25 using std::map;
26 using std::istream;
27 using std::ostream;
28
29 #ifdef UNKNOWN
30 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
31 #undef UNKNOWN
32 #endif
33
34 #ifdef BOOL
35 #pragma warn A sloppy coder has defined BOOL as a macro!
36 #undef BOOL
37 #endif
38
39 #ifdef INT
40 #pragma warn A sloppy coder has defined INT as a macro!
41 #undef INT
42 #endif
43
44 #ifdef FLOAT
45 #pragma warn A sloppy coder has defined FLOAT as a macro!
46 #undef FLOAT
47 #endif
48
49 #ifdef DOUBLE
50 #pragma warn A sloppy coder has defined DOUBLE as a macro!
51 #undef DOUBLE
52 #endif
53
54 #ifdef STRING
55 #pragma warn A sloppy coder has defined STRING as a macro!
56 #undef STRING
57 #endif
58
59
60 \f
61 ////////////////////////////////////////////////////////////////////////
62 // Values.
63 ////////////////////////////////////////////////////////////////////////
64
65 /**
66  * Abstract representation of a FlightGear value.
67  *
68  * This value is designed to be fairly robust -- it can exist without
69  * a specified value, it can be any of several types, and it can
70  * be tied to an external variable without disrupting any existing
71  * pointers or references to the value.  Some basic type conversions
72  * are also handled automatically.
73  *
74  * Values also have attributes that control whether they can be read
75  * from, written to, or archived (i.e. saved to disk).
76  */
77 class SGValue
78 {
79 public:
80
81                                 // External getters
82   typedef bool (*bool_getter)();
83   typedef int (*int_getter)();
84   typedef float (*float_getter)();
85   typedef double (*double_getter)();
86   typedef const string &(*string_getter)();
87
88                                 // External setters
89   typedef void (*bool_setter)(bool);
90   typedef void (*int_setter)(int);
91   typedef void (*float_setter)(float);
92   typedef void (*double_setter)(double);
93   typedef void (*string_setter)(const string &);
94
95   enum Type {
96     UNKNOWN,                    // no value assigned yet
97     BOOL,                       // boolean
98     INT,                        // integer
99     FLOAT,                      // floating point
100     DOUBLE,                     // double precision
101     STRING                      // text
102   };
103
104   SGValue ();
105   virtual ~SGValue ();
106
107                                 // Meta information.
108   virtual Type getType () const { return _type; }
109   virtual bool isTied () const { return _tied; }
110
111                                 // Accessors.
112   virtual bool getBoolValue () const;
113   virtual int getIntValue () const;
114   virtual float getFloatValue () const;
115   virtual double getDoubleValue () const;
116   virtual const string & getStringValue () const;
117
118                                 // Setters.
119   virtual bool setBoolValue (bool value);
120   virtual bool setIntValue (int value);
121   virtual bool setFloatValue (float value);
122   virtual bool setDoubleValue (double value);
123   virtual bool setStringValue (const string &value);
124   virtual bool setUnknownValue (const string &value);
125
126                                 // Tie to external variables.
127   virtual bool tieBool (bool_getter getter,
128                         bool_setter setter = 0,
129                         bool useDefault = true);
130   virtual bool tieInt (int_getter getter,
131                        int_setter setter = 0,
132                        bool useDefault = true);
133   virtual bool tieFloat (float_getter getter,
134                          float_setter setter = 0,
135                          bool useDefault = true);
136   virtual bool tieDouble (double_getter getter,
137                           double_setter setter = 0,
138                           bool useDefault = true);
139   virtual bool tieString (string_getter getter,
140                           string_setter setter = 0,
141                           bool useDefault = true);
142
143                                 // Untie from external variables.
144   virtual bool untie ();
145
146 protected:
147
148   bool getRawBool () const;
149   int getRawInt () const;
150   float getRawFloat () const;
151   double getRawDouble () const;
152   const string &getRawString () const;
153
154   bool setRawBool (bool value);
155   bool setRawInt (int value);
156   bool setRawFloat (float value);
157   bool setRawDouble (double value);
158   bool setRawString (const string & value);
159
160 private:
161
162   Type _type;
163   bool _tied;
164
165   mutable string string_val;
166
167                                 // The value is one of the following...
168   union {
169
170     bool bool_val;
171     int int_val;
172     float float_val;
173     double double_val;
174
175     struct {
176       bool_setter setter;
177       bool_getter getter;
178     } bool_func;
179
180     struct {
181       int_setter setter;
182       int_getter getter;
183     } int_func;
184
185     struct {
186       void * obj;
187       float_setter setter;
188       float_getter getter;
189     } float_func;
190
191     struct {
192       void * obj;
193       double_setter setter;
194       double_getter getter;
195     } double_func;
196
197     struct {
198       string_setter setter;
199       string_getter getter;
200     } string_func;
201
202   } _value;
203
204 };
205
206
207 \f
208 ////////////////////////////////////////////////////////////////////////
209 // Top-level manager.
210 ////////////////////////////////////////////////////////////////////////
211
212
213 /**
214  * A list of FlightGear properties.
215  *
216  * This list associates names (conventional written as paths,
217  * i.e. "/foo/bar/hack") with SGValue classes.  Once an SGValue
218  * object is associated with the name, the association is
219  * permanent -- it is safe to keep a pointer or reference.
220  * however, that the type of a value may change if it is tied
221  * to a variable.
222  *
223  * When iterating through the list, the value type is
224  *
225  *   pair<string,SGValue>
226  *
227  * To get the name from a const_iterator, use
228  *
229  *   it->first
230  *
231  * and to get the value from a const_iterator, use
232  *
233  *   it->second
234  */
235 class SGPropertyList
236 {
237 public:
238   typedef map<string, SGValue> value_map;
239
240   typedef SGValue::bool_getter bool_getter;
241   typedef SGValue::int_getter int_getter;
242   typedef SGValue::float_getter float_getter;
243   typedef SGValue::double_getter double_getter;
244   typedef SGValue::string_getter string_getter;
245
246   typedef SGValue::bool_setter bool_setter;
247   typedef SGValue::int_setter int_setter;
248   typedef SGValue::float_setter float_setter;
249   typedef SGValue::double_setter double_setter;
250   typedef SGValue::string_setter string_setter;
251
252   typedef value_map::value_type value_type;
253   typedef value_map::size_type size_type;
254   typedef value_map::const_iterator const_iterator;
255
256   SGPropertyList ();
257   virtual ~SGPropertyList ();
258
259   virtual size_type size () const { return _props.size(); }
260
261   virtual const_iterator begin () const { return _props.begin(); }
262   virtual const_iterator end () const { return _props.end(); }
263
264   virtual bool hasValue (const string &name) const;
265
266   virtual SGValue * getValue (const string &name, bool create = false);
267   virtual const SGValue * getValue (const string &name) const;
268
269   virtual bool getBoolValue (const string &name,
270                              bool defaultValue = false) const;
271   virtual int getIntValue (const string &name,
272                            int defaultValue = 0) const;
273   virtual float getFloatValue (const string &name,
274                                float defaultValue = 0.0) const;
275   virtual double getDoubleValue (const string &name,
276                                  double defaultValue = 0.0L) const;
277   virtual const string & getStringValue (const string &name,
278                                          const string &defaultValue = "")
279     const;
280
281   virtual bool setBoolValue (const string &name, bool value);
282   virtual bool setIntValue (const string &name, int value);
283   virtual bool setFloatValue (const string &name, float value);
284   virtual bool setDoubleValue (const string &name, double value);
285   virtual bool setStringValue (const string &name, const string &value);
286   virtual bool setUnknownValue (const string &name, const string &value);
287
288   virtual bool tieBool (const string &name,
289                         bool_getter getter,
290                         bool_setter setter = 0,
291                         bool useDefault = true);
292   virtual bool tieInt (const string &name,
293                        int_getter getter,
294                        int_setter setter = 0,
295                        bool useDefault = true);
296   virtual bool tieFloat (const string &name,
297                          float_getter getter,
298                          float_setter setter = 0,
299                          bool useDefault = true);
300   virtual bool tieDouble (const string &name,
301                           double_getter getter,
302                           double_setter setter = 0,
303                           bool useDefault = true);
304   virtual bool tieString (const string &name,
305                           string_getter getter,
306                           string_setter setter = 0,
307                           bool useDefault = true);
308
309   virtual bool untie (const string &name);
310
311 private:
312   value_map _props;
313 };
314
315
316 \f
317 ////////////////////////////////////////////////////////////////////////
318 // Tree/node/directory view.
319 ////////////////////////////////////////////////////////////////////////
320
321
322 /**
323  * Tree view of a property list.
324  *
325  * This class provides a virtual tree view of a property list, without
326  * actually constructing a tree -- the view always stays in sync with
327  * the property list itself.
328  *
329  * This class is designed to be used for setup and configuration; it is
330  * optimized for ease of use rather than performance, and shouldn't be
331  * used inside a tight loop.
332  *
333  * Every node is actually just a path together with a pointer to
334  * the real property list and a few convenient operations; to the
335  * user, however, it looks like a node in a tree or a file system,
336  * with the regular operations such as getChild and getParent.
337  *
338  * Note that a node may be both a branch and a leaf -- that is, it
339  * may have a value itself and it may have children.  Here is a simple
340  * example that prints the names of all of the different nodes inside 
341  * "/controls":
342  *
343  *   SGPropertyNode controls("/controls", current_property_list);
344  *   SGPropertyNode child;
345  *   int size = controls.size();
346  *   for (int i = 0; i < size; i++) {
347  *     if (controls.getChild(child, i))
348  *       cout << child.getName() << endl;
349  *     else
350  *       cerr << "Failed to read child " << i << endl;
351  *   }
352  */
353 class SGPropertyNode
354 {
355 public:
356                                 // Constructor and destructor
357   SGPropertyNode (const string &path = "", SGPropertyList * props = 0);
358   virtual ~SGPropertyNode ();
359
360                                 // Accessor and setter for the internal
361                                 // path.
362   virtual const string &getPath () const { return _path; }
363   virtual void setPath (const string &path);
364
365                                 // Accessor and setter for the real
366                                 // property list.
367   virtual SGPropertyList * getPropertyList () { return _props; }
368   virtual void setPropertyList (SGPropertyList * props) {
369     _props = props;
370   }
371
372                                 // Accessors for derived information.
373   virtual int size () const;
374   virtual const string &getName () const;
375   virtual SGPropertyNode &getParent () const;
376   virtual SGPropertyNode &getChild (int n) const;
377   virtual SGPropertyNode &getSubNode (const string &subpath) const;
378
379                                 // Check for a value.
380   virtual bool hasValue (const string &subpath = "") const;
381
382                                 // Get values directly.
383   virtual SGValue * getValue (const string &subpath = "");
384   virtual bool getBoolValue (const string &subpath = "",
385                              bool defaultValue = false) const;
386   virtual int getIntValue (const string &subpath = "",
387                            int defaultValue = 0) const;
388   virtual float getFloatValue (const string &subpath = "",
389                                float defaultValue = 0.0) const;
390   virtual double getDoubleValue (const string &subpath = "",
391                                  double defaultValue = 0.0L) const;
392   virtual const string &
393   getStringValue (const string &subpath = "",
394                   const string &defaultValue = "") const;
395
396 private:
397   string _path;
398   SGPropertyList * _props;
399                                 // for pointer persistence...
400                                 // NOT THREAD SAFE!!!
401                                 // (each thread must have its own node
402                                 // object)
403   mutable string _name;
404   mutable SGPropertyNode * _node;
405 };
406
407
408 \f
409 ////////////////////////////////////////////////////////////////////////
410 // Input and output.
411 ////////////////////////////////////////////////////////////////////////
412
413 extern bool readPropertyList (istream &input, SGPropertyList * props);
414 extern bool readPropertyList (const string &file, SGPropertyList * props);
415 extern bool writePropertyList (ostream &output, const SGPropertyList * props);
416 extern bool writePropertyList (const string &file,
417                                const SGPropertyList * props);
418
419
420 \f
421 ////////////////////////////////////////////////////////////////////////
422 // Global property manager.
423 ////////////////////////////////////////////////////////////////////////
424
425 extern SGPropertyList current_properties;
426
427
428 #endif // __PROPS_HXX
429
430 // end of props.hxx