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