1 // props.hxx - interface definition for a property list.
2 // Started Fall 2000 by David Megginson, david@megginson.com
3 // This code is released into the Public Domain.
5 // See props.html for documentation [replace with URL when available].
16 #include <simgear/compiler.h>
26 #if !defined(FG_HAVE_NATIVE_SGI_COMPILERS)
27 FG_USING_STD(istream);
28 FG_USING_STD(ostream);
32 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
37 #pragma warn A sloppy coder has defined BOOL as a macro!
42 #pragma warn A sloppy coder has defined INT as a macro!
47 #pragma warn A sloppy coder has defined FLOAT as a macro!
52 #pragma warn A sloppy coder has defined DOUBLE as a macro!
57 #pragma warn A sloppy coder has defined STRING as a macro!
63 ////////////////////////////////////////////////////////////////////////
66 // This is the mechanism that information-providing routines can
67 // use to link their own values to the property manager. Any
68 // SGValue can be tied to a raw value and then untied again.
69 ////////////////////////////////////////////////////////////////////////
73 * Abstract base class for a raw value.
75 * Unlike values, raw values are not persistent -- the raw value can
76 * change frequently, but the changes are not visible to the application.
78 * The SGValue class always keeps a *copy* of a raw value, not the
79 * original one passed to it; if you override a derived class but do
80 * not replace the clone() method, strange things will happen.
82 * All raw values must implement getValue, setValue, and clone for the
89 static const T DefaultValue; // Default for this kind of raw value.
92 virtual ~SGRawValue () {}
93 virtual T getValue () const = 0;
94 virtual bool setValue (T value) = 0;
95 virtual SGRawValue * clone () const = 0;
100 * A value managed internally.
102 * Instances of this class are created automatically, by default,
103 * by the SGValue class; ordinarily the application should not
107 class SGRawValueInternal : public SGRawValue<T>
110 SGRawValueInternal () {}
111 SGRawValueInternal (T value) : _value(value) {}
112 virtual ~SGRawValueInternal () {}
113 virtual T getValue () const { return _value; }
114 virtual bool setValue (T value) { _value = value; return true; }
115 virtual SGRawValue<T> * clone () const {
116 return new SGRawValueInternal<T>(_value);
124 * A value managed through a direct pointer.
126 * This is the most efficient way to tie an external value, but also
127 * the most dangerous, because there is no way for the supplier to
128 * perform bounds checking and derived calculations except by polling
129 * the variable to see if it has changed.
132 class SGRawValuePointer : public SGRawValue<T>
135 SGRawValuePointer (T * ptr) : _ptr(ptr) {}
136 virtual ~SGRawValuePointer () {}
137 virtual T getValue () const { return *_ptr; }
138 virtual bool setValue (T value) { *_ptr = value; return true; }
139 virtual SGRawValue<T> * clone () const {
140 return new SGRawValuePointer<T>(_ptr);
148 * A value managed through static functions.
150 * A read-only value will not have a setter; a write-only value will
154 class SGRawValueFunctions : public SGRawValue<T>
157 typedef T (*getter_t)();
158 typedef void (*setter_t)(T);
159 SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
160 : _getter(getter), _setter(setter) {}
161 virtual ~SGRawValueFunctions () {}
162 virtual T getValue () const {
163 if (_getter) return (*_getter)();
164 else return DefaultValue;
166 virtual bool setValue (T value) {
167 if (_setter) { (*_setter)(value); return true; }
170 virtual SGRawValue<T> * clone () const {
171 return new SGRawValueFunctions<T>(_getter,_setter);
180 * An indexed value managed through static functions.
182 * A read-only value will not have a setter; a write-only value will
186 class SGRawValueFunctionsIndexed : public SGRawValue<T>
189 typedef T (*getter_t)(int);
190 typedef void (*setter_t)(int,T);
191 SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
192 : _index(index), _getter(getter), _setter(setter) {}
193 virtual ~SGRawValueFunctionsIndexed () {}
194 virtual T getValue () const {
195 if (_getter) return (*_getter)(_index);
196 else return DefaultValue;
198 virtual bool setValue (T value) {
199 if (_setter) { (*_setter)(_index, value); return true; }
202 virtual SGRawValue<T> * clone () const {
203 return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
213 * A value managed through an object and access methods.
215 * A read-only value will not have a setter; a write-only value will
218 template <class C, class T>
219 class SGRawValueMethods : public SGRawValue<T>
222 typedef T (C::*getter_t)() const;
223 typedef void (C::*setter_t)(T);
224 SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
225 : _obj(obj), _getter(getter), _setter(setter) {}
226 virtual ~SGRawValueMethods () {}
227 virtual T getValue () const {
228 if (_getter) { return (_obj.*_getter)(); }
229 else { return DefaultValue; }
231 virtual bool setValue (T value) {
232 if (_setter) { (_obj.*_setter)(value); return true; }
235 virtual SGRawValue<T> * clone () const {
236 return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
246 * An indexed value managed through an object and access methods.
248 * A read-only value will not have a setter; a write-only value will
251 template <class C, class T>
252 class SGRawValueMethodsIndexed : public SGRawValue<T>
255 typedef T (C::*getter_t)(int) const;
256 typedef void (C::*setter_t)(int, T);
257 SGRawValueMethodsIndexed (C &obj, int index,
258 getter_t getter = 0, setter_t setter = 0)
259 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
260 virtual ~SGRawValueMethodsIndexed () {}
261 virtual T getValue () const {
262 if (_getter) { return (_obj.*_getter)(_index); }
263 else { return DefaultValue; }
265 virtual bool setValue (T value) {
266 if (_setter) { (_obj.*_setter)(_index, value); return true; }
269 virtual SGRawValue<T> * clone () const {
270 return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
281 ////////////////////////////////////////////////////////////////////////
284 // This is the value that property-list clients see. It is a
285 // persistent layer over the possibly-changing raw value; once a
286 // client gets an SGValue from the property manager, the pointer
287 // will be good for the life of the property manager itself, no
288 // matter how often the pointer is tied or untied.
289 ////////////////////////////////////////////////////////////////////////
303 SGValue (const SGValue &value);
306 Type getType () const { return _type; }
308 bool getBoolValue () const;
309 int getIntValue () const;
310 float getFloatValue () const;
311 double getDoubleValue () const;
312 string getStringValue () const;
314 bool setBoolValue (bool value);
315 bool setIntValue (int value);
316 bool setFloatValue (float value);
317 bool setDoubleValue (double value);
318 bool setStringValue (string value);
319 bool setUnknownValue (string value);
321 bool isTied () const { return _tied; }
323 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
324 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
325 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
326 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
327 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
338 // The right kind of pointer...
340 SGRawValue<bool> * bool_val;
341 SGRawValue<int> * int_val;
342 SGRawValue<float> * float_val;
343 SGRawValue<double> * double_val;
344 SGRawValue<string> * string_val;
351 ////////////////////////////////////////////////////////////////////////
352 // A node in a property tree.
353 ////////////////////////////////////////////////////////////////////////
361 virtual ~SGPropertyNode ();
364 bool hasValue () const { return (_value != 0); }
365 SGValue * getValue () { return _value; }
366 const SGValue * getValue () const { return _value; }
367 const string &getName () const { return _name; }
368 const int getIndex () const { return _index; }
369 SGPropertyNode * getParent () { return _parent; }
370 const SGPropertyNode * getParent () const { return _parent; }
373 const int nChildren () const { return _children.size(); }
374 SGPropertyNode * getChild (int position);
375 const SGPropertyNode * getChild (int position) const;
376 SGPropertyNode * getChild (const string &name, int index = 0,
377 bool create = false);
378 const SGPropertyNode * getChild (const string &name, int index = 0) const;
380 vector<SGPropertyNode *> getChildren (const string &name);
381 vector<const SGPropertyNode *> getChildren (const string &name) const;
384 string getPath (bool simplify = false) const;
386 // Relative or absolute paths.
387 SGPropertyNode * getRootNode ();
388 const SGPropertyNode * getRootNode () const;
389 SGPropertyNode * getNode (const string &relative_path, bool create = false);
390 const SGPropertyNode * getNode (const string &relative_path) const;
392 // Value-related stuff.
393 SGValue::Type getType () const;
395 bool getBoolValue () const;
396 int getIntValue () const;
397 float getFloatValue () const;
398 double getDoubleValue () const;
399 string getStringValue () const;
401 bool setBoolValue (bool value);
402 bool setIntValue (int value);
403 bool setFloatValue (float value);
404 bool setDoubleValue (double value);
405 bool setStringValue (string value);
406 bool setUnknownValue (string value);
408 bool isTied () const;
410 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
411 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
412 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
413 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
414 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
418 // Values from paths.
419 bool hasValue (const string &relative_path) const;
420 SGValue * getValue (const string &relative_path, bool create = false);
421 const SGValue * getValue (const string &relative_path) const;
423 SGValue::Type getType (const string &relative_path) const;
425 bool getBoolValue (const string &relative_path,
426 bool defaultValue = false) const;
427 int getIntValue (const string &relative_path,
428 int defaultValue = 0) const;
429 float getFloatValue (const string &relative_path,
430 float defaultValue = 0.0) const;
431 double getDoubleValue (const string &relative_path,
432 double defaultValue = 0.0L) const;
433 string getStringValue (const string &relative_path,
434 string defaultValue = "") const;
436 bool setBoolValue (const string &relative_path, bool value);
437 bool setIntValue (const string &relative_path, int value);
438 bool setFloatValue (const string &relative_path, float value);
439 bool setDoubleValue (const string &relative_path, double value);
440 bool setStringValue (const string &relative_path, string value);
441 bool setUnknownValue (const string &relative_path, string value);
443 bool isTied (const string &relative_path) const;
445 bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
446 bool useDefault = true);
447 bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
448 bool useDefault = true);
449 bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
450 bool useDefault = true);
451 bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
452 bool useDefault = true);
453 bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
454 bool useDefault = true);
456 bool untie (const string &relative_path);
460 SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
464 SGPropertyNode (const SGPropertyNode &node) {}
469 SGPropertyNode * _parent;
470 vector<SGPropertyNode *> _children;
476 ////////////////////////////////////////////////////////////////////////
478 ////////////////////////////////////////////////////////////////////////
480 bool readProperties (istream &input, SGPropertyNode * start_node);
481 bool readProperties (const string &file, SGPropertyNode * start_node);
482 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
483 bool writeProperties (const string &file, const SGPropertyNode * start_node);
484 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
487 #endif // __PROPS_HXX