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 #include <string>
00021 #include <iostream>
00022 #include <sstream>
00023
00024 #include <boost/utility.hpp>
00025
00026 #if PROPS_STANDALONE
00027 #else
00028 #include <simgear/compiler.h>
00029 #include <simgear/debug/logstream.hxx>
00030 #endif
00031
00032
00033 #include <simgear/math/SGMathFwd.hxx>
00034 #include <simgear/structure/SGReferenced.hxx>
00035 #include <simgear/structure/SGSharedPtr.hxx>
00036
00037
00038
00039
00040 namespace simgear
00041 {
00042 template<typename T>
00043 std::istream& readFrom(std::istream& stream, T& result)
00044 {
00045 stream >> result;
00046 return stream;
00047 }
00048
00057 template<typename T>
00058 inline T parseString(const std::string& str)
00059 {
00060 std::istringstream stream(str);
00061 T result;
00062 readFrom(stream, result);
00063 return result;
00064 }
00065
00066
00067 template<>
00068 std::istream& readFrom<SGVec3d>(std::istream& stream, SGVec3d& result);
00069 template<>
00070 std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result);
00071
00072
00077 #ifdef NONE
00078 #pragma warn A sloppy coder has defined NONE as a macro!
00079 #undef NONE
00080 #endif
00081
00082 #ifdef ALIAS
00083 #pragma warn A sloppy coder has defined ALIAS as a macro!
00084 #undef ALIAS
00085 #endif
00086
00087 #ifdef UNSPECIFIED
00088 #pragma warn A sloppy coder has defined UNSPECIFIED as a macro!
00089 #undef UNSPECIFIED
00090 #endif
00091
00092 #ifdef BOOL
00093 #pragma warn A sloppy coder has defined BOOL as a macro!
00094 #undef BOOL
00095 #endif
00096
00097 #ifdef INT
00098 #pragma warn A sloppy coder has defined INT as a macro!
00099 #undef INT
00100 #endif
00101
00102 #ifdef LONG
00103 #pragma warn A sloppy coder has defined LONG as a macro!
00104 #undef LONG
00105 #endif
00106
00107 #ifdef FLOAT
00108 #pragma warn A sloppy coder has defined FLOAT as a macro!
00109 #undef FLOAT
00110 #endif
00111
00112 #ifdef DOUBLE
00113 #pragma warn A sloppy coder has defined DOUBLE as a macro!
00114 #undef DOUBLE
00115 #endif
00116
00117 #ifdef STRING
00118 #pragma warn A sloppy coder has defined STRING as a macro!
00119 #undef STRING
00120 #endif
00121
00122 namespace props
00123 {
00128 enum Type {
00129 NONE = 0,
00130 ALIAS,
00131 BOOL,
00132 INT,
00133 LONG,
00134 FLOAT,
00135 DOUBLE,
00136 STRING,
00137 UNSPECIFIED,
00138 EXTENDED,
00143
00144 VEC3D,
00145 VEC4D
00146 };
00147
00148 template<typename T> struct PropertyTraits;
00149
00150 #define DEFINTERNALPROP(TYPE, PROP) \
00151 template<> \
00152 struct PropertyTraits<TYPE> \
00153 { \
00154 static const Type type_tag = PROP; \
00155 enum { Internal = 1 }; \
00156 }
00157
00158 DEFINTERNALPROP(bool, BOOL);
00159 DEFINTERNALPROP(int, INT);
00160 DEFINTERNALPROP(long, LONG);
00161 DEFINTERNALPROP(float, FLOAT);
00162 DEFINTERNALPROP(double, DOUBLE);
00163 DEFINTERNALPROP(const char *, STRING);
00164 DEFINTERNALPROP(const char[], STRING);
00165 #undef DEFINTERNALPROP
00166
00167 template<>
00168 struct PropertyTraits<SGVec3d>
00169 {
00170 static const Type type_tag = VEC3D;
00171 enum { Internal = 0 };
00172 };
00173
00174 template<>
00175 struct PropertyTraits<SGVec4d>
00176 {
00177 static const Type type_tag = VEC4D;
00178 enum { Internal = 0 };
00179 };
00180 }
00181 }
00182
00183
00184
00185
00187
00188
00189
00190
00191
00192
00193
00194
00195
00197
00203 class SGRaw
00204 {
00205 public:
00211 virtual simgear::props::Type getType() const = 0;
00212 virtual ~SGRaw() {}
00213
00222 virtual SGRaw* clone() const = 0;
00223
00224 };
00225
00226 class SGRawExtended : public SGRaw
00227 {
00228 public:
00236 virtual SGRawExtended* makeContainer() const = 0;
00240 virtual std::ostream& printOn(std::ostream& stream) const = 0;
00244 virtual std::istream& readFrom(std::istream& stream) = 0;
00245 };
00246
00247
00248
00249
00250
00251 template<typename T, int internal = simgear::props::PropertyTraits<T>::Internal>
00252 class SGRawBase;
00253
00254 template<typename T>
00255 class SGRawBase<T, 1> : public SGRaw
00256 {
00257 };
00258
00259 template<typename T>
00260 class SGRawBase<T, 0> : public SGRawExtended
00261 {
00262 virtual SGRawExtended* makeContainer() const;
00263 virtual std::ostream& printOn(std::ostream& stream) const;
00264 virtual std::istream& readFrom(std::istream& stream);
00265 };
00266
00302 template <class T>
00303 class SGRawValue : public SGRawBase<T>
00304 {
00305 public:
00306
00316 static T DefaultValue()
00317 {
00318 return T();
00319 }
00320
00321
00327 SGRawValue () {}
00328
00329
00333 virtual ~SGRawValue () {}
00334
00335
00342 virtual T getValue () const = 0;
00343
00344
00357 virtual bool setValue (T value) = 0;
00358
00359
00363 virtual simgear::props::Type getType() const
00364 {
00365 return simgear::props::PropertyTraits<T>::type_tag;
00366 }
00367 };
00368
00369
00370
00372
00374
00375 template<> inline bool SGRawValue<bool>::DefaultValue()
00376 {
00377 return false;
00378 }
00379
00380 template<> inline const char * SGRawValue<const char *>::DefaultValue()
00381 {
00382 return "";
00383 }
00384
00395 template <class T>
00396 class SGRawValuePointer : public SGRawValue<T>
00397 {
00398 public:
00399
00409 SGRawValuePointer (T * ptr) : _ptr(ptr) {}
00410
00414 virtual ~SGRawValuePointer () {}
00415
00422 virtual T getValue () const { return *_ptr; }
00423
00430 virtual bool setValue (T value) { *_ptr = value; return true; }
00431
00437 virtual SGRaw* clone () const {
00438 return new SGRawValuePointer(_ptr);
00439 }
00440
00441 private:
00442 T * _ptr;
00443 };
00444
00445
00452 template <class T>
00453 class SGRawValueFunctions : public SGRawValue<T>
00454 {
00455 public:
00456
00460 typedef T (*getter_t)();
00461
00465 typedef void (*setter_t)(T);
00466
00477 SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
00478 : _getter(getter), _setter(setter) {}
00479
00483 virtual ~SGRawValueFunctions () {}
00484
00492 virtual T getValue () const {
00493 if (_getter) return (*_getter)();
00494 else return SGRawValue<T>::DefaultValue();
00495 }
00496
00504 virtual bool setValue (T value) {
00505 if (_setter) { (*_setter)(value); return true; }
00506 else return false;
00507 }
00508
00512 virtual SGRaw* clone () const {
00513 return new SGRawValueFunctions(_getter,_setter);
00514 }
00515
00516 private:
00517 getter_t _getter;
00518 setter_t _setter;
00519 };
00520
00521
00532 template <class T>
00533 class SGRawValueFunctionsIndexed : public SGRawValue<T>
00534 {
00535 public:
00536 typedef T (*getter_t)(int);
00537 typedef void (*setter_t)(int,T);
00538 SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
00539 : _index(index), _getter(getter), _setter(setter) {}
00540 virtual ~SGRawValueFunctionsIndexed () {}
00541 virtual T getValue () const {
00542 if (_getter) return (*_getter)(_index);
00543 else return SGRawValue<T>::DefaultValue();
00544 }
00545 virtual bool setValue (T value) {
00546 if (_setter) { (*_setter)(_index, value); return true; }
00547 else return false;
00548 }
00549 virtual SGRaw* clone () const {
00550 return new SGRawValueFunctionsIndexed(_index, _getter, _setter);
00551 }
00552 private:
00553 int _index;
00554 getter_t _getter;
00555 setter_t _setter;
00556 };
00557
00558
00565 template <class C, class T>
00566 class SGRawValueMethods : public SGRawValue<T>
00567 {
00568 public:
00569 typedef T (C::*getter_t)() const;
00570 typedef void (C::*setter_t)(T);
00571 SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
00572 : _obj(obj), _getter(getter), _setter(setter) {}
00573 virtual ~SGRawValueMethods () {}
00574 virtual T getValue () const {
00575 if (_getter) { return (_obj.*_getter)(); }
00576 else { return SGRawValue<T>::DefaultValue(); }
00577 }
00578 virtual bool setValue (T value) {
00579 if (_setter) { (_obj.*_setter)(value); return true; }
00580 else return false;
00581 }
00582 virtual SGRaw* clone () const {
00583 return new SGRawValueMethods(_obj, _getter, _setter);
00584 }
00585 private:
00586 C &_obj;
00587 getter_t _getter;
00588 setter_t _setter;
00589 };
00590
00591
00598 template <class C, class T>
00599 class SGRawValueMethodsIndexed : public SGRawValue<T>
00600 {
00601 public:
00602 typedef T (C::*getter_t)(int) const;
00603 typedef void (C::*setter_t)(int, T);
00604 SGRawValueMethodsIndexed (C &obj, int index,
00605 getter_t getter = 0, setter_t setter = 0)
00606 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
00607 virtual ~SGRawValueMethodsIndexed () {}
00608 virtual T getValue () const {
00609 if (_getter) { return (_obj.*_getter)(_index); }
00610 else { return SGRawValue<T>::DefaultValue(); }
00611 }
00612 virtual bool setValue (T value) {
00613 if (_setter) { (_obj.*_setter)(_index, value); return true; }
00614 else return false;
00615 }
00616 virtual SGRaw* clone () const {
00617 return new SGRawValueMethodsIndexed(_obj, _index, _getter, _setter);
00618 }
00619 private:
00620 C &_obj;
00621 int _index;
00622 getter_t _getter;
00623 setter_t _setter;
00624 };
00625
00631 template <class T>
00632 class SGRawValueContainer : public SGRawValue<T>
00633 {
00634 public:
00635
00639 SGRawValueContainer(const T& obj) : _obj(obj) {}
00640
00644 virtual ~SGRawValueContainer() {}
00645
00649 virtual T getValue() const { return _obj; }
00650
00657 virtual bool setValue (T value) { _obj = value; return true; }
00658
00662 virtual SGRaw* clone () const {
00663 return new SGRawValueContainer(_obj);
00664 }
00665
00666 private:
00667 T _obj;
00668 };
00669
00670 template<typename T>
00671 SGRawExtended* SGRawBase<T, 0>::makeContainer() const
00672 {
00673 return new SGRawValueContainer<T>(static_cast<const SGRawValue<T>*>(this)
00674 ->getValue());
00675 }
00676
00677 template<typename T>
00678 std::ostream& SGRawBase<T, 0>::printOn(std::ostream& stream) const
00679 {
00680 return stream << static_cast<SGRawValue<T>*>(this)->getValue();
00681 }
00682
00683 template<typename T>
00684 std::istream& SGRawBase<T, 0>::readFrom(std::istream& stream)
00685 {
00686 T value;
00687 simgear::readFrom(stream, value);
00688 static_cast<SGRawValue<T>*>(this)->setValue(value);
00689 return stream;
00690 }
00691
00692 template<>
00693 std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const;
00694 template<>
00695 std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const;
00696
00697
00701 class SGPropertyNode;
00702 typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr;
00703 typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr;
00704
00705 namespace simgear
00706 {
00707 typedef std::vector<SGPropertyNode_ptr> PropertyList;
00708 }
00709
00710
00717 class SGPropertyChangeListener
00718 {
00719 public:
00720 virtual ~SGPropertyChangeListener ();
00721 virtual void valueChanged (SGPropertyNode * node);
00722 virtual void childAdded (SGPropertyNode * parent, SGPropertyNode * child);
00723 virtual void childRemoved (SGPropertyNode * parent, SGPropertyNode * child);
00724
00725 protected:
00726 friend class SGPropertyNode;
00727 virtual void register_property (SGPropertyNode * node);
00728 virtual void unregister_property (SGPropertyNode * node);
00729
00730 private:
00731 std::vector<SGPropertyNode *> _properties;
00732 };
00733
00734
00735
00739 class SGPropertyNode : public SGReferenced
00740 {
00741 public:
00742
00746 enum {
00747 MAX_STRING_LEN = 1024
00748 };
00749
00756 enum Attribute {
00757 READ = 1,
00758 WRITE = 2,
00759 ARCHIVE = 4,
00760 REMOVED = 8,
00761 TRACE_READ = 16,
00762 TRACE_WRITE = 32,
00763 USERARCHIVE = 64
00764 };
00765
00766
00771 static const int LAST_USED_ATTRIBUTE;
00772
00773
00777 SGPropertyNode ();
00778
00779
00783 SGPropertyNode (const SGPropertyNode &node);
00784
00785
00789 virtual ~SGPropertyNode ();
00790
00791
00792
00793
00794
00795
00796
00800 bool hasValue () const { return (_type != simgear::props::NONE); }
00801
00802
00806 const char * getName () const { return _name.c_str(); }
00807
00811 const std::string& getNameString () const { return _name; }
00812
00816 std::string getDisplayName (bool simplify = false) const;
00817
00818
00822 int getIndex () const { return _index; }
00823
00824
00828 SGPropertyNode * getParent () { return _parent; }
00829
00830
00834 const SGPropertyNode * getParent () const { return _parent; }
00835
00836
00837
00838
00839
00840
00841
00845 int nChildren () const { return (int)_children.size(); }
00846
00847
00851 SGPropertyNode * getChild (int position);
00852
00853
00857 const SGPropertyNode * getChild (int position) const;
00858
00859
00863 bool hasChild (const char * name, int index = 0) const
00864 {
00865 return (getChild(name, index) != 0);
00866 }
00867
00871 bool hasChild (const std::string& name, int index = 0) const
00872 {
00873 return (getChild(name, index) != 0);
00874 }
00875
00879 SGPropertyNode * addChild (const char * name);
00880
00884 SGPropertyNode * getChild (const char* name, int index = 0,
00885 bool create = false);
00886 SGPropertyNode * getChild (const std::string& name, int index = 0,
00887 bool create = false);
00891 const SGPropertyNode * getChild (const char * name, int index = 0) const;
00892
00896 const SGPropertyNode * getChild (const std::string& name, int index = 0) const
00897 { return getChild(name.c_str(), index); }
00898
00899
00903 simgear::PropertyList getChildren (const char * name) const;
00904
00908 simgear::PropertyList getChildren (const std::string& name) const
00909 { return getChildren(name.c_str()); }
00910
00914 SGPropertyNode_ptr removeChild (int pos, bool keep = true);
00915
00916
00920 SGPropertyNode_ptr removeChild (const char * name, int index = 0,
00921 bool keep = true);
00922
00926 SGPropertyNode_ptr removeChild (const std::string& name, int index = 0,
00927 bool keep = true)
00928 { return removeChild(name.c_str(), index, keep); }
00929
00933 simgear::PropertyList removeChildren (const char * name, bool keep = true);
00934
00938 simgear::PropertyList removeChildren (const std::string& name,
00939 bool keep = true)
00940 { return removeChildren(name.c_str(), keep); }
00941
00942
00943
00944
00945
00946
00950 bool alias (SGPropertyNode * target);
00951
00952
00956 bool alias (const char * path);
00957
00961 bool alias (const std::string& path)
00962 { return alias(path.c_str()); }
00963
00964
00968 bool unalias ();
00969
00970
00974 bool isAlias () const { return (_type == simgear::props::ALIAS); }
00975
00976
00980 SGPropertyNode * getAliasTarget ();
00981
00982
00986 const SGPropertyNode * getAliasTarget () const;
00987
00988
00989
00990
00991
00992
00993
00997 const char * getPath (bool simplify = false) const;
00998
00999
01003 SGPropertyNode * getRootNode ();
01004
01005
01009 const SGPropertyNode * getRootNode () const;
01010
01011
01015 SGPropertyNode * getNode (const char * relative_path, bool create = false);
01016
01020 SGPropertyNode * getNode (const std::string& relative_path, bool create = false)
01021 { return getNode(relative_path.c_str(), create); }
01022
01033 SGPropertyNode * getNode (const char * relative_path, int index,
01034 bool create = false);
01035
01046 SGPropertyNode * getNode (const std::string& relative_path, int index,
01047 bool create = false)
01048 { return getNode(relative_path.c_str(), index, create); }
01049
01053 const SGPropertyNode * getNode (const char * relative_path) const;
01054
01058 const SGPropertyNode * getNode (const std::string& relative_path) const
01059 { return getNode(relative_path.c_str()); }
01060
01061
01068 const SGPropertyNode * getNode (const char * relative_path,
01069 int index) const;
01070
01077 const SGPropertyNode * getNode (const std::string& relative_path,
01078 int index) const
01079 { return getNode(relative_path.c_str(), index); }
01080
01081
01082
01083
01084
01088 bool getAttribute (Attribute attr) const { return ((_attr & attr) != 0); }
01089
01090
01094 void setAttribute (Attribute attr, bool state) {
01095 (state ? _attr |= attr : _attr &= ~attr);
01096 }
01097
01098
01102 int getAttributes () const { return _attr; }
01103
01104
01108 void setAttributes (int attr) { _attr = attr; }
01109
01110
01111
01112
01113
01114
01115
01119 simgear::props::Type getType () const;
01120
01121
01125 bool getBoolValue () const;
01126
01127
01131 int getIntValue () const;
01132
01133
01137 long getLongValue () const;
01138
01139
01143 float getFloatValue () const;
01144
01145
01149 double getDoubleValue () const;
01150
01151
01155 const char * getStringValue () const;
01156
01161 template<typename T>
01162 T getValue(typename boost::enable_if_c<simgear::props::PropertyTraits<T>::Internal>
01163 ::type* dummy = 0) const;
01164
01165 template<typename T>
01166 T getValue(typename boost::disable_if_c<simgear::props::PropertyTraits<T>::Internal>
01167 ::type* dummy = 0) const;
01168
01172 bool setBoolValue (bool value);
01173
01174
01178 bool setIntValue (int value);
01179
01180
01184 bool setLongValue (long value);
01185
01186
01190 bool setFloatValue (float value);
01191
01192
01196 bool setDoubleValue (double value);
01197
01198
01202 bool setStringValue (const char * value);
01203
01207 bool setStringValue (const std::string& value)
01208 { return setStringValue(value.c_str()); }
01209
01210
01214 bool setUnspecifiedValue (const char * value);
01215
01216 template<typename T>
01217 bool setValue(const T& val,
01218 typename boost::enable_if_c<simgear::props::PropertyTraits<T>::Internal>
01219 ::type* dummy = 0);
01220
01221 template<typename T>
01222 bool setValue(const T& val,
01223 typename boost::disable_if_c<simgear::props::PropertyTraits<T>::Internal>
01224 ::type* dummy = 0);
01225
01226 template<int N>
01227 bool setValue(const char (&val)[N])
01228 {
01229 return setValue(&val[0]);
01230 }
01231
01235 std::ostream& printOn(std::ostream& stream) const;
01236
01237
01238
01239
01240
01241
01245 bool isTied () const { return _tied; }
01246
01250 template<typename T>
01251 bool tie(const SGRawValue<T> &rawValue, bool useDefault = true);
01252
01256 bool untie ();
01257
01258
01259
01260
01261
01262
01263
01264
01268 simgear::props::Type getType (const char * relative_path) const;
01269
01273 simgear::props::Type getType (const std::string& relative_path) const
01274 { return getType(relative_path.c_str()); }
01275
01279 bool hasValue (const char * relative_path) const;
01280
01284 bool hasValue (const std::string& relative_path) const
01285 { return hasValue(relative_path.c_str()); }
01286
01290 bool getBoolValue (const char * relative_path,
01291 bool defaultValue = false) const;
01292
01296 bool getBoolValue (const std::string& relative_path,
01297 bool defaultValue = false) const
01298 { return getBoolValue(relative_path.c_str(), defaultValue); }
01299
01303 int getIntValue (const char * relative_path,
01304 int defaultValue = 0) const;
01305
01309 int getIntValue (const std::string& relative_path,
01310 int defaultValue = 0) const
01311 { return getIntValue(relative_path.c_str(), defaultValue); }
01312
01313
01317 long getLongValue (const char * relative_path,
01318 long defaultValue = 0L) const;
01319
01323 long getLongValue (const std::string& relative_path,
01324 long defaultValue = 0L) const
01325 { return getLongValue(relative_path.c_str(), defaultValue); }
01326
01330 float getFloatValue (const char * relative_path,
01331 float defaultValue = 0.0f) const;
01332
01336 float getFloatValue (const std::string& relative_path,
01337 float defaultValue = 0.0f) const
01338 { return getFloatValue(relative_path.c_str(), defaultValue); }
01339
01340
01344 double getDoubleValue (const char * relative_path,
01345 double defaultValue = 0.0) const;
01346
01350 double getDoubleValue (const std::string& relative_path,
01351 double defaultValue = 0.0) const
01352 { return getDoubleValue(relative_path.c_str(), defaultValue); }
01353
01357 const char * getStringValue (const char * relative_path,
01358 const char * defaultValue = "") const;
01359
01360
01364 const char * getStringValue (const std::string& relative_path,
01365 const char * defaultValue = "") const
01366 { return getStringValue(relative_path.c_str(), defaultValue); }
01367
01368
01372 bool setBoolValue (const char * relative_path, bool value);
01373
01377 bool setBoolValue (const std::string& relative_path, bool value)
01378 { return setBoolValue(relative_path.c_str(), value); }
01379
01380
01384 bool setIntValue (const char * relative_path, int value);
01385
01389 bool setIntValue (const std::string& relative_path, int value)
01390 { return setIntValue(relative_path.c_str(), value); }
01391
01392
01396 bool setLongValue (const char * relative_path, long value);
01397
01401 bool setLongValue (const std::string& relative_path, long value)
01402 { return setLongValue(relative_path.c_str(), value); }
01403
01404
01408 bool setFloatValue (const char * relative_path, float value);
01409
01413 bool setFloatValue (const std::string& relative_path, float value)
01414 { return setFloatValue(relative_path.c_str(), value); }
01415
01416
01420 bool setDoubleValue (const char * relative_path, double value);
01421
01425 bool setDoubleValue (const std::string& relative_path, double value)
01426 { return setDoubleValue(relative_path.c_str(), value); }
01427
01428
01432 bool setStringValue (const char * relative_path, const char * value);
01433
01434 bool setStringValue(const char * relative_path, const std::string& value)
01435 { return setStringValue(relative_path, value.c_str()); }
01439 bool setStringValue (const std::string& relative_path, const char * value)
01440 { return setStringValue(relative_path.c_str(), value); }
01441
01442 bool setStringValue (const std::string& relative_path,
01443 const std::string& value)
01444 { return setStringValue(relative_path.c_str(), value.c_str()); }
01445
01449 bool setUnspecifiedValue (const char * relative_path, const char * value);
01450
01451
01455 bool isTied (const char * relative_path) const;
01456
01460 bool isTied (const std::string& relative_path) const
01461 { return isTied(relative_path.c_str()); }
01462
01466 bool tie (const char * relative_path, const SGRawValue<bool> &rawValue,
01467 bool useDefault = true);
01468
01472 bool tie (const std::string& relative_path, const SGRawValue<bool> &rawValue,
01473 bool useDefault = true)
01474 { return tie(relative_path.c_str(), rawValue, useDefault); }
01475
01476
01480 bool tie (const char * relative_path, const SGRawValue<int> &rawValue,
01481 bool useDefault = true);
01482
01486 bool tie (const std::string& relative_path, const SGRawValue<int> &rawValue,
01487 bool useDefault = true)
01488 { return tie(relative_path.c_str(), rawValue, useDefault); }
01489
01490
01494 bool tie (const char * relative_path, const SGRawValue<long> &rawValue,
01495 bool useDefault = true);
01496
01500 bool tie (const std::string& relative_path, const SGRawValue<long> &rawValue,
01501 bool useDefault = true)
01502 { return tie(relative_path.c_str(), rawValue, useDefault); }
01503
01504
01508 bool tie (const char * relative_path, const SGRawValue<float> &rawValue,
01509 bool useDefault = true);
01510
01514 bool tie (const std::string& relative_path, const SGRawValue<float> &rawValue,
01515 bool useDefault = true)
01516 { return tie(relative_path.c_str(), rawValue, useDefault); }
01517
01518
01522 bool tie (const char * relative_path, const SGRawValue<double> &rawValue,
01523 bool useDefault = true);
01524
01528 bool tie (const std::string& relative_path, const SGRawValue<double> &rawValue,
01529 bool useDefault = true)
01530 { return tie(relative_path.c_str(), rawValue, useDefault); }
01531
01532
01536 bool tie (const char * relative_path, const SGRawValue<const char *> &rawValue,
01537 bool useDefault = true);
01538
01542 bool tie (const std::string& relative_path, const SGRawValue<const char*> &rawValue,
01543 bool useDefault = true)
01544 { return tie(relative_path.c_str(), rawValue, useDefault); }
01545
01546
01550 bool untie (const char * relative_path);
01551
01555 bool untie (const std::string& relative_path)
01556 { return untie(relative_path.c_str()); }
01557
01558
01563 void addChangeListener (SGPropertyChangeListener * listener,
01564 bool initial = false);
01565
01566
01570 void removeChangeListener (SGPropertyChangeListener * listener);
01571
01572
01576 int nListeners () const { return _listeners ? (int)_listeners->size() : 0; }
01577
01578
01582 void fireValueChanged ();
01583
01584
01588 void fireChildAdded (SGPropertyNode * child);
01589
01590
01594 void fireChildRemoved (SGPropertyNode * child);
01595
01596
01600 void clearValue ();
01601
01611 static bool compare (const SGPropertyNode& lhs, const SGPropertyNode& rhs);
01612
01613 protected:
01614
01615 void fireValueChanged (SGPropertyNode * node);
01616 void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
01617 void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
01618
01622 SGPropertyNode (const std::string& name, int index, SGPropertyNode * parent);
01623 template<typename Itr>
01624 SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent);
01625
01626 private:
01627
01628
01629 bool get_bool () const;
01630 int get_int () const;
01631 long get_long () const;
01632 float get_float () const;
01633 double get_double () const;
01634 const char * get_string () const;
01635
01636
01637 bool set_bool (bool value);
01638 bool set_int (int value);
01639 bool set_long (long value);
01640 bool set_float (float value);
01641 bool set_double (double value);
01642 bool set_string (const char * value);
01643
01644
01648 const char * make_string () const;
01649
01653 void trace_read () const;
01654
01655
01659 void trace_write () const;
01660
01661
01665 void remove_from_path_caches();
01666
01667
01668 class hash_table;
01669
01670 int _index;
01671 std::string _name;
01674 SGPropertyNode * _parent;
01675 simgear::PropertyList _children;
01676 simgear::PropertyList _removedChildren;
01677 std::vector<hash_table *> _linkedNodes;
01678 mutable std::string _path;
01679 mutable std::string _buffer;
01680 hash_table * _path_cache;
01681 simgear::props::Type _type;
01682 bool _tied;
01683 int _attr;
01684
01685
01686 union {
01687 SGPropertyNode * alias;
01688 SGRaw* val;
01689 } _value;
01690
01691 union {
01692 bool bool_val;
01693 int int_val;
01694 long long_val;
01695 float float_val;
01696 double double_val;
01697 char * string_val;
01698 } _local_val;
01699
01700 std::vector<SGPropertyChangeListener *> * _listeners;
01701
01702
01706 void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
01707 bool remove_linked_node (hash_table * node);
01708
01709
01710
01714 class hash_table {
01715 public:
01716
01720 class entry {
01721 public:
01722 entry ();
01723 ~entry ();
01724 const char * get_key () { return _key.c_str(); }
01725 void set_key (const char * key);
01726 SGPropertyNode * get_value () { return _value; }
01727 void set_value (SGPropertyNode * value);
01728 private:
01729 std::string _key;
01730 SGSharedPtr<SGPropertyNode> _value;
01731 };
01732
01733
01737 class bucket {
01738 public:
01739 bucket ();
01740 ~bucket ();
01741 entry * get_entry (const char * key, bool create = false);
01742 bool erase (SGPropertyNode * node);
01743 void clear (hash_table * owner);
01744 private:
01745 int _length;
01746 entry ** _entries;
01747 };
01748
01749 friend class bucket;
01750
01751 hash_table ();
01752 ~hash_table ();
01753 SGPropertyNode * get (const char * key);
01754 void put (const char * key, SGPropertyNode * value);
01755 bool erase (SGPropertyNode * node);
01756
01757 private:
01758 unsigned int hashcode (const char * key);
01759 unsigned int _data_length;
01760 bucket ** _data;
01761 };
01762
01763 template<typename Itr>
01764 SGPropertyNode * getChildImpl (Itr begin, Itr end, int index = 0, bool create = false);
01765
01766 template<typename Itr>
01767 SGPropertyNode* getExistingChild (Itr begin, Itr end, int index, bool create);
01768
01769 template<typename SplitItr>
01770 friend SGPropertyNode* find_node_aux(SGPropertyNode * current, SplitItr& itr,
01771 bool create, int last_index);
01772
01773 friend size_t hash_value(const SGPropertyNode& node);
01774 };
01775
01776
01777 template<typename T>
01778 T getValue(const SGPropertyNode*);
01779
01780 template<>
01781 inline bool getValue<bool>(const SGPropertyNode* node) { return node->getBoolValue(); }
01782
01783 template<>
01784 inline int getValue<int>(const SGPropertyNode* node) { return node->getIntValue(); }
01785
01786 template<>
01787 inline long getValue<long>(const SGPropertyNode* node) { return node->getLongValue(); }
01788
01789 template<>
01790 inline float getValue<float>(const SGPropertyNode* node)
01791 {
01792 return node->getFloatValue();
01793 }
01794
01795 template<>
01796 inline double getValue<double>(const SGPropertyNode* node)
01797 {
01798 return node->getDoubleValue();
01799 }
01800
01801 template<>
01802 inline const char * getValue<const char*>(const SGPropertyNode* node)
01803 {
01804 return node->getStringValue ();
01805 }
01806
01807 inline bool setValue(SGPropertyNode* node, bool value)
01808 {
01809 return node->setBoolValue(value);
01810 }
01811
01812 inline bool setValue(SGPropertyNode* node, int value)
01813 {
01814 return node->setIntValue(value);
01815 }
01816
01817 inline bool setValue(SGPropertyNode* node, long value)
01818 {
01819 return node->setLongValue(value);
01820 }
01821
01822 inline bool setValue(SGPropertyNode* node, float value)
01823 {
01824 return node->setFloatValue(value);
01825 }
01826
01827 inline bool setValue(SGPropertyNode* node, double value)
01828 {
01829 return node->setDoubleValue(value);
01830 }
01831
01832 inline bool setValue(SGPropertyNode* node, const char* value)
01833 {
01834 return node->setStringValue(value);
01835 }
01836
01837 inline bool setValue (SGPropertyNode* node, const std::string& value)
01838 {
01839 return node->setStringValue(value.c_str());
01840 }
01841
01842 template<typename T>
01843 bool SGPropertyNode::tie(const SGRawValue<T> &rawValue, bool useDefault)
01844 {
01845 using namespace simgear::props;
01846 if (_type == ALIAS || _tied)
01847 return false;
01848
01849 useDefault = useDefault && hasValue();
01850 T old_val = SGRawValue<T>::DefaultValue();
01851 if (useDefault)
01852 old_val = getValue<T>(this);
01853 clearValue();
01854 if (PropertyTraits<T>::Internal)
01855 _type = PropertyTraits<T>::type_tag;
01856 else
01857 _type = EXTENDED;
01858 _tied = true;
01859 _value.val = rawValue.clone();
01860 if (useDefault)
01861 setValue(old_val);
01862 return true;
01863 }
01864
01865 template<>
01866 bool SGPropertyNode::tie (const SGRawValue<const char *> &rawValue,
01867 bool useDefault);
01868
01869 template<typename T>
01870 T SGPropertyNode::getValue(typename boost::disable_if_c<simgear::props
01871 ::PropertyTraits<T>::Internal>::type* dummy) const
01872 {
01873 using namespace simgear::props;
01874 if (_attr == (READ|WRITE) && _type == EXTENDED
01875 && _value.val->getType() == PropertyTraits<T>::type_tag) {
01876 return static_cast<SGRawValue<T>*>(_value.val)->getValue();
01877 }
01878 if (getAttribute(TRACE_READ))
01879 trace_read();
01880 if (!getAttribute(READ))
01881 return SGRawValue<T>::DefaultValue();
01882 switch (_type) {
01883 case EXTENDED:
01884 if (_value.val->getType() == PropertyTraits<T>::type_tag)
01885 return static_cast<SGRawValue<T>*>(_value.val)->getValue();
01886 break;
01887 case STRING:
01888 case UNSPECIFIED:
01889 return simgear::parseString<T>(make_string());
01890 break;
01891 default:
01892 break;
01893 }
01894 return SGRawValue<T>::DefaultValue();
01895 }
01896
01897 template<typename T>
01898 inline T SGPropertyNode::getValue(typename boost::enable_if_c<simgear::props
01899 ::PropertyTraits<T>::Internal>::type* dummy) const
01900 {
01901 return ::getValue<T>(this);
01902 }
01903
01904 template<typename T>
01905 bool SGPropertyNode::setValue(const T& val,
01906 typename boost::disable_if_c<simgear::props
01907 ::PropertyTraits<T>::Internal>::type* dummy)
01908 {
01909 using namespace simgear::props;
01910 if (_attr == (READ|WRITE) && _type == EXTENDED
01911 && _value.val->getType() == PropertyTraits<T>::type_tag) {
01912 static_cast<SGRawValue<T>*>(_value.val)->setValue(val);
01913 return true;
01914 }
01915 if (getAttribute(WRITE)
01916 && ((_type == EXTENDED
01917 && _value.val->getType() == PropertyTraits<T>::type_tag)
01918 || _type == NONE || _type == UNSPECIFIED)) {
01919 if (_type == NONE || _type == UNSPECIFIED) {
01920 clearValue();
01921 _type = EXTENDED;
01922 _value.val = new SGRawValueContainer<T>(val);
01923 } else {
01924 static_cast<SGRawValue<T>*>(_value.val)->setValue(val);
01925 }
01926 if (getAttribute(TRACE_WRITE))
01927 trace_write();
01928 return true;
01929 }
01930 return false;
01931 }
01932
01933 template<typename T>
01934 inline bool SGPropertyNode::setValue(const T& val,
01935 typename boost::enable_if_c<simgear::props
01936 ::PropertyTraits<T>::Internal>::type* dummy)
01937 {
01938 return ::setValue(this, val);
01939 }
01940
01944 inline SGPropertyNode* makeChild(SGPropertyNode* parent, const char* name,
01945 int index = 0)
01946 {
01947 return parent->getChild(name, index, true);
01948 }
01949
01954 namespace simgear
01955 {
01956 template<typename StringType>
01957 inline SGPropertyNode* makeNode(SGPropertyNode* parent, const StringType& name)
01958 {
01959 return parent->getNode(name, true);
01960 }
01961 }
01962
01963
01964 size_t hash_value(const SGPropertyNode& node);
01965
01966
01967
01968 namespace simgear
01969 {
01970 namespace props
01971 {
01972 struct Compare
01973 {
01974 bool operator()(const SGPropertyNode* lhs, const SGPropertyNode* rhs) const
01975 {
01976 return SGPropertyNode::compare(*lhs, *rhs);
01977 }
01978 bool operator()(SGPropertyNode_ptr lhs, const SGPropertyNode* rhs) const
01979 {
01980 return SGPropertyNode::compare(*lhs, *rhs);
01981 }
01982 bool operator()(const SGPropertyNode* lhs, SGPropertyNode_ptr rhs) const
01983 {
01984 return SGPropertyNode::compare(*lhs, *rhs);
01985 }
01986 bool operator()(SGPropertyNode_ptr lhs, SGPropertyNode_ptr rhs) const
01987 {
01988 return SGPropertyNode::compare(*lhs, *rhs);
01989 }
01990 };
01991
01992 struct Hash
01993 {
01994 size_t operator()(const SGPropertyNode* node) const
01995 {
01996 return hash_value(*node);
01997 }
01998 size_t operator()(SGPropertyNode_ptr node) const
01999 {
02000 return hash_value(*node);
02001 }
02002 };
02003 }
02004 }
02005 #endif // __PROPS_HXX
02006
02007