]> git.mxchange.org Git - simgear.git/blob - simgear/props/props.hxx
Also test against bounds when updating the scene.
[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    * Create a child node after the last node with the same name.
627    */
628   SGPropertyNode * addChild (const char * name);
629
630   /**
631    * Get a child node by name and index.
632    */
633   SGPropertyNode * getChild (const char * name, int index = 0,
634                              bool create = false);
635
636   /**
637    * Get a child node by name and index.
638    */
639   SGPropertyNode * getChild (const std::string& name, int index = 0,
640                              bool create = false)
641   { return getChild(name.c_str(), index, create); }
642
643
644   /**
645    * Get a const child node by name and index.
646    */
647   const SGPropertyNode * getChild (const char * name, int index = 0) const;
648
649   /**
650    * Get a const child node by name and index.
651    */
652   const SGPropertyNode * getChild (const std::string& name, int index = 0) const
653   { return getChild(name.c_str(), index); }
654
655
656   /**
657    * Get a vector of all children with the specified name.
658    */
659   std::vector<SGPropertyNode_ptr> getChildren (const char * name) const;
660
661   /**
662    * Get a vector of all children with the specified name.
663    */
664   std::vector<SGPropertyNode_ptr> getChildren (const std::string& name) const
665   { return getChildren(name.c_str()); }
666
667   /**
668    * Remove child by position.
669    */
670   SGPropertyNode_ptr removeChild (int pos, bool keep = true);
671
672
673   /**
674    * Remove a child node
675    */
676   SGPropertyNode_ptr removeChild (const char * name, int index = 0,
677                                   bool keep = true);
678
679   /**
680    * Remove a child node
681    */
682   SGPropertyNode_ptr removeChild (const std::string& name, int index = 0,
683                                   bool keep = true)
684   { return removeChild(name.c_str(), index, keep); }
685
686   /**
687    * Remove all children with the specified name.
688    */
689   std::vector<SGPropertyNode_ptr> removeChildren (const char * name,
690                                              bool keep = true);
691
692
693   /**
694    * Remove all children with the specified name.
695    */
696   std::vector<SGPropertyNode_ptr> removeChildren (const std::string& name,
697                                              bool keep = true)
698   { return removeChildren(name.c_str(), keep); }
699
700   //
701   // Alias support.
702   //
703
704
705   /**
706    * Alias this node's leaf value to another's.
707    */
708   bool alias (SGPropertyNode * target);
709
710
711   /**
712    * Alias this node's leaf value to another's by relative path.
713    */
714   bool alias (const char * path);
715
716   /**
717    * Alias this node's leaf value to another's by relative path.
718    */
719   bool alias (const std::string& path)
720   { return alias(path.c_str()); }
721
722
723   /**
724    * Remove any alias for this node.
725    */
726   bool unalias ();
727
728
729   /**
730    * Test whether the node's leaf value is aliased to another's.
731    */
732   bool isAlias () const { return (_type == ALIAS); }
733
734
735   /**
736    * Get a non-const pointer to the current alias target, if any.
737    */
738   SGPropertyNode * getAliasTarget ();
739
740
741   /**
742    * Get a const pointer to the current alias target, if any.
743    */
744   const SGPropertyNode * getAliasTarget () const;
745
746
747   //
748   // Path information.
749   //
750
751
752   /**
753    * Get the path to this node from the root.
754    */
755   const char * getPath (bool simplify = false) const;
756
757
758   /**
759    * Get a pointer to the root node.
760    */
761   SGPropertyNode * getRootNode ();
762
763
764   /**
765    * Get a const pointer to the root node.
766    */
767   const SGPropertyNode * getRootNode () const;
768
769
770   /**
771    * Get a pointer to another node by relative path.
772    */
773   SGPropertyNode * getNode (const char * relative_path, bool create = false);
774
775   /**
776    * Get a pointer to another node by relative path.
777    */
778   SGPropertyNode * getNode (const std::string& relative_path, bool create = false)
779   { return getNode(relative_path.c_str(), create); }
780
781   /**
782    * Get a pointer to another node by relative path.
783    *
784    * This method leaves the index off the last member of the path,
785    * so that the user can specify it separately (and save some
786    * string building).  For example, getNode("/bar[1]/foo", 3) is
787    * exactly equivalent to getNode("bar[1]/foo[3]").  The index
788    * provided overrides any given in the path itself for the last
789    * component.
790    */
791   SGPropertyNode * getNode (const char * relative_path, int index,
792                             bool create = false);
793
794   /**
795    * Get a pointer to another node by relative path.
796    *
797    * This method leaves the index off the last member of the path,
798    * so that the user can specify it separately (and save some
799    * string building).  For example, getNode("/bar[1]/foo", 3) is
800    * exactly equivalent to getNode("bar[1]/foo[3]").  The index
801    * provided overrides any given in the path itself for the last
802    * component.
803    */
804   SGPropertyNode * getNode (const std::string& relative_path, int index,
805                             bool create = false)
806   { return getNode(relative_path.c_str(), index, create); }
807
808   /**
809    * Get a const pointer to another node by relative path.
810    */
811   const SGPropertyNode * getNode (const char * relative_path) const;
812
813   /**
814    * Get a const pointer to another node by relative path.
815    */
816   const SGPropertyNode * getNode (const std::string& relative_path) const
817   { return getNode(relative_path.c_str()); }
818
819
820   /**
821    * Get a const pointer to another node by relative path.
822    *
823    * This method leaves the index off the last member of the path,
824    * so that the user can specify it separate.
825    */
826   const SGPropertyNode * getNode (const char * relative_path,
827                                   int index) const;
828
829   /**
830    * Get a const pointer to another node by relative path.
831    *
832    * This method leaves the index off the last member of the path,
833    * so that the user can specify it separate.
834    */
835   const SGPropertyNode * getNode (const std::string& relative_path,
836                                   int index) const
837   { return getNode(relative_path.c_str(), index); }
838
839   //
840   // Access Mode.
841   //
842
843   /**
844    * Check a single mode attribute for the property node.
845    */
846   bool getAttribute (Attribute attr) const { return ((_attr & attr) != 0); }
847
848
849   /**
850    * Set a single mode attribute for the property node.
851    */
852   void setAttribute (Attribute attr, bool state) {
853     (state ? _attr |= attr : _attr &= ~attr);
854   }
855
856
857   /**
858    * Get all of the mode attributes for the property node.
859    */
860   int getAttributes () const { return _attr; }
861
862
863   /**
864    * Set all of the mode attributes for the property node.
865    */
866   void setAttributes (int attr) { _attr = attr; }
867   
868
869   //
870   // Leaf Value (primitive).
871   //
872
873
874   /**
875    * Get the type of leaf value, if any, for this node.
876    */
877   Type getType () const;
878
879
880   /**
881    * Get a bool value for this node.
882    */
883   bool getBoolValue () const;
884
885
886   /**
887    * Get an int value for this node.
888    */
889   int getIntValue () const;
890
891
892   /**
893    * Get a long int value for this node.
894    */
895   long getLongValue () const;
896
897
898   /**
899    * Get a float value for this node.
900    */
901   float getFloatValue () const;
902
903
904   /**
905    * Get a double value for this node.
906    */
907   double getDoubleValue () const;
908
909
910   /**
911    * Get a string value for this node.
912    */
913   const char * getStringValue () const;
914
915
916
917   /**
918    * Set a bool value for this node.
919    */
920   bool setBoolValue (bool value);
921
922
923   /**
924    * Set an int value for this node.
925    */
926   bool setIntValue (int value);
927
928
929   /**
930    * Set a long int value for this node.
931    */
932   bool setLongValue (long value);
933
934
935   /**
936    * Set a float value for this node.
937    */
938   bool setFloatValue (float value);
939
940
941   /**
942    * Set a double value for this node.
943    */
944   bool setDoubleValue (double value);
945
946
947   /**
948    * Set a string value for this node.
949    */
950   bool setStringValue (const char * value);
951
952   /**
953    * Set a string value for this node.
954    */
955   bool setStringValue (const std::string& value)
956   { return setStringValue(value.c_str()); }
957
958
959   /**
960    * Set a value of unspecified type for this node.
961    */
962   bool setUnspecifiedValue (const char * value);
963
964
965   //
966   // Data binding.
967   //
968
969
970   /**
971    * Test whether this node is bound to an external data source.
972    */
973   bool isTied () const { return _tied; }
974
975
976   /**
977    * Bind this node to an external bool source.
978    */
979   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
980
981
982   /**
983    * Bind this node to an external int source.
984    */
985   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
986
987
988   /**
989    * Bind this node to an external long int source.
990    */
991   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
992
993
994   /**
995    * Bind this node to an external float source.
996    */
997   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
998
999
1000   /**
1001    * Bind this node to an external double source.
1002    */
1003   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
1004
1005
1006   /**
1007    * Bind this node to an external string source.
1008    */
1009   bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
1010
1011
1012   /**
1013    * Unbind this node from any external data source.
1014    */
1015   bool untie ();
1016
1017
1018   //
1019   // Convenience methods using paths.
1020   // TODO: add attribute methods
1021   //
1022
1023
1024   /**
1025    * Get another node's type.
1026    */
1027   Type getType (const char * relative_path) const;
1028
1029   /**
1030    * Get another node's type.
1031    */
1032   Type getType (const std::string& relative_path) const
1033   { return getType(relative_path.c_str()); }
1034
1035   /**
1036    * Test whether another node has a leaf value.
1037    */
1038   bool hasValue (const char * relative_path) const;
1039
1040   /**
1041    * Test whether another node has a leaf value.
1042    */
1043   bool hasValue (const std::string& relative_path) const
1044   { return hasValue(relative_path.c_str()); }
1045
1046   /**
1047    * Get another node's value as a bool.
1048    */
1049   bool getBoolValue (const char * relative_path,
1050                      bool defaultValue = false) const;
1051
1052   /**
1053    * Get another node's value as a bool.
1054    */
1055   bool getBoolValue (const std::string& relative_path,
1056                      bool defaultValue = false) const
1057   { return getBoolValue(relative_path.c_str(), defaultValue); }
1058
1059   /**
1060    * Get another node's value as an int.
1061    */
1062   int getIntValue (const char * relative_path,
1063                    int defaultValue = 0) const;
1064
1065   /**
1066    * Get another node's value as an int.
1067    */
1068   int getIntValue (const std::string& relative_path,
1069                    int defaultValue = 0) const
1070   { return getIntValue(relative_path.c_str(), defaultValue); }
1071
1072
1073   /**
1074    * Get another node's value as a long int.
1075    */
1076   long getLongValue (const char * relative_path,
1077                      long defaultValue = 0L) const;
1078
1079   /**
1080    * Get another node's value as a long int.
1081    */
1082   long getLongValue (const std::string& relative_path,
1083                      long defaultValue = 0L) const
1084   { return getLongValue(relative_path.c_str(), defaultValue); }
1085
1086   /**
1087    * Get another node's value as a float.
1088    */
1089   float getFloatValue (const char * relative_path,
1090                        float defaultValue = 0.0f) const;
1091
1092   /**
1093    * Get another node's value as a float.
1094    */
1095   float getFloatValue (const std::string& relative_path,
1096                        float defaultValue = 0.0f) const
1097   { return getFloatValue(relative_path.c_str(), defaultValue); }
1098
1099
1100   /**
1101    * Get another node's value as a double.
1102    */
1103   double getDoubleValue (const char * relative_path,
1104                          double defaultValue = 0.0) const;
1105
1106   /**
1107    * Get another node's value as a double.
1108    */
1109   double getDoubleValue (const std::string& relative_path,
1110                          double defaultValue = 0.0) const
1111   { return getDoubleValue(relative_path.c_str(), defaultValue); }
1112
1113   /**
1114    * Get another node's value as a string.
1115    */
1116   const char * getStringValue (const char * relative_path,
1117                                const char * defaultValue = "") const;
1118
1119
1120   /**
1121    * Get another node's value as a string.
1122    */
1123   const char * getStringValue (const std::string& relative_path,
1124                                const char * defaultValue = "") const
1125   { return getStringValue(relative_path.c_str(), defaultValue); }
1126
1127
1128   /**
1129    * Set another node's value as a bool.
1130    */
1131   bool setBoolValue (const char * relative_path, bool value);
1132
1133   /**
1134    * Set another node's value as a bool.
1135    */
1136   bool setBoolValue (const std::string& relative_path, bool value)
1137   { return setBoolValue(relative_path.c_str(), value); }
1138
1139
1140   /**
1141    * Set another node's value as an int.
1142    */
1143   bool setIntValue (const char * relative_path, int value);
1144
1145   /**
1146    * Set another node's value as an int.
1147    */
1148   bool setIntValue (const std::string& relative_path, int value)
1149   { return setIntValue(relative_path.c_str(), value); }
1150
1151
1152   /**
1153    * Set another node's value as a long int.
1154    */
1155   bool setLongValue (const char * relative_path, long value);
1156
1157   /**
1158    * Set another node's value as a long int.
1159    */
1160   bool setLongValue (const std::string& relative_path, long value)
1161   { return setLongValue(relative_path.c_str(), value); }
1162
1163
1164   /**
1165    * Set another node's value as a float.
1166    */
1167   bool setFloatValue (const char * relative_path, float value);
1168
1169   /**
1170    * Set another node's value as a float.
1171    */
1172   bool setFloatValue (const std::string& relative_path, float value)
1173   { return setFloatValue(relative_path.c_str(), value); }
1174
1175
1176   /**
1177    * Set another node's value as a double.
1178    */
1179   bool setDoubleValue (const char * relative_path, double value);
1180
1181   /**
1182    * Set another node's value as a double.
1183    */
1184   bool setDoubleValue (const std::string& relative_path, double value)
1185   { return setDoubleValue(relative_path.c_str(), value); }
1186
1187
1188   /**
1189    * Set another node's value as a string.
1190    */
1191   bool setStringValue (const char * relative_path, const char * value);
1192
1193   /**
1194    * Set another node's value as a string.
1195    */
1196   bool setStringValue (const std::string& relative_path, const char * value)
1197   { return setStringValue(relative_path.c_str(), value); }
1198
1199
1200   /**
1201    * Set another node's value with no specified type.
1202    */
1203   bool setUnspecifiedValue (const char * relative_path, const char * value);
1204
1205
1206   /**
1207    * Test whether another node is bound to an external data source.
1208    */
1209   bool isTied (const char * relative_path) const;
1210
1211   /**
1212    * Test whether another node is bound to an external data source.
1213    */
1214   bool isTied (const std::string& relative_path) const
1215   { return isTied(relative_path.c_str()); }
1216
1217   /**
1218    * Bind another node to an external bool source.
1219    */
1220   bool tie (const char * relative_path, const SGRawValue<bool> &rawValue,
1221             bool useDefault = true);
1222
1223   /**
1224    * Bind another node to an external bool source.
1225    */
1226   bool tie (const std::string& relative_path, const SGRawValue<bool> &rawValue,
1227             bool useDefault = true)
1228   { return tie(relative_path.c_str(), rawValue, useDefault); }
1229
1230
1231   /**
1232    * Bind another node to an external int source.
1233    */
1234   bool tie (const char * relative_path, const SGRawValue<int> &rawValue,
1235             bool useDefault = true);
1236
1237   /**
1238    * Bind another node to an external int source.
1239    */
1240   bool tie (const std::string& relative_path, const SGRawValue<int> &rawValue,
1241             bool useDefault = true)
1242   { return tie(relative_path.c_str(), rawValue, useDefault); }
1243
1244
1245   /**
1246    * Bind another node to an external long int source.
1247    */
1248   bool tie (const char * relative_path, const SGRawValue<long> &rawValue,
1249             bool useDefault = true);
1250
1251   /**
1252    * Bind another node to an external long int source.
1253    */
1254   bool tie (const std::string& relative_path, const SGRawValue<long> &rawValue,
1255             bool useDefault = true)
1256   { return tie(relative_path.c_str(), rawValue, useDefault); }
1257
1258
1259   /**
1260    * Bind another node to an external float source.
1261    */
1262   bool tie (const char * relative_path, const SGRawValue<float> &rawValue,
1263             bool useDefault = true);
1264
1265   /**
1266    * Bind another node to an external float source.
1267    */
1268   bool tie (const std::string& relative_path, const SGRawValue<float> &rawValue,
1269             bool useDefault = true)
1270   { return tie(relative_path.c_str(), rawValue, useDefault); }
1271
1272
1273   /**
1274    * Bind another node to an external double source.
1275    */
1276   bool tie (const char * relative_path, const SGRawValue<double> &rawValue,
1277             bool useDefault = true);
1278
1279   /**
1280    * Bind another node to an external double source.
1281    */
1282   bool tie (const std::string& relative_path, const SGRawValue<double> &rawValue,
1283             bool useDefault = true)
1284   { return tie(relative_path.c_str(), rawValue, useDefault); }
1285
1286
1287   /**
1288    * Bind another node to an external string source.
1289    */
1290   bool tie (const char * relative_path, const SGRawValue<const char *> &rawValue,
1291             bool useDefault = true);
1292
1293   /**
1294    * Bind another node to an external string source.
1295    */
1296   bool tie (const std::string& relative_path, const SGRawValue<const char*> &rawValue,
1297             bool useDefault = true)
1298   { return tie(relative_path.c_str(), rawValue, useDefault); }
1299
1300
1301   /**
1302    * Unbind another node from any external data source.
1303    */
1304   bool untie (const char * relative_path);
1305
1306   /**
1307    * Unbind another node from any external data source.
1308    */
1309   bool untie (const std::string& relative_path)
1310   { return untie(relative_path.c_str()); }
1311
1312
1313   /**
1314    * Add a change listener to the property. If "initial" is set call the
1315    * listener initially.
1316    */
1317   void addChangeListener (SGPropertyChangeListener * listener,
1318                           bool initial = false);
1319
1320
1321   /**
1322    * Remove a change listener from the property.
1323    */
1324   void removeChangeListener (SGPropertyChangeListener * listener);
1325
1326
1327   /**
1328    * Get the number of listeners.
1329    */
1330   int nListeners () const { return _listeners ? _listeners->size() : 0; }
1331
1332
1333   /**
1334    * Fire a value change event to all listeners.
1335    */
1336   void fireValueChanged ();
1337
1338
1339   /**
1340    * Fire a child-added event to all listeners.
1341    */
1342   void fireChildAdded (SGPropertyNode * child);
1343
1344
1345   /**
1346    * Fire a child-removed event to all listeners.
1347    */
1348   void fireChildRemoved (SGPropertyNode * child);
1349
1350
1351   /**
1352    * Clear any existing value and set the type to NONE.
1353    */
1354   void clearValue ();
1355
1356
1357 protected:
1358
1359   void fireValueChanged (SGPropertyNode * node);
1360   void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
1361   void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
1362
1363   /**
1364    * Protected constructor for making new nodes on demand.
1365    */
1366   SGPropertyNode (const char * name, int index, SGPropertyNode * parent);
1367
1368
1369 private:
1370
1371                                 // Get the raw value
1372   bool get_bool () const;
1373   int get_int () const;
1374   long get_long () const;
1375   float get_float () const;
1376   double get_double () const;
1377   const char * get_string () const;
1378
1379                                 // Set the raw value
1380   bool set_bool (bool value);
1381   bool set_int (int value);
1382   bool set_long (long value);
1383   bool set_float (float value);
1384   bool set_double (double value);
1385   bool set_string (const char * value);
1386
1387
1388   /**
1389    * Get the value as a string.
1390    */
1391   const char * make_string () const;
1392
1393
1394   /**
1395    * Trace a read access.
1396    */
1397   void trace_read () const;
1398
1399
1400   /**
1401    * Trace a write access.
1402    */
1403   void trace_write () const;
1404
1405
1406   /**
1407    * Remove this node from all nodes that link to it in their path cache.
1408    */
1409   void remove_from_path_caches();
1410
1411
1412   class hash_table;
1413
1414   int _index;
1415   std::string _name;
1416   mutable std::string _display_name;
1417   /// To avoid cyclic reference counting loops this shall not be a reference
1418   /// counted pointer
1419   SGPropertyNode * _parent;
1420   std::vector<SGPropertyNode_ptr> _children;
1421   std::vector<SGPropertyNode_ptr> _removedChildren;
1422   std::vector<hash_table *> _linkedNodes;
1423   mutable std::string _path;
1424   mutable std::string _buffer;
1425   hash_table * _path_cache;
1426   Type _type;
1427   bool _tied;
1428   int _attr;
1429
1430                                 // The right kind of pointer...
1431   union {
1432     SGPropertyNode * alias;
1433     SGRawValue<bool> * bool_val;
1434     SGRawValue<int> * int_val;
1435     SGRawValue<long> * long_val;
1436     SGRawValue<float> * float_val;
1437     SGRawValue<double> * double_val;
1438     SGRawValue<const char *> * string_val;
1439   } _value;
1440
1441   union {
1442     bool bool_val;
1443     int int_val;
1444     long long_val;
1445     float float_val;
1446     double double_val;
1447     char * string_val;
1448   } _local_val;
1449
1450   std::vector<SGPropertyChangeListener *> * _listeners;
1451
1452
1453   /**
1454     * Register/unregister node that links to this node in its path cache.
1455     */
1456   void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
1457   bool remove_linked_node (hash_table * node);
1458
1459
1460 \f
1461   /**
1462    * A very simple hash table.
1463    */
1464   class hash_table {
1465   public:
1466
1467     /**
1468      * An entry in a bucket in a hash table.
1469      */
1470     class entry {
1471     public:
1472       entry ();
1473       ~entry ();
1474       const char * get_key () { return _key.c_str(); }
1475       void set_key (const char * key);
1476       SGPropertyNode * get_value () { return _value; }
1477       void set_value (SGPropertyNode * value);
1478     private:
1479       std::string _key;
1480       SGSharedPtr<SGPropertyNode> _value;
1481     };
1482
1483
1484     /**
1485      * A bucket in a hash table.
1486      */
1487     class bucket {
1488     public:
1489       bucket ();
1490       ~bucket ();
1491       entry * get_entry (const char * key, bool create = false);
1492       bool erase (SGPropertyNode * node);
1493       void clear (hash_table * owner);
1494     private:
1495       int _length;
1496       entry ** _entries;
1497     };
1498
1499     friend class bucket;
1500
1501     hash_table ();
1502     ~hash_table ();
1503     SGPropertyNode * get (const char * key);
1504     void put (const char * key, SGPropertyNode * value);
1505     bool erase (SGPropertyNode * node);
1506
1507   private:
1508     unsigned int hashcode (const char * key);
1509     unsigned int _data_length;
1510     bucket ** _data;
1511   };
1512
1513 };
1514
1515 // Convenice functions for use in templates
1516 template<typename T>
1517 T getValue(const SGPropertyNode*);
1518
1519 template<>
1520 inline bool getValue<bool>(const SGPropertyNode* node) { return node->getBoolValue(); }
1521
1522 template<>
1523 inline int getValue<int>(const SGPropertyNode* node) { return node->getIntValue(); }
1524
1525 template<>
1526 inline long getValue<long>(const SGPropertyNode* node) { return node->getLongValue(); }
1527
1528 template<>
1529 inline float getValue<float>(const SGPropertyNode* node)
1530 {
1531     return node->getFloatValue();
1532 }
1533
1534 template<>
1535 inline double getValue<double>(const SGPropertyNode* node)
1536 {
1537     return node->getDoubleValue();
1538 }
1539
1540 template<>
1541 inline const char * getValue<const char*>(const SGPropertyNode* node)
1542 {
1543     return node->getStringValue ();
1544 }
1545
1546 inline bool setValue(SGPropertyNode* node, bool value)
1547 {
1548     return node->setBoolValue(value);
1549 }
1550
1551 inline bool setValue(SGPropertyNode* node, int value)
1552 {
1553     return node->setIntValue(value);
1554 }
1555
1556 inline bool setValue(SGPropertyNode* node, long value)
1557 {
1558     return node->setLongValue(value);
1559 }
1560
1561 inline bool setValue(SGPropertyNode* node, float value)
1562 {
1563     return node->setFloatValue(value);
1564 }
1565
1566 inline bool setValue(SGPropertyNode* node, double value)
1567 {
1568     return node->setDoubleValue(value);
1569 }
1570
1571 inline bool setValue(SGPropertyNode* node, const char* value)
1572 {
1573     return node->setStringValue(value);
1574 }
1575
1576 inline bool setValue (SGPropertyNode* node, const std::string& value)
1577 {
1578     return node->setStringValue(value.c_str());
1579 }
1580
1581 #endif // __PROPS_HXX
1582
1583 // end of props.hxx