]> git.mxchange.org Git - simgear.git/blob - simgear/misc/props.hxx
Fix a build order problem.
[simgear.git] / simgear / misc / props.hxx
1 // props.hxx - interface definition for a property list.
2 // Started Fall 2000 by David Megginson, david@megginson.com
3 // This code is released into the Public Domain.
4 //
5 // See props.html for documentation [replace with URL when available].
6 //
7 // $Id$
8
9 #ifndef __PROPS_HXX
10 #define __PROPS_HXX
11
12 #include <stdio.h>
13
14 #include <string>
15 #include <vector>
16 #include <iostream>
17
18 using std::string;
19 using std::vector;
20 using std::istream;
21 using std::ostream;
22
23 #ifdef UNKNOWN
24 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
25 #undef UNKNOWN
26 #endif
27
28 #ifdef BOOL
29 #pragma warn A sloppy coder has defined BOOL as a macro!
30 #undef BOOL
31 #endif
32
33 #ifdef INT
34 #pragma warn A sloppy coder has defined INT as a macro!
35 #undef INT
36 #endif
37
38 #ifdef FLOAT
39 #pragma warn A sloppy coder has defined FLOAT as a macro!
40 #undef FLOAT
41 #endif
42
43 #ifdef DOUBLE
44 #pragma warn A sloppy coder has defined DOUBLE as a macro!
45 #undef DOUBLE
46 #endif
47
48 #ifdef STRING
49 #pragma warn A sloppy coder has defined STRING as a macro!
50 #undef STRING
51 #endif
52
53
54 \f
55 ////////////////////////////////////////////////////////////////////////
56 // A raw value.
57 //
58 // This is the mechanism that information-providing routines can
59 // use to link their own values to the property manager.  Any
60 // SGValue can be tied to a raw value and then untied again.
61 ////////////////////////////////////////////////////////////////////////
62
63
64 /**
65  * Abstract base class for a raw value.
66  *
67  * Unlike values, raw values are not persistent -- the raw value can
68  * change frequently, but the changes are not visible to the application.
69  *
70  * The SGValue class always keeps a *copy* of a raw value, not the
71  * original one passed to it; if you override a derived class but do
72  * not replace the clone() method, strange things will happen.
73  *
74  * All raw values must implement getValue, setValue, and clone for the
75  * appropriate type.
76  */
77 template <class T>
78 class SGRawValue
79 {
80 public:
81   static const T DefaultValue;  // Default for this kind of raw value.
82
83   SGRawValue () {}
84   virtual ~SGRawValue () {}
85   virtual T getValue () const = 0;
86   virtual bool setValue (T value) = 0;
87   virtual SGRawValue * clone () const = 0;
88 };
89
90
91 /**
92  * A value managed internally.
93  *
94  * Instances of this class are created automatically, by default,
95  * by the SGValue class; ordinarily the application should not
96  * need to touch it.
97  */
98 template <class T>
99 class SGRawValueInternal : public SGRawValue<T>
100 {
101 public:
102   SGRawValueInternal () {}
103   SGRawValueInternal (T value) : _value(value) {}
104   virtual ~SGRawValueInternal () {}
105   virtual T getValue () const { return _value; }
106   virtual bool setValue (T value) { _value = value; return true; }
107   virtual SGRawValue<T> * clone () const {
108     return new SGRawValueInternal<T>(_value);
109   }
110 private:
111   T _value;
112 };
113
114
115 /**
116  * A value managed through a direct pointer.
117  *
118  * This is the most efficient way to tie an external value, but also
119  * the most dangerous, because there is no way for the supplier to
120  * perform bounds checking and derived calculations except by polling
121  * the variable to see if it has changed.
122  */
123 template <class T>
124 class SGRawValuePointer : public SGRawValue<T>
125 {
126 public:
127   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
128   virtual ~SGRawValuePointer () {}
129   virtual T getValue () const { return *_ptr; }
130   virtual bool setValue (T value) { *_ptr = value; return true; }
131   virtual SGRawValue<T> * clone () const {
132     return new SGRawValuePointer<T>(_ptr);
133   }
134 private:
135   T * _ptr;
136 };
137
138
139 /**
140  * A value managed through static functions.
141  *
142  * A read-only value will not have a setter; a write-only value will
143  * not have a getter.
144  */
145 template <class T>
146 class SGRawValueFunctions : public SGRawValue<T>
147 {
148 public:
149   typedef T (*getter_t)();
150   typedef void (*setter_t)(T);
151   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
152     : _getter(getter), _setter(setter) {}
153   virtual ~SGRawValueFunctions () {}
154   virtual T getValue () const {
155     if (_getter) return (*_getter)();
156     else return DefaultValue;
157   }
158   virtual bool setValue (T value) {
159     if (_setter) { (*_setter)(value); return true; }
160     else return false;
161   }
162   virtual SGRawValue<T> * clone () const {
163     return new SGRawValueFunctions<T>(_getter,_setter);
164   }
165 private:
166   getter_t _getter;
167   setter_t _setter;
168 };
169
170
171 /**
172  * An indexed value managed through static functions.
173  *
174  * A read-only value will not have a setter; a write-only value will
175  * not have a getter.
176  */
177 template <class T>
178 class SGRawValueFunctionsIndexed : public SGRawValue<T>
179 {
180 public:
181   typedef T (*getter_t)(int);
182   typedef void (*setter_t)(int,T);
183   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
184     : _index(index), _getter(getter), _setter(setter) {}
185   virtual ~SGRawValueFunctionsIndexed () {}
186   virtual T getValue () const {
187     if (_getter) return (*_getter)(_index);
188     else return DefaultValue;
189   }
190   virtual bool setValue (T value) {
191     if (_setter) { (*_setter)(_index, value); return true; }
192     else return false;
193   }
194   virtual SGRawValue<T> * clone () const {
195     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
196   }
197 private:
198   int _index;
199   getter_t _getter;
200   setter_t _setter;
201 };
202
203
204 /**
205  * A value managed through an object and access methods.
206  *
207  * A read-only value will not have a setter; a write-only value will
208  * not have a getter.
209  */
210 template <class C, class T>
211 class SGRawValueMethods : public SGRawValue<T>
212 {
213 public:
214   typedef T (C::*getter_t)() const;
215   typedef void (C::*setter_t)(T);
216   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
217     : _obj(obj), _getter(getter), _setter(setter) {}
218   virtual ~SGRawValueMethods () {}
219   virtual T getValue () const {
220     if (_getter) { return (_obj.*_getter)(); }
221     else { return DefaultValue; }
222   }
223   virtual bool setValue (T value) {
224     if (_setter) { (_obj.*_setter)(value); return true; }
225     else return false;
226   }
227   virtual SGRawValue<T> * clone () const {
228     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
229   }
230 private:
231   C &_obj;
232   getter_t _getter;
233   setter_t _setter;
234 };
235
236
237 /**
238  * An indexed value managed through an object and access methods.
239  *
240  * A read-only value will not have a setter; a write-only value will
241  * not have a getter.
242  */
243 template <class C, class T>
244 class SGRawValueMethodsIndexed : public SGRawValue<T>
245 {
246 public:
247   typedef T (C::*getter_t)(int) const;
248   typedef void (C::*setter_t)(int, T);
249   SGRawValueMethodsIndexed (C &obj, int index,
250                      getter_t getter = 0, setter_t setter = 0)
251     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
252   virtual ~SGRawValueMethodsIndexed () {}
253   virtual T getValue () const {
254     if (_getter) { return (_obj.*_getter)(_index); }
255     else { return DefaultValue; }
256   }
257   virtual bool setValue (T value) {
258     if (_setter) { (_obj.*_setter)(_index, value); return true; }
259     else return false;
260   }
261   virtual SGRawValue<T> * clone () const {
262     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
263   }
264 private:
265   C &_obj;
266   int _index;
267   getter_t _getter;
268   setter_t _setter;
269 };
270
271
272 \f
273 ////////////////////////////////////////////////////////////////////////
274 // A cooked value.
275 //
276 // This is the value that property-list clients see.  It is a 
277 // persistent layer over the possibly-changing raw value; once a
278 // client gets an SGValue from the property manager, the pointer
279 // will be good for the life of the property manager itself, no
280 // matter how often the pointer is tied or untied.
281 ////////////////////////////////////////////////////////////////////////
282
283 class SGValue
284 {
285 public:
286   enum Type {
287     BOOL,
288     INT,
289     FLOAT,
290     DOUBLE,
291     STRING,
292     UNKNOWN
293   };
294   SGValue ();
295   SGValue (const SGValue &value);
296   ~SGValue ();
297
298   Type getType () const { return _type; }
299
300   bool getBoolValue () const;
301   int getIntValue () const;
302   float getFloatValue () const;
303   double getDoubleValue () const;
304   string getStringValue () const;
305
306   bool setBoolValue (bool value);
307   bool setIntValue (int value);
308   bool setFloatValue (float value);
309   bool setDoubleValue (double value);
310   bool setStringValue (string value);
311   bool setUnknownValue (string value);
312
313   bool isTied () const { return _tied; }
314
315   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
316   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
317   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
318   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
319   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
320
321   bool untie ();
322
323 private:
324
325   void clear_value ();
326
327   Type _type;
328   bool _tied;
329
330                                 // The right kind of pointer...
331   union {
332     SGRawValue<bool> * bool_val;
333     SGRawValue<int> * int_val;
334     SGRawValue<float> * float_val;
335     SGRawValue<double> * double_val;
336     SGRawValue<string> * string_val;
337   } _value;
338
339 };
340
341
342 \f
343 ////////////////////////////////////////////////////////////////////////
344 // A node in a property tree.
345 ////////////////////////////////////////////////////////////////////////
346
347 class SGPropertyNode
348 {
349
350 public:
351
352   SGPropertyNode ();
353   virtual ~SGPropertyNode ();
354
355                                 // Basic properties.
356   bool hasValue () const { return (_value != 0); }
357   SGValue * getValue () { return _value; }
358   const SGValue * getValue () const { return _value; }
359   const string &getName () const { return _name; }
360   const int getIndex () const { return _index; }
361   SGPropertyNode * getParent () { return _parent; }
362   const SGPropertyNode * getParent () const { return _parent; }
363
364                                 // Children.
365   const int nChildren () const { return _children.size(); }
366   SGPropertyNode * getChild (int position);
367   const SGPropertyNode * getChild (int position) const;
368   SGPropertyNode * getChild (const string &name, int index = 0,
369                              bool create = false);
370   const SGPropertyNode * getChild (const string &name, int index = 0) const;
371
372   vector<SGPropertyNode *> getChildren (const string &name);
373   vector<const SGPropertyNode *> getChildren (const string &name) const;
374
375                                 // Path information.
376   string getPath (bool simplify = false) const;
377
378                                 // Relative or absolute paths.
379   SGPropertyNode * getRootNode ();
380   const SGPropertyNode * getRootNode () const;
381   SGPropertyNode * getNode (const string &relative_path, bool create = false);
382   const SGPropertyNode * getNode (const string &relative_path) const;
383
384                                 // Value-related stuff.
385   SGValue::Type getType () const;
386   
387   bool getBoolValue () const;
388   int getIntValue () const;
389   float getFloatValue () const;
390   double getDoubleValue () const;
391   string getStringValue () const;
392
393   bool setBoolValue (bool value);
394   bool setIntValue (int value);
395   bool setFloatValue (float value);
396   bool setDoubleValue (double value);
397   bool setStringValue (string value);
398   bool setUnknownValue (string value);
399
400   bool isTied () const;
401
402   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
403   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
404   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
405   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
406   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
407
408   bool untie ();
409
410                                 // Values from paths.
411   bool hasValue (const string &relative_path) const;
412   SGValue * getValue (const string &relative_path, bool create = false);
413   const SGValue * getValue (const string &relative_path) const;
414
415   SGValue::Type getType (const string &relative_path) const;
416   
417   bool getBoolValue (const string &relative_path,
418                      bool defaultValue = false) const;
419   int getIntValue (const string &relative_path,
420                    int defaultValue = 0) const;
421   float getFloatValue (const string &relative_path,
422                        float defaultValue = 0.0) const;
423   double getDoubleValue (const string &relative_path,
424                          double defaultValue = 0.0L) const;
425   string getStringValue (const string &relative_path,
426                          string defaultValue = "") const;
427
428   bool setBoolValue (const string &relative_path, bool value);
429   bool setIntValue (const string &relative_path, int value);
430   bool setFloatValue (const string &relative_path, float value);
431   bool setDoubleValue (const string &relative_path, double value);
432   bool setStringValue (const string &relative_path, string value);
433   bool setUnknownValue (const string &relative_path, string value);
434
435   bool isTied (const string &relative_path) const;
436
437   bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
438             bool useDefault = true);
439   bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
440             bool useDefault = true);
441   bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
442             bool useDefault = true);
443   bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
444             bool useDefault = true);
445   bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
446             bool useDefault = true);
447
448   bool untie (const string &relative_path);
449
450 protected:
451
452   SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
453
454 private:
455
456   SGPropertyNode (const SGPropertyNode &node) {}
457
458   SGValue * _value;
459   string _name;
460   int _index;
461   SGPropertyNode * _parent;
462   vector<SGPropertyNode *> _children;
463
464 };
465
466
467 \f
468 ////////////////////////////////////////////////////////////////////////
469 // I/O functions.
470 ////////////////////////////////////////////////////////////////////////
471
472 bool readProperties (istream &input, SGPropertyNode * start_node);
473 bool readProperties (const string &file, SGPropertyNode * start_node);
474 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
475 bool writeProperties (const string &file, const SGPropertyNode * start_node);
476
477
478 #endif // __PROPS_HXX
479
480 // end of props.hxx