props.hxx

Go to the documentation of this file.
00001 
00012 #ifndef __PROPS_HXX
00013 #define __PROPS_HXX
00014 
00015 #ifndef PROPS_STANDALONE
00016 #define PROPS_STANDALONE 0
00017 #endif
00018 
00019 #include <vector>
00020 
00021 #if PROPS_STANDALONE
00022 
00023 #include <string>
00024 #include <iostream>
00025 
00026 using std::string;
00027 using std::vector;
00028 using std::istream;
00029 using std::ostream;
00030 
00031 #else
00032 
00033 #include <simgear/compiler.h>
00034 #include <simgear/debug/logstream.hxx>
00035 #include STL_STRING
00036 #include STL_IOSTREAM
00037 SG_USING_STD(string);
00038 SG_USING_STD(vector);
00039 SG_USING_STD(istream);
00040 SG_USING_STD(ostream);
00041 
00042 #endif
00043 
00044 #include <simgear/structure/SGReferenced.hxx>
00045 #include <simgear/structure/SGSharedPtr.hxx>
00046 
00047 
00048 #ifdef NONE
00049 #pragma warn A sloppy coder has defined NONE as a macro!
00050 #undef NONE
00051 #endif
00052 
00053 #ifdef ALIAS
00054 #pragma warn A sloppy coder has defined ALIAS as a macro!
00055 #undef ALIAS
00056 #endif
00057 
00058 #ifdef UNSPECIFIED
00059 #pragma warn A sloppy coder has defined UNSPECIFIED as a macro!
00060 #undef UNSPECIFIED
00061 #endif
00062 
00063 #ifdef BOOL
00064 #pragma warn A sloppy coder has defined BOOL as a macro!
00065 #undef BOOL
00066 #endif
00067 
00068 #ifdef INT
00069 #pragma warn A sloppy coder has defined INT as a macro!
00070 #undef INT
00071 #endif
00072 
00073 #ifdef LONG
00074 #pragma warn A sloppy coder has defined LONG as a macro!
00075 #undef LONG
00076 #endif
00077 
00078 #ifdef FLOAT
00079 #pragma warn A sloppy coder has defined FLOAT as a macro!
00080 #undef FLOAT
00081 #endif
00082 
00083 #ifdef DOUBLE
00084 #pragma warn A sloppy coder has defined DOUBLE as a macro!
00085 #undef DOUBLE
00086 #endif
00087 
00088 #ifdef STRING
00089 #pragma warn A sloppy coder has defined STRING as a macro!
00090 #undef STRING
00091 #endif
00092 
00093 
00094 
00096 // A raw value.
00097 //
00098 // This is the mechanism that information-providing routines can
00099 // use to link their own values to the property manager.  Any
00100 // SGValue can be tied to a raw value and then untied again.
00101 //
00102 // Note: we are forced to use inlined methods here to ensure
00103 // that the templates will be instantiated.  We're probably taking
00104 // a small performance hit for that.
00106 
00107 
00145 template <class T>
00146 class SGRawValue
00147 {
00148 public:
00149 
00159   static const T DefaultValue;  // Default for this kind of raw value.
00160 
00161 
00167   SGRawValue () {}
00168 
00169 
00173   virtual ~SGRawValue () {}
00174 
00175 
00182   virtual T getValue () const = 0;
00183 
00184 
00197   virtual bool setValue (T value) = 0;
00198 
00199 
00208   virtual SGRawValue * clone () const = 0;
00209 };
00210 
00211 
00222 template <class T>
00223 class SGRawValuePointer : public SGRawValue<T>
00224 {
00225 public:
00226 
00236   SGRawValuePointer (T * ptr) : _ptr(ptr) {}
00237 
00241   virtual ~SGRawValuePointer () {}
00242 
00249   virtual T getValue () const { return *_ptr; }
00250 
00257   virtual bool setValue (T value) { *_ptr = value; return true; }
00258 
00264   virtual SGRawValue<T> * clone () const {
00265     return new SGRawValuePointer<T>(_ptr);
00266   }
00267 
00268 private:
00269   T * _ptr;
00270 };
00271 
00272 
00279 template <class T>
00280 class SGRawValueFunctions : public SGRawValue<T>
00281 {
00282 public:
00283 
00287   typedef T (*getter_t)();
00288 
00292   typedef void (*setter_t)(T);
00293 
00304   SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
00305     : _getter(getter), _setter(setter) {}
00306 
00310   virtual ~SGRawValueFunctions () {}
00311 
00319   virtual T getValue () const {
00320     if (_getter) return (*_getter)();
00321     else return SGRawValue<T>::DefaultValue;
00322   }
00323 
00331   virtual bool setValue (T value) {
00332     if (_setter) { (*_setter)(value); return true; }
00333     else return false;
00334   }
00335 
00339   virtual SGRawValue<T> * clone () const {
00340     return new SGRawValueFunctions<T>(_getter,_setter);
00341   }
00342 
00343 private:
00344   getter_t _getter;
00345   setter_t _setter;
00346 };
00347 
00348 
00359 template <class T>
00360 class SGRawValueFunctionsIndexed : public SGRawValue<T>
00361 {
00362 public:
00363   typedef T (*getter_t)(int);
00364   typedef void (*setter_t)(int,T);
00365   SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
00366     : _index(index), _getter(getter), _setter(setter) {}
00367   virtual ~SGRawValueFunctionsIndexed () {}
00368   virtual T getValue () const {
00369     if (_getter) return (*_getter)(_index);
00370     else return SGRawValue<T>::DefaultValue;
00371   }
00372   virtual bool setValue (T value) {
00373     if (_setter) { (*_setter)(_index, value); return true; }
00374     else return false;
00375   }
00376   virtual SGRawValue<T> * clone () const {
00377     return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
00378   }
00379 private:
00380   int _index;
00381   getter_t _getter;
00382   setter_t _setter;
00383 };
00384 
00385 
00392 template <class C, class T>
00393 class SGRawValueMethods : public SGRawValue<T>
00394 {
00395 public:
00396   typedef T (C::*getter_t)() const;
00397   typedef void (C::*setter_t)(T);
00398   SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
00399     : _obj(obj), _getter(getter), _setter(setter) {}
00400   virtual ~SGRawValueMethods () {}
00401   virtual T getValue () const {
00402     if (_getter) { return (_obj.*_getter)(); }
00403     else { return SGRawValue<T>::DefaultValue; }
00404   }
00405   virtual bool setValue (T value) {
00406     if (_setter) { (_obj.*_setter)(value); return true; }
00407     else return false;
00408   }
00409   virtual SGRawValue<T> * clone () const {
00410     return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
00411   }
00412 private:
00413   C &_obj;
00414   getter_t _getter;
00415   setter_t _setter;
00416 };
00417 
00418 
00425 template <class C, class T>
00426 class SGRawValueMethodsIndexed : public SGRawValue<T>
00427 {
00428 public:
00429   typedef T (C::*getter_t)(int) const;
00430   typedef void (C::*setter_t)(int, T);
00431   SGRawValueMethodsIndexed (C &obj, int index,
00432                      getter_t getter = 0, setter_t setter = 0)
00433     : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
00434   virtual ~SGRawValueMethodsIndexed () {}
00435   virtual T getValue () const {
00436     if (_getter) { return (_obj.*_getter)(_index); }
00437     else { return SGRawValue<T>::DefaultValue; }
00438   }
00439   virtual bool setValue (T value) {
00440     if (_setter) { (_obj.*_setter)(_index, value); return true; }
00441     else return false;
00442   }
00443   virtual SGRawValue<T> * clone () const {
00444     return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
00445   }
00446 private:
00447   C &_obj;
00448   int _index;
00449   getter_t _getter;
00450   setter_t _setter;
00451 };
00452 
00453 
00457 class SGPropertyNode;
00458 typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr;
00459 typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr;
00460 
00461 
00468 class SGPropertyChangeListener
00469 {
00470 public:
00471   virtual ~SGPropertyChangeListener ();
00472   virtual void valueChanged (SGPropertyNode * node);
00473   virtual void childAdded (SGPropertyNode * parent, SGPropertyNode * child);
00474   virtual void childRemoved (SGPropertyNode * parent, SGPropertyNode * child);
00475 
00476 protected:
00477   friend class SGPropertyNode;
00478   virtual void register_property (SGPropertyNode * node);
00479   virtual void unregister_property (SGPropertyNode * node);
00480 
00481 private:
00482   vector<SGPropertyNode *> _properties;
00483 };
00484 
00485 
00486 
00490 class SGPropertyNode : public SGReferenced
00491 {
00492 public:
00493 
00497   enum {
00498     MAX_STRING_LEN = 1024
00499   };
00500 
00504   enum Type {
00505     NONE = 0,
00506     ALIAS,
00507     BOOL,
00508     INT,
00509     LONG,
00510     FLOAT,
00511     DOUBLE,
00512     STRING,
00513     UNSPECIFIED
00514   };
00515 
00516 
00523   enum Attribute {
00524     READ = 1,
00525     WRITE = 2,
00526     ARCHIVE = 4,
00527     REMOVED = 8,
00528     TRACE_READ = 16,
00529     TRACE_WRITE = 32,
00530     USERARCHIVE = 64
00531   };
00532 
00533 
00538   static const int LAST_USED_ATTRIBUTE;
00539 
00540 
00544   SGPropertyNode ();
00545 
00546 
00550   SGPropertyNode (const SGPropertyNode &node);
00551 
00552 
00556   virtual ~SGPropertyNode ();
00557 
00558 
00559 
00560   //
00561   // Basic properties.
00562   //
00563 
00567   bool hasValue () const { return (_type != NONE); }
00568 
00569 
00573   const char * getName () const { return _name.c_str(); }
00574 
00575 
00579   const char * getDisplayName (bool simplify = false) const;
00580 
00581 
00585   int getIndex () const { return _index; }
00586 
00587 
00591   SGPropertyNode * getParent () { return _parent; }
00592 
00593 
00597   const SGPropertyNode * getParent () const { return _parent; }
00598 
00599 
00600   //
00601   // Children.
00602   //
00603 
00604 
00608   int nChildren () const { return _children.size(); }
00609 
00610 
00614   SGPropertyNode * getChild (int position);
00615 
00616 
00620   const SGPropertyNode * getChild (int position) const;
00621 
00622 
00626   bool hasChild (const char * name, int index = 0) const
00627   {
00628     return (getChild(name, index) != 0);
00629   }
00630 
00631 
00635   SGPropertyNode * getChild (const char * name, int index = 0,
00636                              bool create = false);
00637 
00638 
00642   const SGPropertyNode * getChild (const char * name, int index = 0) const;
00643 
00644 
00648   vector<SGPropertyNode_ptr> getChildren (const char * name) const;
00649 
00650 
00654   SGPropertyNode_ptr removeChild (int pos, bool keep = true);
00655 
00656 
00660   SGPropertyNode_ptr removeChild (const char * name, int index = 0,
00661                                   bool keep = true);
00662 
00666   vector<SGPropertyNode_ptr> removeChildren (const char * name,
00667                                              bool keep = true);
00668 
00669 
00670   //
00671   // Alias support.
00672   //
00673 
00674 
00678   bool alias (SGPropertyNode * target);
00679 
00680 
00684   bool alias (const char * path);
00685 
00686 
00690   bool unalias ();
00691 
00692 
00696   bool isAlias () const { return (_type == ALIAS); }
00697 
00698 
00702   SGPropertyNode * getAliasTarget ();
00703 
00704 
00708   const SGPropertyNode * getAliasTarget () const;
00709 
00710 
00711   //
00712   // Path information.
00713   //
00714 
00715 
00719   const char * getPath (bool simplify = false) const;
00720 
00721 
00725   SGPropertyNode * getRootNode ();
00726 
00727 
00731   const SGPropertyNode * getRootNode () const;
00732 
00733 
00737   SGPropertyNode * getNode (const char * relative_path, bool create = false);
00738 
00739 
00750   SGPropertyNode * getNode (const char * relative_path, int index,
00751                             bool create = false);
00752 
00753 
00757   const SGPropertyNode * getNode (const char * relative_path) const;
00758 
00759 
00766   const SGPropertyNode * getNode (const char * relative_path,
00767                                   int index) const;
00768 
00769 
00770   //
00771   // Access Mode.
00772   //
00773 
00777   bool getAttribute (Attribute attr) const { return ((_attr & attr) != 0); }
00778 
00779 
00783   void setAttribute (Attribute attr, bool state) {
00784     (state ? _attr |= attr : _attr &= ~attr);
00785   }
00786 
00787 
00791   int getAttributes () const { return _attr; }
00792 
00793 
00797   void setAttributes (int attr) { _attr = attr; }
00798   
00799 
00800   //
00801   // Leaf Value (primitive).
00802   //
00803 
00804 
00808   Type getType () const;
00809 
00810 
00814   bool getBoolValue () const;
00815 
00816 
00820   int getIntValue () const;
00821 
00822 
00826   long getLongValue () const;
00827 
00828 
00832   float getFloatValue () const;
00833 
00834 
00838   double getDoubleValue () const;
00839 
00840 
00844   const char * getStringValue () const;
00845 
00846 
00847 
00851   bool setBoolValue (bool value);
00852 
00853 
00857   bool setIntValue (int value);
00858 
00859 
00863   bool setLongValue (long value);
00864 
00865 
00869   bool setFloatValue (float value);
00870 
00871 
00875   bool setDoubleValue (double value);
00876 
00877 
00881   bool setStringValue (const char * value);
00882 
00883 
00887   bool setUnspecifiedValue (const char * value);
00888 
00889 
00890   //
00891   // Data binding.
00892   //
00893 
00894 
00898   bool isTied () const { return _tied; }
00899 
00900 
00904   bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
00905 
00906 
00910   bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
00911 
00912 
00916   bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
00917 
00918 
00922   bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
00923 
00924 
00928   bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
00929 
00930 
00934   bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
00935 
00936 
00940   bool untie ();
00941 
00942 
00943   //
00944   // Convenience methods using paths.
00945   // TODO: add attribute methods
00946   //
00947 
00948 
00952   Type getType (const char * relative_path) const;
00953 
00954 
00958   bool hasValue (const char * relative_path) const;
00959 
00960 
00964   bool getBoolValue (const char * relative_path,
00965                      bool defaultValue = false) const;
00966 
00967 
00971   int getIntValue (const char * relative_path,
00972                    int defaultValue = 0) const;
00973 
00974 
00978   long getLongValue (const char * relative_path,
00979                      long defaultValue = 0L) const;
00980 
00981 
00985   float getFloatValue (const char * relative_path,
00986                        float defaultValue = 0.0) const;
00987 
00988 
00992   double getDoubleValue (const char * relative_path,
00993                          double defaultValue = 0.0L) const;
00994 
00995 
00999   const char * getStringValue (const char * relative_path,
01000                                const char * defaultValue = "") const;
01001 
01002 
01006   bool setBoolValue (const char * relative_path, bool value);
01007 
01008 
01012   bool setIntValue (const char * relative_path, int value);
01013 
01014 
01018   bool setLongValue (const char * relative_path, long value);
01019 
01020 
01024   bool setFloatValue (const char * relative_path, float value);
01025 
01026 
01030   bool setDoubleValue (const char * relative_path, double value);
01031 
01032 
01036   bool setStringValue (const char * relative_path, const char * value);
01037 
01038 
01042   bool setUnspecifiedValue (const char * relative_path, const char * value);
01043 
01044 
01048   bool isTied (const char * relative_path) const;
01049 
01050 
01054   bool tie (const char * relative_path, const SGRawValue<bool> &rawValue,
01055             bool useDefault = true);
01056 
01057 
01061   bool tie (const char * relative_path, const SGRawValue<int> &rawValue,
01062             bool useDefault = true);
01063 
01064 
01068   bool tie (const char * relative_path, const SGRawValue<long> &rawValue,
01069             bool useDefault = true);
01070 
01071 
01075   bool tie (const char * relative_path, const SGRawValue<float> &rawValue,
01076             bool useDefault = true);
01077 
01078 
01082   bool tie (const char * relative_path, const SGRawValue<double> &rawValue,
01083             bool useDefault = true);
01084 
01085 
01089   bool tie (const char * relative_path, const SGRawValue<const char *> &rawValue,
01090             bool useDefault = true);
01091 
01092 
01096   bool untie (const char * relative_path);
01097 
01098 
01103   void addChangeListener (SGPropertyChangeListener * listener,
01104                           bool initial = false);
01105 
01106 
01110   void removeChangeListener (SGPropertyChangeListener * listener);
01111 
01112 
01116   int nListeners () const { return _listeners ? _listeners->size() : 0; }
01117 
01118 
01122   void fireValueChanged ();
01123 
01124 
01128   void fireChildAdded (SGPropertyNode * child);
01129 
01130 
01134   void fireChildRemoved (SGPropertyNode * child);
01135 
01136 
01140   void clearValue ();
01141 
01142 
01143 protected:
01144 
01145   void fireValueChanged (SGPropertyNode * node);
01146   void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
01147   void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
01148 
01152   SGPropertyNode (const char * name, int index, SGPropertyNode * parent);
01153 
01154 
01155 private:
01156 
01157                                 // Get the raw value
01158   bool get_bool () const;
01159   int get_int () const;
01160   long get_long () const;
01161   float get_float () const;
01162   double get_double () const;
01163   const char * get_string () const;
01164 
01165                                 // Set the raw value
01166   bool set_bool (bool value);
01167   bool set_int (int value);
01168   bool set_long (long value);
01169   bool set_float (float value);
01170   bool set_double (double value);
01171   bool set_string (const char * value);
01172 
01173 
01177   const char * make_string () const;
01178 
01179 
01183   void trace_read () const;
01184 
01185 
01189   void trace_write () const;
01190 
01191 
01195   void remove_from_path_caches();
01196 
01197 
01198   class hash_table;
01199 
01200   int _index;
01201   string _name;
01202   mutable string _display_name;
01205   SGPropertyNode * _parent;
01206   vector<SGPropertyNode_ptr> _children;
01207   vector<SGPropertyNode_ptr> _removedChildren;
01208   vector<hash_table *> _linkedNodes;
01209   mutable string _path;
01210   mutable string _buffer;
01211   hash_table * _path_cache;
01212   Type _type;
01213   bool _tied;
01214   int _attr;
01215 
01216                                 // The right kind of pointer...
01217   union {
01218     SGPropertyNode * alias;
01219     SGRawValue<bool> * bool_val;
01220     SGRawValue<int> * int_val;
01221     SGRawValue<long> * long_val;
01222     SGRawValue<float> * float_val;
01223     SGRawValue<double> * double_val;
01224     SGRawValue<const char *> * string_val;
01225   } _value;
01226 
01227   union {
01228     bool bool_val;
01229     int int_val;
01230     long long_val;
01231     float float_val;
01232     double double_val;
01233     char * string_val;
01234   } _local_val;
01235 
01236   vector <SGPropertyChangeListener *> * _listeners;
01237 
01238 
01242   void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
01243   bool remove_linked_node (hash_table * node);
01244 
01245 
01246 
01250   class hash_table {
01251   public:
01252 
01256     class entry {
01257     public:
01258       entry ();
01259       ~entry ();
01260       const char * get_key () { return _key.c_str(); }
01261       void set_key (const char * key);
01262       SGPropertyNode * get_value () { return _value; }
01263       void set_value (SGPropertyNode * value);
01264     private:
01265       string _key;
01266       SGSharedPtr<SGPropertyNode> _value;
01267     };
01268 
01269 
01273     class bucket {
01274     public:
01275       bucket ();
01276       ~bucket ();
01277       entry * get_entry (const char * key, bool create = false);
01278       bool erase (SGPropertyNode * node);
01279       void clear (hash_table * owner);
01280     private:
01281       int _length;
01282       entry ** _entries;
01283     };
01284 
01285     friend class bucket;
01286 
01287     hash_table ();
01288     ~hash_table ();
01289     SGPropertyNode * get (const char * key);
01290     void put (const char * key, SGPropertyNode * value);
01291     bool erase (SGPropertyNode * node);
01292 
01293   private:
01294     unsigned int hashcode (const char * key);
01295     unsigned int _data_length;
01296     bucket ** _data;
01297   };
01298 
01299 };
01300 
01301 #endif // __PROPS_HXX
01302 
01303 // end of props.hxx

Generated on Mon Dec 17 09:30:55 2007 for SimGear by  doxygen 1.5.1