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