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