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.
7 * See props.html for documentation [replace with URL when available].
19 #include <simgear/compiler.h>
29 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
30 SG_USING_STD(istream);
31 SG_USING_STD(ostream);
35 #pragma warn A sloppy coder has defined ALIAS as a macro!
40 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
45 #pragma warn A sloppy coder has defined BOOL as a macro!
50 #pragma warn A sloppy coder has defined INT as a macro!
55 #pragma warn A sloppy coder has defined LONG as a macro!
60 #pragma warn A sloppy coder has defined FLOAT as a macro!
65 #pragma warn A sloppy coder has defined DOUBLE as a macro!
70 #pragma warn A sloppy coder has defined STRING as a macro!
76 ////////////////////////////////////////////////////////////////////////
79 // This is the mechanism that information-providing routines can
80 // use to link their own values to the property manager. Any
81 // SGValue can be tied to a raw value and then untied again.
82 ////////////////////////////////////////////////////////////////////////
86 * Abstract base class for a raw value.
88 * Unlike values, raw values are not persistent -- the raw value can
89 * change frequently, but the changes are not visible to the application.
91 * The SGValue class always keeps a *copy* of a raw value, not the
92 * original one passed to it; if you override a derived class but do
93 * not replace the clone() method, strange things will happen.
95 * All raw values must implement getValue, setValue, and clone for the
102 static const T DefaultValue; // Default for this kind of raw value.
105 virtual ~SGRawValue () {}
106 virtual T getValue () const = 0;
107 virtual bool setValue (T value) = 0;
108 virtual SGRawValue * clone () const = 0;
113 * A value managed internally.
115 * Instances of this class are created automatically, by default,
116 * by the SGValue class; ordinarily the application should not
120 class SGRawValueInternal : public SGRawValue<T>
123 SGRawValueInternal () {}
124 SGRawValueInternal (T value) : _value(value) {}
125 virtual ~SGRawValueInternal () {}
126 virtual T getValue () const { return _value; }
127 virtual bool setValue (T value) { _value = value; return true; }
128 virtual SGRawValue<T> * clone () const {
129 return new SGRawValueInternal<T>(_value);
137 * A value managed through a direct pointer.
139 * This is the most efficient way to tie an external value, but also
140 * the most dangerous, because there is no way for the supplier to
141 * perform bounds checking and derived calculations except by polling
142 * the variable to see if it has changed.
145 class SGRawValuePointer : public SGRawValue<T>
148 SGRawValuePointer (T * ptr) : _ptr(ptr) {}
149 virtual ~SGRawValuePointer () {}
150 virtual T getValue () const { return *_ptr; }
151 virtual bool setValue (T value) { *_ptr = value; return true; }
152 virtual SGRawValue<T> * clone () const {
153 return new SGRawValuePointer<T>(_ptr);
161 * A value managed through static functions.
163 * A read-only value will not have a setter; a write-only value will
167 class SGRawValueFunctions : public SGRawValue<T>
170 typedef T (*getter_t)();
171 typedef void (*setter_t)(T);
172 SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
173 : _getter(getter), _setter(setter) {}
174 virtual ~SGRawValueFunctions () {}
175 virtual T getValue () const {
176 if (_getter) return (*_getter)();
177 else return SGRawValue<T>::DefaultValue;
179 virtual bool setValue (T value) {
180 if (_setter) { (*_setter)(value); return true; }
183 virtual SGRawValue<T> * clone () const {
184 return new SGRawValueFunctions<T>(_getter,_setter);
193 * An indexed value managed through static functions.
195 * A read-only value will not have a setter; a write-only value will
199 class SGRawValueFunctionsIndexed : public SGRawValue<T>
202 typedef T (*getter_t)(int);
203 typedef void (*setter_t)(int,T);
204 SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
205 : _index(index), _getter(getter), _setter(setter) {}
206 virtual ~SGRawValueFunctionsIndexed () {}
207 virtual T getValue () const {
208 if (_getter) return (*_getter)(_index);
209 else return SGRawValue<T>::DefaultValue;
211 virtual bool setValue (T value) {
212 if (_setter) { (*_setter)(_index, value); return true; }
215 virtual SGRawValue<T> * clone () const {
216 return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
226 * A value managed through an object and access methods.
228 * A read-only value will not have a setter; a write-only value will
231 template <class C, class T>
232 class SGRawValueMethods : public SGRawValue<T>
235 typedef T (C::*getter_t)() const;
236 typedef void (C::*setter_t)(T);
237 SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
238 : _obj(obj), _getter(getter), _setter(setter) {}
239 virtual ~SGRawValueMethods () {}
240 virtual T getValue () const {
241 if (_getter) { return (_obj.*_getter)(); }
242 else { return SGRawValue<T>::DefaultValue; }
244 virtual bool setValue (T value) {
245 if (_setter) { (_obj.*_setter)(value); return true; }
248 virtual SGRawValue<T> * clone () const {
249 return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
259 * An indexed value managed through an object and access methods.
261 * A read-only value will not have a setter; a write-only value will
264 template <class C, class T>
265 class SGRawValueMethodsIndexed : public SGRawValue<T>
268 typedef T (C::*getter_t)(int) const;
269 typedef void (C::*setter_t)(int, T);
270 SGRawValueMethodsIndexed (C &obj, int index,
271 getter_t getter = 0, setter_t setter = 0)
272 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
273 virtual ~SGRawValueMethodsIndexed () {}
274 virtual T getValue () const {
275 if (_getter) { return (_obj.*_getter)(_index); }
276 else { return SGRawValue<T>::DefaultValue; }
278 virtual bool setValue (T value) {
279 if (_setter) { (_obj.*_setter)(_index, value); return true; }
282 virtual SGRawValue<T> * clone () const {
283 return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
297 * This is the value that property-list clients see. It is a
298 * persistent layer over the possibly-changing raw value; once a
299 * client gets an SGValue from the property manager, the pointer
300 * will be good for the life of the property manager itself, no
301 * matter how often the pointer is tied or untied.
316 SGValue (const SGValue &value);
319 Type getType () const;
321 SGValue * getAlias ();
322 const SGValue * getAlias () const;
323 bool alias (SGValue * alias);
325 bool isAlias () const { return _type == ALIAS; }
327 bool getBoolValue () const;
328 int getIntValue () const;
329 long getLongValue () const;
330 float getFloatValue () const;
331 double getDoubleValue () const;
332 string getStringValue () const;
334 bool setBoolValue (bool value);
335 bool setIntValue (int value);
336 bool setLongValue (long value);
337 bool setFloatValue (float value);
338 bool setDoubleValue (double value);
339 bool setStringValue (string value);
340 bool setUnknownValue (string value);
342 bool isTied () const { return _tied; }
344 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
345 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
346 bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
347 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
348 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
349 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
364 // The right kind of pointer...
367 SGRawValue<bool> * bool_val;
368 SGRawValue<int> * int_val;
369 SGRawValue<long> * long_val;
370 SGRawValue<float> * float_val;
371 SGRawValue<double> * double_val;
372 SGRawValue<string> * string_val;
380 * A node in a property tree.
388 virtual ~SGPropertyNode ();
391 bool hasValue () const { return (_value != 0); }
392 SGValue * getValue () { return _value; }
393 SGValue * getValue (bool create);
394 const SGValue * getValue () const { return _value; }
395 const string &getName () const { return _name; }
396 const int getIndex () const { return _index; }
397 SGPropertyNode * getParent () { return _parent; }
398 const SGPropertyNode * getParent () const { return _parent; }
401 bool alias (SGPropertyNode * target);
402 bool alias (const string &path);
404 bool isAlias () const;
405 SGPropertyNode * getAliasTarget ();
406 const SGPropertyNode * getAliasTarget () const;
409 const int nChildren () const { return _children.size(); }
410 SGPropertyNode * getChild (int position);
411 const SGPropertyNode * getChild (int position) const;
412 SGPropertyNode * getChild (const string &name, int index = 0,
413 bool create = false);
414 const SGPropertyNode * getChild (const string &name, int index = 0) const;
416 vector<SGPropertyNode *> getChildren (const string &name);
417 vector<const SGPropertyNode *> getChildren (const string &name) const;
420 string getPath (bool simplify = false) const;
422 // Relative or absolute paths.
423 SGPropertyNode * getRootNode ();
424 const SGPropertyNode * getRootNode () const;
425 SGPropertyNode * getNode (const string &relative_path, bool create = false);
426 const SGPropertyNode * getNode (const string &relative_path) const;
428 // Value-related stuff.
429 SGValue::Type getType () const;
431 bool getBoolValue () const;
432 int getIntValue () const;
433 long getLongValue () const;
434 float getFloatValue () const;
435 double getDoubleValue () const;
436 string getStringValue () const;
438 bool setBoolValue (bool value);
439 bool setIntValue (int value);
440 bool setLongValue (long value);
441 bool setFloatValue (float value);
442 bool setDoubleValue (double value);
443 bool setStringValue (string value);
444 bool setUnknownValue (string value);
446 bool isTied () const;
448 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
449 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
450 bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
451 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
452 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
453 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
457 // Values from paths.
458 bool hasValue (const string &relative_path) const;
459 SGValue * getValue (const string &relative_path, bool create = false);
460 const SGValue * getValue (const string &relative_path) const;
462 SGValue::Type getType (const string &relative_path) const;
464 bool getBoolValue (const string &relative_path,
465 bool defaultValue = false) const;
466 int getIntValue (const string &relative_path,
467 int defaultValue = 0) const;
468 long getLongValue (const string &relative_path,
469 long defaultValue = 0L) const;
470 float getFloatValue (const string &relative_path,
471 float defaultValue = 0.0) const;
472 double getDoubleValue (const string &relative_path,
473 double defaultValue = 0.0L) const;
474 string getStringValue (const string &relative_path,
475 string defaultValue = "") const;
477 bool setBoolValue (const string &relative_path, bool value);
478 bool setIntValue (const string &relative_path, int value);
479 bool setLongValue (const string &relative_path, long value);
480 bool setFloatValue (const string &relative_path, float value);
481 bool setDoubleValue (const string &relative_path, double value);
482 bool setStringValue (const string &relative_path, string value);
483 bool setUnknownValue (const string &relative_path, string value);
485 bool isTied (const string &relative_path) const;
487 bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
488 bool useDefault = true);
489 bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
490 bool useDefault = true);
491 bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
492 bool useDefault = true);
493 bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
494 bool useDefault = true);
495 bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
496 bool useDefault = true);
497 bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
498 bool useDefault = true);
500 bool untie (const string &relative_path);
504 SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
508 SGPropertyNode (const SGPropertyNode &node) {}
513 SGPropertyNode * _parent;
514 vector<SGPropertyNode *> _children;
515 mutable SGPropertyNode * _target;
521 ////////////////////////////////////////////////////////////////////////
523 ////////////////////////////////////////////////////////////////////////
525 bool readProperties (istream &input, SGPropertyNode * start_node,
526 const string &base = "");
527 bool readProperties (const string &file, SGPropertyNode * start_node);
528 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
529 bool writeProperties (const string &file, const SGPropertyNode * start_node);
530 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
533 #endif // __PROPS_HXX