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