]> git.mxchange.org Git - simgear.git/blob - simgear/props/props.hxx
Merge branch 'topic/modelopt' into next
[simgear.git] / simgear / props / 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 #ifndef PROPS_STANDALONE
16 #define PROPS_STANDALONE 0
17 #endif
18
19 #include <vector>
20 #include <string>
21
22 #if PROPS_STANDALONE
23 #else
24 #include <simgear/compiler.h>
25 #include <simgear/debug/logstream.hxx>
26 #endif
27
28
29
30 #include <simgear/structure/SGReferenced.hxx>
31 #include <simgear/structure/SGSharedPtr.hxx>
32
33
34 #ifdef NONE
35 #pragma warn A sloppy coder has defined NONE as a macro!
36 #undef NONE
37 #endif
38
39 #ifdef ALIAS
40 #pragma warn A sloppy coder has defined ALIAS as a macro!
41 #undef ALIAS
42 #endif
43
44 #ifdef UNSPECIFIED
45 #pragma warn A sloppy coder has defined UNSPECIFIED as a macro!
46 #undef UNSPECIFIED
47 #endif
48
49 #ifdef BOOL
50 #pragma warn A sloppy coder has defined BOOL as a macro!
51 #undef BOOL
52 #endif
53
54 #ifdef INT
55 #pragma warn A sloppy coder has defined INT as a macro!
56 #undef INT
57 #endif
58
59 #ifdef LONG
60 #pragma warn A sloppy coder has defined LONG as a macro!
61 #undef LONG
62 #endif
63
64 #ifdef FLOAT
65 #pragma warn A sloppy coder has defined FLOAT as a macro!
66 #undef FLOAT
67 #endif
68
69 #ifdef DOUBLE
70 #pragma warn A sloppy coder has defined DOUBLE as a macro!
71 #undef DOUBLE
72 #endif
73
74 #ifdef STRING
75 #pragma warn A sloppy coder has defined STRING as a macro!
76 #undef STRING
77 #endif
78
79
80 \f
81 ////////////////////////////////////////////////////////////////////////
82 // A raw value.
83 //
84 // This is the mechanism that information-providing routines can
85 // use to link their own values to the property manager.  Any
86 // SGValue can be tied to a raw value and then untied again.
87 //
88 // Note: we are forced to use inlined methods here to ensure
89 // that the templates will be instantiated.  We're probably taking
90 // a small performance hit for that.
91 ////////////////////////////////////////////////////////////////////////
92
93
94 /**
95  * Abstract base class for a raw value.
96  *
97  * <p>The property manager is implemented in two layers.  The {@link
98  * SGPropertyNode} is the highest and most abstract layer,
99  * representing an LValue/RValue pair: it records the position of the
100  * property in the property tree and contains facilities for
101  * navigation to other nodes.  It is guaranteed to be persistent: the
102  * {@link SGPropertyNode} will not change during a session, even if
103  * the property is bound and unbound multiple times.</p>
104  *
105  * <p>When the property value is not managed internally in the
106  * SGPropertyNode, the SGPropertyNode will contain a reference to an
107  * SGRawValue (this class), which provides an abstract way to get,
108  * set, and clone the underlying value.  The SGRawValue may change
109  * frequently during a session as a value is retyped or bound and
110  * unbound to various data source, but the abstract SGPropertyNode
111  * layer insulates the application from those changes.  The raw value
112  * contains no facilities for data binding or for type conversion: it
113  * is simply the abstraction of a primitive data type (or a compound
114  * data type, in the case of a string).</p>
115  *
116  * <p>The SGPropertyNode class always keeps a *copy* of a raw value,
117  * not the original one passed to it; if you override a derived class
118  * but do not replace the {@link #clone} method, strange things will
119  * happen.</p>
120  *
121  * <p>All derived SGRawValue classes must implement {@link #getValue},
122  * {@link #setValue}, and {@link #clone} for the appropriate type.</p>
123  *
124  * @see SGPropertyNode
125  * @see SGRawValuePointer
126  * @see SGRawValueFunctions
127  * @see SGRawValueFunctionsIndexed
128  * @see SGRawValueMethods
129  * @see SGRawValueMethodsIndexed
130  */
131 template <class T>
132 class SGRawValue
133 {
134 public:
135
136   /**
137    * The default underlying value for this type.
138    *
139    * Every raw value has a default; the default is false for a
140    * boolean, 0 for the various numeric values, and "" for a string.
141    * If additional types of raw values are added in the future, they
142    * may need different kinds of default values (such as epoch for a
143    * date type).  The default value is used when creating new values.
144    */
145   static const T DefaultValue;  // Default for this kind of raw value.
146
147
148   /**
149    * Constructor.
150    *
151    * Use the default value for this type.
152    */
153   SGRawValue () {}
154
155
156   /**
157    * Destructor.
158    */
159   virtual ~SGRawValue () {}
160
161
162   /**
163    * Return the underlying value.
164    *
165    * @return The actual value for the property.
166    * @see #setValue
167    */
168   virtual T getValue () const = 0;
169
170
171   /**
172    * Assign a new underlying value.
173    *
174    * If the new value cannot be set (because this is a read-only
175    * raw value, or because the new value is not acceptable for
176    * some reason) this method returns false and leaves the original
177    * value unchanged.
178    *
179    * @param value The actual value for the property.
180    * @return true if the value was set successfully, false otherwise.
181    * @see #getValue
182    */
183   virtual bool setValue (T value) = 0;
184
185
186   /**
187    * Create a new deep copy of this raw value.
188    *
189    * The copy will contain its own version of the underlying value
190    * as well.
191    *
192    * @return A deep copy of the current object.
193    */
194   virtual SGRawValue * clone () const = 0;
195 };
196
197
198 /**
199  * A raw value bound to a pointer.
200  *
201  * This is the most efficient way to tie an external value, but also
202  * the most dangerous, because there is no way for the supplier to
203  * perform bounds checking and derived calculations except by polling
204  * the variable to see if it has changed.  There is no default
205  * constructor, because this class would be meaningless without a
206  * pointer.
207  */
208 template <class T>
209 class SGRawValuePointer : public SGRawValue<T>
210 {
211 public:
212
213   /**
214    * Explicit pointer constructor.
215    *
216    * Create a new raw value bound to the value of the variable
217    * referenced by the pointer.
218    *
219    * @param ptr The pointer to the variable to which this raw value
220    * will be bound.
221    */
222   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
223
224   /**
225    * Destructor.
226    */
227   virtual ~SGRawValuePointer () {}
228
229   /**
230    * Get the underlying value.
231    *
232    * This method will dereference the pointer and return the
233    * variable's value.
234    */
235   virtual T getValue () const { return *_ptr; }
236
237   /**
238    * Set the underlying value.
239    *
240    * This method will dereference the pointer and change the
241    * variable's value.
242    */
243   virtual bool setValue (T value) { *_ptr = value; return true; }
244
245   /**
246    * Create a copy of this raw value.
247    *
248    * The copy will use the same external pointer as the original.
249    */
250   virtual SGRawValue<T> * clone () const {
251     return new SGRawValuePointer<T>(_ptr);
252   }
253
254 private:
255   T * _ptr;
256 };
257
258
259 /**
260  * A value managed through static functions.
261  *
262  * A read-only value will not have a setter; a write-only value will
263  * not have a getter.
264  */
265 template <class T>
266 class SGRawValueFunctions : public SGRawValue<T>
267 {
268 public:
269
270   /**
271    * The template type of a static getter function.
272    */
273   typedef T (*getter_t)();
274
275   /**
276    * The template type of a static setter function.
277    */
278   typedef void (*setter_t)(T);
279
280   /**
281    * Explicit constructor.
282    *
283    * Create a new raw value bound to the getter and setter supplied.
284    *
285    * @param getter A static function for getting a value, or 0
286    * to read-disable the value.
287    * @param setter A static function for setting a value, or 0
288    * to write-disable the value.
289    */
290   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
291     : _getter(getter), _setter(setter) {}
292
293   /**
294    * Destructor.
295    */
296   virtual ~SGRawValueFunctions () {}
297
298   /**
299    * Get the underlying value.
300    *
301    * This method will invoke the getter function to get a value.
302    * If no getter function was supplied, this method will always
303    * return the default value for the type.
304    */
305   virtual T getValue () const {
306     if (_getter) return (*_getter)();
307     else return SGRawValue<T>::DefaultValue;
308   }
309
310   /**
311    * Set the underlying value.
312    *
313    * This method will invoke the setter function to change the
314    * underlying value.  If no setter function was supplied, this
315    * method will return false.
316    */
317   virtual bool setValue (T value) {
318     if (_setter) { (*_setter)(value); return true; }
319     else return false;
320   }
321
322   /**
323    * Create a copy of this raw value, bound to the same functions.
324    */
325   virtual SGRawValue<T> * clone () const {
326     return new SGRawValueFunctions<T>(_getter,_setter);
327   }
328
329 private:
330   getter_t _getter;
331   setter_t _setter;
332 };
333
334
335 /**
336  * An indexed value bound to static functions.
337  *
338  * A read-only value will not have a setter; a write-only value will
339  * not have a getter.  An indexed value is useful for binding one
340  * of a list of possible values (such as multiple engines for a
341  * plane).  The index is hard-coded at creation time.
342  *
343  * @see SGRawValue
344  */
345 template <class T>
346 class SGRawValueFunctionsIndexed : public SGRawValue<T>
347 {
348 public:
349   typedef T (*getter_t)(int);
350   typedef void (*setter_t)(int,T);
351   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
352     : _index(index), _getter(getter), _setter(setter) {}
353   virtual ~SGRawValueFunctionsIndexed () {}
354   virtual T getValue () const {
355     if (_getter) return (*_getter)(_index);
356     else return SGRawValue<T>::DefaultValue;
357   }
358   virtual bool setValue (T value) {
359     if (_setter) { (*_setter)(_index, value); return true; }
360     else return false;
361   }
362   virtual SGRawValue<T> * clone () const {
363     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
364   }
365 private:
366   int _index;
367   getter_t _getter;
368   setter_t _setter;
369 };
370
371
372 /**
373  * A value managed through an object and access methods.
374  *
375  * A read-only value will not have a setter; a write-only value will
376  * not have a getter.
377  */
378 template <class C, class T>
379 class SGRawValueMethods : public SGRawValue<T>
380 {
381 public:
382   typedef T (C::*getter_t)() const;
383   typedef void (C::*setter_t)(T);
384   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
385     : _obj(obj), _getter(getter), _setter(setter) {}
386   virtual ~SGRawValueMethods () {}
387   virtual T getValue () const {
388     if (_getter) { return (_obj.*_getter)(); }
389     else { return SGRawValue<T>::DefaultValue; }
390   }
391   virtual bool setValue (T value) {
392     if (_setter) { (_obj.*_setter)(value); return true; }
393     else return false;
394   }
395   virtual SGRawValue<T> * clone () const {
396     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
397   }
398 private:
399   C &_obj;
400   getter_t _getter;
401   setter_t _setter;
402 };
403
404
405 /**
406  * An indexed value managed through an object and access methods.
407  *
408  * A read-only value will not have a setter; a write-only value will
409  * not have a getter.
410  */
411 template <class C, class T>
412 class SGRawValueMethodsIndexed : public SGRawValue<T>
413 {
414 public:
415   typedef T (C::*getter_t)(int) const;
416   typedef void (C::*setter_t)(int, T);
417   SGRawValueMethodsIndexed (C &obj, int index,
418                      getter_t getter = 0, setter_t setter = 0)
419     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
420   virtual ~SGRawValueMethodsIndexed () {}
421   virtual T getValue () const {
422     if (_getter) { return (_obj.*_getter)(_index); }
423     else { return SGRawValue<T>::DefaultValue; }
424   }
425   virtual bool setValue (T value) {
426     if (_setter) { (_obj.*_setter)(_index, value); return true; }
427     else return false;
428   }
429   virtual SGRawValue<T> * clone () const {
430     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
431   }
432 private:
433   C &_obj;
434   int _index;
435   getter_t _getter;
436   setter_t _setter;
437 };
438
439 \f
440 /**
441  * The smart pointer that manage reference counting
442  */
443 class SGPropertyNode;
444 typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr;
445 typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr;
446
447 \f
448 /**
449  * The property change listener interface.
450  *
451  * <p>Any class that needs to listen for property changes must implement
452  * this interface.</p>
453  */
454 class SGPropertyChangeListener
455 {
456 public:
457   virtual ~SGPropertyChangeListener ();
458   virtual void valueChanged (SGPropertyNode * node);
459   virtual void childAdded (SGPropertyNode * parent, SGPropertyNode * child);
460   virtual void childRemoved (SGPropertyNode * parent, SGPropertyNode * child);
461
462 protected:
463   friend class SGPropertyNode;
464   virtual void register_property (SGPropertyNode * node);
465   virtual void unregister_property (SGPropertyNode * node);
466
467 private:
468   std::vector<SGPropertyNode *> _properties;
469 };
470
471
472 \f
473 /**
474  * A node in a property tree.
475  */
476 class SGPropertyNode : public SGReferenced
477 {
478 public:
479
480   /**
481    * Public constants.
482    */
483   enum {
484     MAX_STRING_LEN = 1024
485   };
486
487   /**
488    * Property value types.
489    */
490   enum Type {
491     NONE = 0,
492     ALIAS,
493     BOOL,
494     INT,
495     LONG,
496     FLOAT,
497     DOUBLE,
498     STRING,
499     UNSPECIFIED
500   };
501
502
503   /**
504    * Access mode attributes.
505    *
506    * <p>The ARCHIVE attribute is strictly advisory, and controls
507    * whether the property should normally be saved and restored.</p>
508    */
509   enum Attribute {
510     READ = 1,
511     WRITE = 2,
512     ARCHIVE = 4,
513     REMOVED = 8,
514     TRACE_READ = 16,
515     TRACE_WRITE = 32,
516     USERARCHIVE = 64
517   };
518
519
520   /**
521    * Last used attribute
522    * Update as needed when enum Attribute is changed
523    */
524   static const int LAST_USED_ATTRIBUTE;
525
526
527   /**
528    * Default constructor.
529    */
530   SGPropertyNode ();
531
532
533   /**
534    * Copy constructor.
535    */
536   SGPropertyNode (const SGPropertyNode &node);
537
538
539   /**
540    * Destructor.
541    */
542   virtual ~SGPropertyNode ();
543
544
545
546   //
547   // Basic properties.
548   //
549
550   /**
551    * Test whether this node contains a primitive leaf value.
552    */
553   bool hasValue () const { return (_type != NONE); }
554
555
556   /**
557    * Get the node's simple (XML) name.
558    */
559   const char * getName () const { return _name.c_str(); }
560
561
562   /**
563    * Get the node's pretty display name, with subscript when needed.
564    */
565   const char * getDisplayName (bool simplify = false) const;
566
567
568   /**
569    * Get the node's integer index.
570    */
571   int getIndex () const { return _index; }
572
573
574   /**
575    * Get a non-const pointer to the node's parent.
576    */
577   SGPropertyNode * getParent () { return _parent; }
578
579
580   /**
581    * Get a const pointer to the node's parent.
582    */
583   const SGPropertyNode * getParent () const { return _parent; }
584
585
586   //
587   // Children.
588   //
589
590
591   /**
592    * Get the number of child nodes.
593    */
594   int nChildren () const { return _children.size(); }
595
596
597   /**
598    * Get a child node by position (*NOT* index).
599    */
600   SGPropertyNode * getChild (int position);
601
602
603   /**
604    * Get a const child node by position (*NOT* index).
605    */
606   const SGPropertyNode * getChild (int position) const;
607
608
609   /**
610    * Test whether a named child exists.
611    */
612   bool hasChild (const char * name, int index = 0) const
613   {
614     return (getChild(name, index) != 0);
615   }
616
617   /**
618    * Test whether a named child exists.
619    */
620   bool hasChild (const std::string& name, int index = 0) const
621   {
622     return (getChild(name, index) != 0);
623   }
624
625
626   /**
627    * Get a child node by name and index.
628    */
629   SGPropertyNode * getChild (const char * name, int index = 0,
630                              bool create = false);
631
632   /**
633    * Get a child node by name and index.
634    */
635   SGPropertyNode * getChild (const std::string& name, int index = 0,
636                              bool create = false)
637   { return getChild(name.c_str(), index, create); }
638
639
640   /**
641    * Get a const child node by name and index.
642    */
643   const SGPropertyNode * getChild (const char * name, int index = 0) const;
644
645   /**
646    * Get a const child node by name and index.
647    */
648   const SGPropertyNode * getChild (const std::string& name, int index = 0) const
649   { return getChild(name.c_str(), index); }
650
651
652   /**
653    * Get a vector of all children with the specified name.
654    */
655   std::vector<SGPropertyNode_ptr> getChildren (const char * name) const;
656
657   /**
658    * Get a vector of all children with the specified name.
659    */
660   std::vector<SGPropertyNode_ptr> getChildren (const std::string& name) const
661   { return getChildren(name.c_str()); }
662
663   /**
664    * Remove child by position.
665    */
666   SGPropertyNode_ptr removeChild (int pos, bool keep = true);
667
668
669   /**
670    * Remove a child node
671    */
672   SGPropertyNode_ptr removeChild (const char * name, int index = 0,
673                                   bool keep = true);
674
675   /**
676    * Remove a child node
677    */
678   SGPropertyNode_ptr removeChild (const std::string& name, int index = 0,
679                                   bool keep = true)
680   { return removeChild(name.c_str(), index, keep); }
681
682   /**
683    * Remove all children with the specified name.
684    */
685   std::vector<SGPropertyNode_ptr> removeChildren (const char * name,
686                                              bool keep = true);
687
688
689   /**
690    * Remove all children with the specified name.
691    */
692   std::vector<SGPropertyNode_ptr> removeChildren (const std::string& name,
693                                              bool keep = true)
694   { return removeChildren(name.c_str(), keep); }
695
696   //
697   // Alias support.
698   //
699
700
701   /**
702    * Alias this node's leaf value to another's.
703    */
704   bool alias (SGPropertyNode * target);
705
706
707   /**
708    * Alias this node's leaf value to another's by relative path.
709    */
710   bool alias (const char * path);
711
712   /**
713    * Alias this node's leaf value to another's by relative path.
714    */
715   bool alias (const std::string& path)
716   { return alias(path.c_str()); }
717
718
719   /**
720    * Remove any alias for this node.
721    */
722   bool unalias ();
723
724
725   /**
726    * Test whether the node's leaf value is aliased to another's.
727    */
728   bool isAlias () const { return (_type == ALIAS); }
729
730
731   /**
732    * Get a non-const pointer to the current alias target, if any.
733    */
734   SGPropertyNode * getAliasTarget ();
735
736
737   /**
738    * Get a const pointer to the current alias target, if any.
739    */
740   const SGPropertyNode * getAliasTarget () const;
741
742
743   //
744   // Path information.
745   //
746
747
748   /**
749    * Get the path to this node from the root.
750    */
751   const char * getPath (bool simplify = false) const;
752
753
754   /**
755    * Get a pointer to the root node.
756    */
757   SGPropertyNode * getRootNode ();
758
759
760   /**
761    * Get a const pointer to the root node.
762    */
763   const SGPropertyNode * getRootNode () const;
764
765
766   /**
767    * Get a pointer to another node by relative path.
768    */
769   SGPropertyNode * getNode (const char * relative_path, bool create = false);
770
771   /**
772    * Get a pointer to another node by relative path.
773    */
774   SGPropertyNode * getNode (const std::string& relative_path, bool create = false)
775   { return getNode(relative_path.c_str(), create); }
776
777   /**
778    * Get a pointer to another node by relative path.
779    *
780    * This method leaves the index off the last member of the path,
781    * so that the user can specify it separately (and save some
782    * string building).  For example, getNode("/bar[1]/foo", 3) is
783    * exactly equivalent to getNode("bar[1]/foo[3]").  The index
784    * provided overrides any given in the path itself for the last
785    * component.
786    */
787   SGPropertyNode * getNode (const char * relative_path, int index,
788                             bool create = false);
789
790   /**
791    * Get a pointer to another node by relative path.
792    *
793    * This method leaves the index off the last member of the path,
794    * so that the user can specify it separately (and save some
795    * string building).  For example, getNode("/bar[1]/foo", 3) is
796    * exactly equivalent to getNode("bar[1]/foo[3]").  The index
797    * provided overrides any given in the path itself for the last
798    * component.
799    */
800   SGPropertyNode * getNode (const std::string& relative_path, int index,
801                             bool create = false)
802   { return getNode(relative_path.c_str(), index, create); }
803
804   /**
805    * Get a const pointer to another node by relative path.
806    */
807   const SGPropertyNode * getNode (const char * relative_path) const;
808
809   /**
810    * Get a const pointer to another node by relative path.
811    */
812   const SGPropertyNode * getNode (const std::string& relative_path) const
813   { return getNode(relative_path.c_str()); }
814
815
816   /**
817    * Get a const pointer to another node by relative path.
818    *
819    * This method leaves the index off the last member of the path,
820    * so that the user can specify it separate.
821    */
822   const SGPropertyNode * getNode (const char * relative_path,
823                                   int index) const;
824
825   /**
826    * Get a const pointer to another node by relative path.
827    *
828    * This method leaves the index off the last member of the path,
829    * so that the user can specify it separate.
830    */
831   const SGPropertyNode * getNode (const std::string& relative_path,
832                                   int index) const
833   { return getNode(relative_path.c_str(), index); }
834
835   //
836   // Access Mode.
837   //
838
839   /**
840    * Check a single mode attribute for the property node.
841    */
842   bool getAttribute (Attribute attr) const { return ((_attr & attr) != 0); }
843
844
845   /**
846    * Set a single mode attribute for the property node.
847    */
848   void setAttribute (Attribute attr, bool state) {
849     (state ? _attr |= attr : _attr &= ~attr);
850   }
851
852
853   /**
854    * Get all of the mode attributes for the property node.
855    */
856   int getAttributes () const { return _attr; }
857
858
859   /**
860    * Set all of the mode attributes for the property node.
861    */
862   void setAttributes (int attr) { _attr = attr; }
863   
864
865   //
866   // Leaf Value (primitive).
867   //
868
869
870   /**
871    * Get the type of leaf value, if any, for this node.
872    */
873   Type getType () const;
874
875
876   /**
877    * Get a bool value for this node.
878    */
879   bool getBoolValue () const;
880
881
882   /**
883    * Get an int value for this node.
884    */
885   int getIntValue () const;
886
887
888   /**
889    * Get a long int value for this node.
890    */
891   long getLongValue () const;
892
893
894   /**
895    * Get a float value for this node.
896    */
897   float getFloatValue () const;
898
899
900   /**
901    * Get a double value for this node.
902    */
903   double getDoubleValue () const;
904
905
906   /**
907    * Get a string value for this node.
908    */
909   const char * getStringValue () const;
910
911
912
913   /**
914    * Set a bool value for this node.
915    */
916   bool setBoolValue (bool value);
917
918
919   /**
920    * Set an int value for this node.
921    */
922   bool setIntValue (int value);
923
924
925   /**
926    * Set a long int value for this node.
927    */
928   bool setLongValue (long value);
929
930
931   /**
932    * Set a float value for this node.
933    */
934   bool setFloatValue (float value);
935
936
937   /**
938    * Set a double value for this node.
939    */
940   bool setDoubleValue (double value);
941
942
943   /**
944    * Set a string value for this node.
945    */
946   bool setStringValue (const char * value);
947
948   /**
949    * Set a string value for this node.
950    */
951   bool setStringValue (const std::string& value)
952   { return setStringValue(value.c_str()); }
953
954
955   /**
956    * Set a value of unspecified type for this node.
957    */
958   bool setUnspecifiedValue (const char * value);
959
960
961   //
962   // Data binding.
963   //
964
965
966   /**
967    * Test whether this node is bound to an external data source.
968    */
969   bool isTied () const { return _tied; }
970
971
972   /**
973    * Bind this node to an external bool source.
974    */
975   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
976
977
978   /**
979    * Bind this node to an external int source.
980    */
981   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
982
983
984   /**
985    * Bind this node to an external long int source.
986    */
987   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
988
989
990   /**
991    * Bind this node to an external float source.
992    */
993   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
994
995
996   /**
997    * Bind this node to an external double source.
998    */
999   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
1000
1001
1002   /**
1003    * Bind this node to an external string source.
1004    */
1005   bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
1006
1007
1008   /**
1009    * Unbind this node from any external data source.
1010    */
1011   bool untie ();
1012
1013
1014   //
1015   // Convenience methods using paths.
1016   // TODO: add attribute methods
1017   //
1018
1019
1020   /**
1021    * Get another node's type.
1022    */
1023   Type getType (const char * relative_path) const;
1024
1025   /**
1026    * Get another node's type.
1027    */
1028   Type getType (const std::string& relative_path) const
1029   { return getType(relative_path.c_str()); }
1030
1031   /**
1032    * Test whether another node has a leaf value.
1033    */
1034   bool hasValue (const char * relative_path) const;
1035
1036   /**
1037    * Test whether another node has a leaf value.
1038    */
1039   bool hasValue (const std::string& relative_path) const
1040   { return hasValue(relative_path.c_str()); }
1041
1042   /**
1043    * Get another node's value as a bool.
1044    */
1045   bool getBoolValue (const char * relative_path,
1046                      bool defaultValue = false) const;
1047
1048   /**
1049    * Get another node's value as a bool.
1050    */
1051   bool getBoolValue (const std::string& relative_path,
1052                      bool defaultValue = false) const
1053   { return getBoolValue(relative_path.c_str(), defaultValue); }
1054
1055   /**
1056    * Get another node's value as an int.
1057    */
1058   int getIntValue (const char * relative_path,
1059                    int defaultValue = 0) const;
1060
1061   /**
1062    * Get another node's value as an int.
1063    */
1064   int getIntValue (const std::string& relative_path,
1065                    int defaultValue = 0) const
1066   { return getIntValue(relative_path.c_str(), defaultValue); }
1067
1068
1069   /**
1070    * Get another node's value as a long int.
1071    */
1072   long getLongValue (const char * relative_path,
1073                      long defaultValue = 0L) const;
1074
1075   /**
1076    * Get another node's value as a long int.
1077    */
1078   long getLongValue (const std::string& relative_path,
1079                      long defaultValue = 0L) const
1080   { return getLongValue(relative_path.c_str(), defaultValue); }
1081
1082   /**
1083    * Get another node's value as a float.
1084    */
1085   float getFloatValue (const char * relative_path,
1086                        float defaultValue = 0.0f) const;
1087
1088   /**
1089    * Get another node's value as a float.
1090    */
1091   float getFloatValue (const std::string& relative_path,
1092                        float defaultValue = 0.0f) const
1093   { return getFloatValue(relative_path.c_str(), defaultValue); }
1094
1095
1096   /**
1097    * Get another node's value as a double.
1098    */
1099   double getDoubleValue (const char * relative_path,
1100                          double defaultValue = 0.0) const;
1101
1102   /**
1103    * Get another node's value as a double.
1104    */
1105   double getDoubleValue (const std::string& relative_path,
1106                          double defaultValue = 0.0) const
1107   { return getDoubleValue(relative_path.c_str(), defaultValue); }
1108
1109   /**
1110    * Get another node's value as a string.
1111    */
1112   const char * getStringValue (const char * relative_path,
1113                                const char * defaultValue = "") const;
1114
1115
1116   /**
1117    * Get another node's value as a string.
1118    */
1119   const char * getStringValue (const std::string& relative_path,
1120                                const char * defaultValue = "") const
1121   { return getStringValue(relative_path.c_str(), defaultValue); }
1122
1123
1124   /**
1125    * Set another node's value as a bool.
1126    */
1127   bool setBoolValue (const char * relative_path, bool value);
1128
1129   /**
1130    * Set another node's value as a bool.
1131    */
1132   bool setBoolValue (const std::string& relative_path, bool value)
1133   { return setBoolValue(relative_path.c_str(), value); }
1134
1135
1136   /**
1137    * Set another node's value as an int.
1138    */
1139   bool setIntValue (const char * relative_path, int value);
1140
1141   /**
1142    * Set another node's value as an int.
1143    */
1144   bool setIntValue (const std::string& relative_path, int value)
1145   { return setIntValue(relative_path.c_str(), value); }
1146
1147
1148   /**
1149    * Set another node's value as a long int.
1150    */
1151   bool setLongValue (const char * relative_path, long value);
1152
1153   /**
1154    * Set another node's value as a long int.
1155    */
1156   bool setLongValue (const std::string& relative_path, long value)
1157   { return setLongValue(relative_path.c_str(), value); }
1158
1159
1160   /**
1161    * Set another node's value as a float.
1162    */
1163   bool setFloatValue (const char * relative_path, float value);
1164
1165   /**
1166    * Set another node's value as a float.
1167    */
1168   bool setFloatValue (const std::string& relative_path, float value)
1169   { return setFloatValue(relative_path.c_str(), value); }
1170
1171
1172   /**
1173    * Set another node's value as a double.
1174    */
1175   bool setDoubleValue (const char * relative_path, double value);
1176
1177   /**
1178    * Set another node's value as a double.
1179    */
1180   bool setDoubleValue (const std::string& relative_path, double value)
1181   { return setDoubleValue(relative_path.c_str(), value); }
1182
1183
1184   /**
1185    * Set another node's value as a string.
1186    */
1187   bool setStringValue (const char * relative_path, const char * value);
1188
1189   /**
1190    * Set another node's value as a string.
1191    */
1192   bool setStringValue (const std::string& relative_path, const char * value)
1193   { return setStringValue(relative_path.c_str(), value); }
1194
1195
1196   /**
1197    * Set another node's value with no specified type.
1198    */
1199   bool setUnspecifiedValue (const char * relative_path, const char * value);
1200
1201
1202   /**
1203    * Test whether another node is bound to an external data source.
1204    */
1205   bool isTied (const char * relative_path) const;
1206
1207   /**
1208    * Test whether another node is bound to an external data source.
1209    */
1210   bool isTied (const std::string& relative_path) const
1211   { return isTied(relative_path.c_str()); }
1212
1213   /**
1214    * Bind another node to an external bool source.
1215    */
1216   bool tie (const char * relative_path, const SGRawValue<bool> &rawValue,
1217             bool useDefault = true);
1218
1219   /**
1220    * Bind another node to an external bool source.
1221    */
1222   bool tie (const std::string& relative_path, const SGRawValue<bool> &rawValue,
1223             bool useDefault = true)
1224   { return tie(relative_path.c_str(), rawValue, useDefault); }
1225
1226
1227   /**
1228    * Bind another node to an external int source.
1229    */
1230   bool tie (const char * relative_path, const SGRawValue<int> &rawValue,
1231             bool useDefault = true);
1232
1233   /**
1234    * Bind another node to an external int source.
1235    */
1236   bool tie (const std::string& relative_path, const SGRawValue<int> &rawValue,
1237             bool useDefault = true)
1238   { return tie(relative_path.c_str(), rawValue, useDefault); }
1239
1240
1241   /**
1242    * Bind another node to an external long int source.
1243    */
1244   bool tie (const char * relative_path, const SGRawValue<long> &rawValue,
1245             bool useDefault = true);
1246
1247   /**
1248    * Bind another node to an external long int source.
1249    */
1250   bool tie (const std::string& relative_path, const SGRawValue<long> &rawValue,
1251             bool useDefault = true)
1252   { return tie(relative_path.c_str(), rawValue, useDefault); }
1253
1254
1255   /**
1256    * Bind another node to an external float source.
1257    */
1258   bool tie (const char * relative_path, const SGRawValue<float> &rawValue,
1259             bool useDefault = true);
1260
1261   /**
1262    * Bind another node to an external float source.
1263    */
1264   bool tie (const std::string& relative_path, const SGRawValue<float> &rawValue,
1265             bool useDefault = true)
1266   { return tie(relative_path.c_str(), rawValue, useDefault); }
1267
1268
1269   /**
1270    * Bind another node to an external double source.
1271    */
1272   bool tie (const char * relative_path, const SGRawValue<double> &rawValue,
1273             bool useDefault = true);
1274
1275   /**
1276    * Bind another node to an external double source.
1277    */
1278   bool tie (const std::string& relative_path, const SGRawValue<double> &rawValue,
1279             bool useDefault = true)
1280   { return tie(relative_path.c_str(), rawValue, useDefault); }
1281
1282
1283   /**
1284    * Bind another node to an external string source.
1285    */
1286   bool tie (const char * relative_path, const SGRawValue<const char *> &rawValue,
1287             bool useDefault = true);
1288
1289   /**
1290    * Bind another node to an external string source.
1291    */
1292   bool tie (const std::string& relative_path, const SGRawValue<const char*> &rawValue,
1293             bool useDefault = true)
1294   { return tie(relative_path.c_str(), rawValue, useDefault); }
1295
1296
1297   /**
1298    * Unbind another node from any external data source.
1299    */
1300   bool untie (const char * relative_path);
1301
1302   /**
1303    * Unbind another node from any external data source.
1304    */
1305   bool untie (const std::string& relative_path)
1306   { return untie(relative_path.c_str()); }
1307
1308
1309   /**
1310    * Add a change listener to the property. If "initial" is set call the
1311    * listener initially.
1312    */
1313   void addChangeListener (SGPropertyChangeListener * listener,
1314                           bool initial = false);
1315
1316
1317   /**
1318    * Remove a change listener from the property.
1319    */
1320   void removeChangeListener (SGPropertyChangeListener * listener);
1321
1322
1323   /**
1324    * Get the number of listeners.
1325    */
1326   int nListeners () const { return _listeners ? _listeners->size() : 0; }
1327
1328
1329   /**
1330    * Fire a value change event to all listeners.
1331    */
1332   void fireValueChanged ();
1333
1334
1335   /**
1336    * Fire a child-added event to all listeners.
1337    */
1338   void fireChildAdded (SGPropertyNode * child);
1339
1340
1341   /**
1342    * Fire a child-removed event to all listeners.
1343    */
1344   void fireChildRemoved (SGPropertyNode * child);
1345
1346
1347   /**
1348    * Clear any existing value and set the type to NONE.
1349    */
1350   void clearValue ();
1351
1352
1353 protected:
1354
1355   void fireValueChanged (SGPropertyNode * node);
1356   void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
1357   void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
1358
1359   /**
1360    * Protected constructor for making new nodes on demand.
1361    */
1362   SGPropertyNode (const char * name, int index, SGPropertyNode * parent);
1363
1364
1365 private:
1366
1367                                 // Get the raw value
1368   bool get_bool () const;
1369   int get_int () const;
1370   long get_long () const;
1371   float get_float () const;
1372   double get_double () const;
1373   const char * get_string () const;
1374
1375                                 // Set the raw value
1376   bool set_bool (bool value);
1377   bool set_int (int value);
1378   bool set_long (long value);
1379   bool set_float (float value);
1380   bool set_double (double value);
1381   bool set_string (const char * value);
1382
1383
1384   /**
1385    * Get the value as a string.
1386    */
1387   const char * make_string () const;
1388
1389
1390   /**
1391    * Trace a read access.
1392    */
1393   void trace_read () const;
1394
1395
1396   /**
1397    * Trace a write access.
1398    */
1399   void trace_write () const;
1400
1401
1402   /**
1403    * Remove this node from all nodes that link to it in their path cache.
1404    */
1405   void remove_from_path_caches();
1406
1407
1408   class hash_table;
1409
1410   int _index;
1411   std::string _name;
1412   mutable std::string _display_name;
1413   /// To avoid cyclic reference counting loops this shall not be a reference
1414   /// counted pointer
1415   SGPropertyNode * _parent;
1416   std::vector<SGPropertyNode_ptr> _children;
1417   std::vector<SGPropertyNode_ptr> _removedChildren;
1418   std::vector<hash_table *> _linkedNodes;
1419   mutable std::string _path;
1420   mutable std::string _buffer;
1421   hash_table * _path_cache;
1422   Type _type;
1423   bool _tied;
1424   int _attr;
1425
1426                                 // The right kind of pointer...
1427   union {
1428     SGPropertyNode * alias;
1429     SGRawValue<bool> * bool_val;
1430     SGRawValue<int> * int_val;
1431     SGRawValue<long> * long_val;
1432     SGRawValue<float> * float_val;
1433     SGRawValue<double> * double_val;
1434     SGRawValue<const char *> * string_val;
1435   } _value;
1436
1437   union {
1438     bool bool_val;
1439     int int_val;
1440     long long_val;
1441     float float_val;
1442     double double_val;
1443     char * string_val;
1444   } _local_val;
1445
1446   std::vector<SGPropertyChangeListener *> * _listeners;
1447
1448
1449   /**
1450     * Register/unregister node that links to this node in its path cache.
1451     */
1452   void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
1453   bool remove_linked_node (hash_table * node);
1454
1455
1456 \f
1457   /**
1458    * A very simple hash table.
1459    */
1460   class hash_table {
1461   public:
1462
1463     /**
1464      * An entry in a bucket in a hash table.
1465      */
1466     class entry {
1467     public:
1468       entry ();
1469       ~entry ();
1470       const char * get_key () { return _key.c_str(); }
1471       void set_key (const char * key);
1472       SGPropertyNode * get_value () { return _value; }
1473       void set_value (SGPropertyNode * value);
1474     private:
1475       std::string _key;
1476       SGSharedPtr<SGPropertyNode> _value;
1477     };
1478
1479
1480     /**
1481      * A bucket in a hash table.
1482      */
1483     class bucket {
1484     public:
1485       bucket ();
1486       ~bucket ();
1487       entry * get_entry (const char * key, bool create = false);
1488       bool erase (SGPropertyNode * node);
1489       void clear (hash_table * owner);
1490     private:
1491       int _length;
1492       entry ** _entries;
1493     };
1494
1495     friend class bucket;
1496
1497     hash_table ();
1498     ~hash_table ();
1499     SGPropertyNode * get (const char * key);
1500     void put (const char * key, SGPropertyNode * value);
1501     bool erase (SGPropertyNode * node);
1502
1503   private:
1504     unsigned int hashcode (const char * key);
1505     unsigned int _data_length;
1506     bucket ** _data;
1507   };
1508
1509 };
1510
1511 // Convenice functions for use in templates
1512 template<typename T>
1513 T getValue(const SGPropertyNode*);
1514
1515 template<>
1516 inline bool getValue<bool>(const SGPropertyNode* node) { return node->getBoolValue(); }
1517
1518 template<>
1519 inline int getValue<int>(const SGPropertyNode* node) { return node->getIntValue(); }
1520
1521 template<>
1522 inline long getValue<long>(const SGPropertyNode* node) { return node->getLongValue(); }
1523
1524 template<>
1525 inline float getValue<float>(const SGPropertyNode* node)
1526 {
1527     return node->getFloatValue();
1528 }
1529
1530 template<>
1531 inline double getValue<double>(const SGPropertyNode* node)
1532 {
1533     return node->getDoubleValue();
1534 }
1535
1536 template<>
1537 inline const char * getValue<const char*>(const SGPropertyNode* node)
1538 {
1539     return node->getStringValue ();
1540 }
1541
1542 inline bool setValue(SGPropertyNode* node, bool value)
1543 {
1544     return node->setBoolValue(value);
1545 }
1546
1547 inline bool setValue(SGPropertyNode* node, int value)
1548 {
1549     return node->setIntValue(value);
1550 }
1551
1552 inline bool setValue(SGPropertyNode* node, long value)
1553 {
1554     return node->setLongValue(value);
1555 }
1556
1557 inline bool setValue(SGPropertyNode* node, float value)
1558 {
1559     return node->setFloatValue(value);
1560 }
1561
1562 inline bool setValue(SGPropertyNode* node, double value)
1563 {
1564     return node->setDoubleValue(value);
1565 }
1566
1567 inline bool setValue(SGPropertyNode* node, const char* value)
1568 {
1569     return node->setStringValue(value);
1570 }
1571
1572 inline bool setValue (SGPropertyNode* node, const std::string& value)
1573 {
1574     return node->setStringValue(value.c_str());
1575 }
1576
1577 #endif // __PROPS_HXX
1578
1579 // end of props.hxx