]> git.mxchange.org Git - simgear.git/blob - simgear/misc/props.hxx
- started adding doc comments to simgear/misc/props.hxx
[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  * The property manager is implemented in three layers.  The {@link
89  * SGPropertyNode} is the highest and most abstract layer,
90  * representing * an LValue/RValue pair: it * records the position
91  * of the property in the property tree and * contains facilities
92  * for navigation to other nodes.  Each node * may contain an {@link
93  * SGValue}, which is guaranteed persistent: the * {@link SGValue}
94  * will not change during a session, even if the * property is bound
95  * and unbound multiple times.  The SGValue is the * abstraction of
96  * an RValue: it allows for conversion among all of the different
97  * types, and can be bound to external pointers, functions, methods,
98  * or other data sources.  Every SGValue contains an SGRawValue of
99  * a specific type.  The SGRawValue (this class) may change frequently
100  * during a session as a value is retyped or bound and unbound to
101  * various data source, but the abstract SGValue layer insulates
102  * the application from those changes.  The raw value contains no
103  * facilities for data binding or for type conversion: it is simply
104  * the abstraction of a primitive data type (or a compound data
105  * type, in the case of a string).
106  *
107  * The SGValue class always keeps a *copy* of a raw value, not the
108  * original one passed to it; if you override a derived class but do
109  * not replace the {@link #clone} method, strange things will happen.
110  *
111  * All raw values must implement {@link #getValue}, {@link #setValue},
112  * and {@link #clone} for the appropriate type.
113  *
114  * @see SGValue
115  * @see SGPropertyNode */
116 template <class T>
117 class SGRawValue
118 {
119 public:
120
121   /**
122    * The default underlying value for this type.
123    *
124    * Every raw value has a default; the default is false for a
125    * boolean, 0 for the various numeric values, and "" for a string.
126    * If additional types of raw values are added in the future, they
127    * may need different kinds of default values (such as epoch for a
128    * date type).  The default value is used when creating new values.
129    */
130   static const T DefaultValue;  // Default for this kind of raw value.
131
132
133   /**
134    * Constructor.
135    *
136    * Use the default value for this type.
137    */
138   SGRawValue () {}
139
140
141   /**
142    * Destructor.
143    */
144   virtual ~SGRawValue () {}
145
146
147   /**
148    * Return the underlying value.
149    *
150    * @return The actual value for the property.
151    * @see #setValue
152    */
153   virtual T getValue () const = 0;
154
155
156   /**
157    * Assign a new underlying value.
158    *
159    * If the new value cannot be set (because this is a read-only
160    * raw value, or because the new value is not acceptable for
161    * some reason) this method returns false and leaves the original
162    * value unchanged.
163    *
164    * @param value The actual value for the property.
165    * @return true if the value was set successfully, false otherwise.
166    * @see #getValue
167    */
168   virtual bool setValue (T value) = 0;
169
170
171   /**
172    * Create a new deep copy of this raw value.
173    *
174    * The copy will contain its own version of the underlying value
175    * as well.
176    *
177    * @return A deep copy of the current object.
178    */
179   virtual SGRawValue * clone () const = 0;
180 };
181
182
183 /**
184  * An unbound raw value, stored internally.
185  *
186  * Instances of this class are created automatically, by default,
187  * by the SGValue class; ordinarily the application should not
188  * need to touch it.
189  */
190 template <class T>
191 class SGRawValueInternal : public SGRawValue<T>
192 {
193 public:
194
195   /**
196    * Default constructor.
197    *
198    * Initialize with the default value for this type.
199    */
200   SGRawValueInternal () {}
201
202   /**
203    * Explicit value constructor.
204    *
205    * Initialize with the underlying value provided.
206    *
207    * @param value The initial value for this property.
208    */
209   SGRawValueInternal (T value) : _value(value) {}
210
211   /**
212    * Destructor.
213    */
214   virtual ~SGRawValueInternal () {}
215
216   /**
217    * Get the underlying value.
218    */
219   virtual T getValue () const { return _value; }
220
221   /**
222    * Set the underlying value.
223    */
224   virtual bool setValue (T value) { _value = value; return true; }
225
226   /**
227    * Create a deep copy of this raw value.
228    */
229   virtual SGRawValue<T> * clone () const {
230     return new SGRawValueInternal<T>(_value);
231   }
232
233 private:
234   T _value;
235 };
236
237
238 /**
239  * A raw value bound to a pointer.
240  *
241  * This is the most efficient way to tie an external value, but also
242  * the most dangerous, because there is no way for the supplier to
243  * perform bounds checking and derived calculations except by polling
244  * the variable to see if it has changed.  There is no default
245  * constructor, because this class would be meaningless without a
246  * pointer.
247  */
248 template <class T>
249 class SGRawValuePointer : public SGRawValue<T>
250 {
251 public:
252
253   /**
254    * Explicit pointer constructor.
255    *
256    * Create a new raw value bound to the value of the variable
257    * referenced by the pointer.
258    *
259    * @param ptr The pointer to the variable to which this raw value
260    * will be bound.
261    */
262   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
263
264   /**
265    * Destructor.
266    */
267   virtual ~SGRawValuePointer () {}
268
269   /**
270    * Get the underlying value.
271    *
272    * This method will dereference the pointer and return the
273    * variable's value.
274    */
275   virtual T getValue () const { return *_ptr; }
276
277   /**
278    * Set the underlying value.
279    *
280    * This method will dereference the pointer and change the
281    * variable's value.
282    */
283   virtual bool setValue (T value) { *_ptr = value; return true; }
284
285   /**
286    * Create a copy of this raw value.
287    *
288    * The copy will use the same external pointer as the original.
289    */
290   virtual SGRawValue<T> * clone () const {
291     return new SGRawValuePointer<T>(_ptr);
292   }
293
294 private:
295   T * _ptr;
296 };
297
298
299 /**
300  * A value managed through static functions.
301  *
302  * A read-only value will not have a setter; a write-only value will
303  * not have a getter.
304  */
305 template <class T>
306 class SGRawValueFunctions : public SGRawValue<T>
307 {
308 public:
309
310   /**
311    * The template type of a static getter function.
312    */
313   typedef T (*getter_t)();
314
315   /**
316    * The template type of a static setter function.
317    */
318   typedef void (*setter_t)(T);
319
320   /**
321    * Explicit constructor.
322    *
323    * Create a new raw value bound to the getter and setter supplied.
324    *
325    * @param getter A static function for getting a value, or 0
326    * to read-disable the value.
327    * @param setter A static function for setting a value, or 0
328    * to write-disable the value.
329    */
330   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
331     : _getter(getter), _setter(setter) {}
332
333   /**
334    * Destructor.
335    */
336   virtual ~SGRawValueFunctions () {}
337
338   /**
339    * Get the underlying value.
340    *
341    * This method will invoke the getter function to get a value.
342    * If no getter function was supplied, this method will always
343    * return the default value for the type.
344    */
345   virtual T getValue () const {
346     if (_getter) return (*_getter)();
347     else return SGRawValue<T>::DefaultValue;
348   }
349
350   /**
351    * Set the underlying value.
352    *
353    * This method will invoke the setter function to change the
354    * underlying value.  If no setter function was supplied, this
355    * method will return false.
356    */
357   virtual bool setValue (T value) {
358     if (_setter) { (*_setter)(value); return true; }
359     else return false;
360   }
361
362   /**
363    * Create a copy of this raw value, bound to the same functions.
364    */
365   virtual SGRawValue<T> * clone () const {
366     return new SGRawValueFunctions<T>(_getter,_setter);
367   }
368
369 private:
370   getter_t _getter;
371   setter_t _setter;
372 };
373
374
375 /**
376  * An indexed value bound to static functions.
377  *
378  * A read-only value will not have a setter; a write-only value will
379  * not have a getter.  An indexed value is useful for binding one
380  * of a list of possible values (such as multiple engines for a
381  * plane).  The index is hard-coded at creation time.
382  */
383 template <class T>
384 class SGRawValueFunctionsIndexed : public SGRawValue<T>
385 {
386 public:
387   typedef T (*getter_t)(int);
388   typedef void (*setter_t)(int,T);
389   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
390     : _index(index), _getter(getter), _setter(setter) {}
391   virtual ~SGRawValueFunctionsIndexed () {}
392   virtual T getValue () const {
393     if (_getter) return (*_getter)(_index);
394     else return SGRawValue<T>::DefaultValue;
395   }
396   virtual bool setValue (T value) {
397     if (_setter) { (*_setter)(_index, value); return true; }
398     else return false;
399   }
400   virtual SGRawValue<T> * clone () const {
401     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
402   }
403 private:
404   int _index;
405   getter_t _getter;
406   setter_t _setter;
407 };
408
409
410 /**
411  * A value managed through an object and access methods.
412  *
413  * A read-only value will not have a setter; a write-only value will
414  * not have a getter.
415  */
416 template <class C, class T>
417 class SGRawValueMethods : public SGRawValue<T>
418 {
419 public:
420   typedef T (C::*getter_t)() const;
421   typedef void (C::*setter_t)(T);
422   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
423     : _obj(obj), _getter(getter), _setter(setter) {}
424   virtual ~SGRawValueMethods () {}
425   virtual T getValue () const {
426     if (_getter) { return (_obj.*_getter)(); }
427     else { return SGRawValue<T>::DefaultValue; }
428   }
429   virtual bool setValue (T value) {
430     if (_setter) { (_obj.*_setter)(value); return true; }
431     else return false;
432   }
433   virtual SGRawValue<T> * clone () const {
434     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
435   }
436 private:
437   C &_obj;
438   getter_t _getter;
439   setter_t _setter;
440 };
441
442
443 /**
444  * An indexed value managed through an object and access methods.
445  *
446  * A read-only value will not have a setter; a write-only value will
447  * not have a getter.
448  */
449 template <class C, class T>
450 class SGRawValueMethodsIndexed : public SGRawValue<T>
451 {
452 public:
453   typedef T (C::*getter_t)(int) const;
454   typedef void (C::*setter_t)(int, T);
455   SGRawValueMethodsIndexed (C &obj, int index,
456                      getter_t getter = 0, setter_t setter = 0)
457     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
458   virtual ~SGRawValueMethodsIndexed () {}
459   virtual T getValue () const {
460     if (_getter) { return (_obj.*_getter)(_index); }
461     else { return SGRawValue<T>::DefaultValue; }
462   }
463   virtual bool setValue (T value) {
464     if (_setter) { (_obj.*_setter)(_index, value); return true; }
465     else return false;
466   }
467   virtual SGRawValue<T> * clone () const {
468     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
469   }
470 private:
471   C &_obj;
472   int _index;
473   getter_t _getter;
474   setter_t _setter;
475 };
476
477
478 \f
479 /**
480  * A cooked value.
481  *
482  * This is the value that property-list clients see.  It is a 
483  * persistent layer over the possibly-changing raw value; once a
484  * client gets an SGValue from the property manager, the pointer
485  * will be good for the life of the property manager itself, no
486  * matter how often the pointer is tied or untied.
487  */
488 class SGValue
489 {
490 public:
491   enum Type {
492     BOOL,
493     INT,
494     LONG,
495     FLOAT,
496     DOUBLE,
497     STRING,
498     UNKNOWN
499   };
500   SGValue ();
501   SGValue (const SGValue &value);
502   ~SGValue ();
503
504   Type getType () const;
505
506   SGValue * getAlias ();
507   const SGValue * getAlias () const;
508   bool alias (SGValue * alias);
509   bool unalias ();
510   bool isAlias () const { return _type == ALIAS; }
511
512   bool getBoolValue () const;
513   int getIntValue () const;
514   long getLongValue () const;
515   float getFloatValue () const;
516   double getDoubleValue () const;
517   string getStringValue () const;
518
519   bool setBoolValue (bool value);
520   bool setIntValue (int value);
521   bool setLongValue (long value);
522   bool setFloatValue (float value);
523   bool setDoubleValue (double value);
524   bool setStringValue (string value);
525   bool setUnknownValue (string value);
526
527   bool isTied () const { return _tied; }
528
529   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
530   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
531   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
532   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
533   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
534   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
535
536   bool untie ();
537
538 private:
539
540   enum {
541     ALIAS = -1
542   };
543
544   void clear_value ();
545
546   int _type;
547   bool _tied;
548
549                                 // The right kind of pointer...
550   union {
551     SGValue * alias;
552     SGRawValue<bool> * bool_val;
553     SGRawValue<int> * int_val;
554     SGRawValue<long> * long_val;
555     SGRawValue<float> * float_val;
556     SGRawValue<double> * double_val;
557     SGRawValue<string> * string_val;
558   } _value;
559
560 };
561
562
563 \f
564 /**
565  * A node in a property tree.
566  */
567 class SGPropertyNode
568 {
569
570 public:
571
572   SGPropertyNode ();
573    virtual ~SGPropertyNode ();
574
575                                 // Basic properties.
576   bool hasValue () const { return (_value != 0); }
577   SGValue * getValue () { return _value; }
578   SGValue * getValue (bool create);
579   const SGValue * getValue () const { return _value; }
580   const string &getName () const { return _name; }
581   const int getIndex () const { return _index; }
582   SGPropertyNode * getParent () { return _parent; }
583   const SGPropertyNode * getParent () const { return _parent; }
584
585                                 // Alias support.
586   bool alias (SGPropertyNode * target);
587   bool alias (const string &path);
588   bool unalias ();
589   bool isAlias () const;
590   SGPropertyNode * getAliasTarget ();
591   const SGPropertyNode * getAliasTarget () const;
592
593                                 // Children.
594   const int nChildren () const { return _children.size(); }
595   SGPropertyNode * getChild (int position);
596   const SGPropertyNode * getChild (int position) const;
597   SGPropertyNode * getChild (const string &name, int index = 0,
598                              bool create = false);
599   const SGPropertyNode * getChild (const string &name, int index = 0) const;
600
601   vector<SGPropertyNode *> getChildren (const string &name);
602   vector<const SGPropertyNode *> getChildren (const string &name) const;
603
604                                 // Path information.
605   string getPath (bool simplify = false) const;
606
607                                 // Relative or absolute paths.
608   SGPropertyNode * getRootNode ();
609   const SGPropertyNode * getRootNode () const;
610   SGPropertyNode * getNode (const string &relative_path, bool create = false);
611   const SGPropertyNode * getNode (const string &relative_path) const;
612
613                                 // Value-related stuff.
614   SGValue::Type getType () const;
615   
616   bool getBoolValue () const;
617   int getIntValue () const;
618   long getLongValue () const;
619   float getFloatValue () const;
620   double getDoubleValue () const;
621   string getStringValue () const;
622
623   bool setBoolValue (bool value);
624   bool setIntValue (int value);
625   bool setLongValue (long value);
626   bool setFloatValue (float value);
627   bool setDoubleValue (double value);
628   bool setStringValue (string value);
629   bool setUnknownValue (string value);
630
631   bool isTied () const;
632
633   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
634   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
635   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
636   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
637   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
638   bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
639
640   bool untie ();
641
642                                 // Values from paths.
643   bool hasValue (const string &relative_path) const;
644   SGValue * getValue (const string &relative_path, bool create = false);
645   const SGValue * getValue (const string &relative_path) const;
646
647   SGValue::Type getType (const string &relative_path) const;
648   
649   bool getBoolValue (const string &relative_path,
650                      bool defaultValue = false) const;
651   int getIntValue (const string &relative_path,
652                    int defaultValue = 0) const;
653   long getLongValue (const string &relative_path,
654                      long defaultValue = 0L) const;
655   float getFloatValue (const string &relative_path,
656                        float defaultValue = 0.0) const;
657   double getDoubleValue (const string &relative_path,
658                          double defaultValue = 0.0L) const;
659   string getStringValue (const string &relative_path,
660                          string defaultValue = "") const;
661
662   bool setBoolValue (const string &relative_path, bool value);
663   bool setIntValue (const string &relative_path, int value);
664   bool setLongValue (const string &relative_path, long value);
665   bool setFloatValue (const string &relative_path, float value);
666   bool setDoubleValue (const string &relative_path, double value);
667   bool setStringValue (const string &relative_path, string value);
668   bool setUnknownValue (const string &relative_path, string value);
669
670   bool isTied (const string &relative_path) const;
671
672   bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
673             bool useDefault = true);
674   bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
675             bool useDefault = true);
676   bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
677             bool useDefault = true);
678   bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
679             bool useDefault = true);
680   bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
681             bool useDefault = true);
682   bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
683             bool useDefault = true);
684
685   bool untie (const string &relative_path);
686
687 protected:
688
689   SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
690
691 private:
692
693   SGPropertyNode (const SGPropertyNode &node) {}
694
695   SGValue * _value;
696   string _name;
697   int _index;
698   SGPropertyNode * _parent;
699   vector<SGPropertyNode *> _children;
700   mutable SGPropertyNode * _target;
701
702 };
703
704
705 \f
706 ////////////////////////////////////////////////////////////////////////
707 // I/O functions.
708 ////////////////////////////////////////////////////////////////////////
709
710 bool readProperties (istream &input, SGPropertyNode * start_node,
711                      const string &base = "");
712 bool readProperties (const string &file, SGPropertyNode * start_node);
713 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
714 bool writeProperties (const string &file, const SGPropertyNode * start_node);
715 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
716
717
718 #endif // __PROPS_HXX
719
720 // end of props.hxx