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
00097
00098
00099
00100
00101
00102
00103
00104
00106
00107
00145 template <class T>
00146 class SGRawValue
00147 {
00148 public:
00149
00159 static const T DefaultValue;
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
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
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
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
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
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
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
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
00945
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
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
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
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