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(SG_HAVE_NATIVE_SGI_COMPILERS)
27 SG_USING_STD(istream);
28 SG_USING_STD(ostream);
32 #pragma warn A sloppy coder has defined ALIAS as a macro!
37 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
42 #pragma warn A sloppy coder has defined BOOL as a macro!
47 #pragma warn A sloppy coder has defined INT as a macro!
52 #pragma warn A sloppy coder has defined LONG as a macro!
57 #pragma warn A sloppy coder has defined FLOAT as a macro!
62 #pragma warn A sloppy coder has defined DOUBLE as a macro!
67 #pragma warn A sloppy coder has defined STRING as a macro!
73 ////////////////////////////////////////////////////////////////////////
76 // This is the mechanism that information-providing routines can
77 // use to link their own values to the property manager. Any
78 // SGValue can be tied to a raw value and then untied again.
79 ////////////////////////////////////////////////////////////////////////
83 * Abstract base class for a raw value.
85 * Unlike values, raw values are not persistent -- the raw value can
86 * change frequently, but the changes are not visible to the application.
88 * The SGValue class always keeps a *copy* of a raw value, not the
89 * original one passed to it; if you override a derived class but do
90 * not replace the clone() method, strange things will happen.
92 * All raw values must implement getValue, setValue, and clone for the
99 static const T DefaultValue; // Default for this kind of raw value.
102 virtual ~SGRawValue () {}
103 virtual T getValue () const = 0;
104 virtual bool setValue (T value) = 0;
105 virtual SGRawValue * clone () const = 0;
110 * A value managed internally.
112 * Instances of this class are created automatically, by default,
113 * by the SGValue class; ordinarily the application should not
117 class SGRawValueInternal : public SGRawValue<T>
120 SGRawValueInternal () {}
121 SGRawValueInternal (T value) : _value(value) {}
122 virtual ~SGRawValueInternal () {}
123 virtual T getValue () const { return _value; }
124 virtual bool setValue (T value) { _value = value; return true; }
125 virtual SGRawValue<T> * clone () const {
126 return new SGRawValueInternal<T>(_value);
134 * A value managed through a direct pointer.
136 * This is the most efficient way to tie an external value, but also
137 * the most dangerous, because there is no way for the supplier to
138 * perform bounds checking and derived calculations except by polling
139 * the variable to see if it has changed.
142 class SGRawValuePointer : public SGRawValue<T>
145 SGRawValuePointer (T * ptr) : _ptr(ptr) {}
146 virtual ~SGRawValuePointer () {}
147 virtual T getValue () const { return *_ptr; }
148 virtual bool setValue (T value) { *_ptr = value; return true; }
149 virtual SGRawValue<T> * clone () const {
150 return new SGRawValuePointer<T>(_ptr);
158 * A value managed through static functions.
160 * A read-only value will not have a setter; a write-only value will
164 class SGRawValueFunctions : public SGRawValue<T>
167 typedef T (*getter_t)();
168 typedef void (*setter_t)(T);
169 SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
170 : _getter(getter), _setter(setter) {}
171 virtual ~SGRawValueFunctions () {}
172 virtual T getValue () const {
173 if (_getter) return (*_getter)();
174 else return SGRawValue<T>::DefaultValue;
176 virtual bool setValue (T value) {
177 if (_setter) { (*_setter)(value); return true; }
180 virtual SGRawValue<T> * clone () const {
181 return new SGRawValueFunctions<T>(_getter,_setter);
190 * An indexed value managed through static functions.
192 * A read-only value will not have a setter; a write-only value will
196 class SGRawValueFunctionsIndexed : public SGRawValue<T>
199 typedef T (*getter_t)(int);
200 typedef void (*setter_t)(int,T);
201 SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
202 : _index(index), _getter(getter), _setter(setter) {}
203 virtual ~SGRawValueFunctionsIndexed () {}
204 virtual T getValue () const {
205 if (_getter) return (*_getter)(_index);
206 else return SGRawValue<T>::DefaultValue;
208 virtual bool setValue (T value) {
209 if (_setter) { (*_setter)(_index, value); return true; }
212 virtual SGRawValue<T> * clone () const {
213 return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
223 * A value managed through an object and access methods.
225 * A read-only value will not have a setter; a write-only value will
228 template <class C, class T>
229 class SGRawValueMethods : public SGRawValue<T>
232 typedef T (C::*getter_t)() const;
233 typedef void (C::*setter_t)(T);
234 SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
235 : _obj(obj), _getter(getter), _setter(setter) {}
236 virtual ~SGRawValueMethods () {}
237 virtual T getValue () const {
238 if (_getter) { return (_obj.*_getter)(); }
239 else { return SGRawValue<T>::DefaultValue; }
241 virtual bool setValue (T value) {
242 if (_setter) { (_obj.*_setter)(value); return true; }
245 virtual SGRawValue<T> * clone () const {
246 return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
256 * An indexed value managed through an object and access methods.
258 * A read-only value will not have a setter; a write-only value will
261 template <class C, class T>
262 class SGRawValueMethodsIndexed : public SGRawValue<T>
265 typedef T (C::*getter_t)(int) const;
266 typedef void (C::*setter_t)(int, T);
267 SGRawValueMethodsIndexed (C &obj, int index,
268 getter_t getter = 0, setter_t setter = 0)
269 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
270 virtual ~SGRawValueMethodsIndexed () {}
271 virtual T getValue () const {
272 if (_getter) { return (_obj.*_getter)(_index); }
273 else { return SGRawValue<T>::DefaultValue; }
275 virtual bool setValue (T value) {
276 if (_setter) { (_obj.*_setter)(_index, value); return true; }
279 virtual SGRawValue<T> * clone () const {
280 return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
291 ////////////////////////////////////////////////////////////////////////
294 // This is the value that property-list clients see. It is a
295 // persistent layer over the possibly-changing raw value; once a
296 // client gets an SGValue from the property manager, the pointer
297 // will be good for the life of the property manager itself, no
298 // matter how often the pointer is tied or untied.
299 ////////////////////////////////////////////////////////////////////////
314 SGValue (const SGValue &value);
317 Type getType () const;
319 SGValue * getAlias ();
320 const SGValue * getAlias () const;
321 bool alias (SGValue * alias);
323 bool isAlias () const { return _type == ALIAS; }
325 bool getBoolValue () const;
326 int getIntValue () const;
327 long getLongValue () const;
328 float getFloatValue () const;
329 double getDoubleValue () const;
330 string getStringValue () const;
332 bool setBoolValue (bool value);
333 bool setIntValue (int value);
334 bool setLongValue (long value);
335 bool setFloatValue (float value);
336 bool setDoubleValue (double value);
337 bool setStringValue (string value);
338 bool setUnknownValue (string value);
340 bool isTied () const { return _tied; }
342 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
343 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
344 bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
345 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
346 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
347 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
362 // The right kind of pointer...
365 SGRawValue<bool> * bool_val;
366 SGRawValue<int> * int_val;
367 SGRawValue<long> * long_val;
368 SGRawValue<float> * float_val;
369 SGRawValue<double> * double_val;
370 SGRawValue<string> * string_val;
377 ////////////////////////////////////////////////////////////////////////
378 // A node in a property tree.
379 ////////////////////////////////////////////////////////////////////////
387 virtual ~SGPropertyNode ();
390 bool hasValue () const { return (_value != 0); }
391 SGValue * getValue () { return _value; }
392 SGValue * getValue (bool create);
393 const SGValue * getValue () const { return _value; }
394 const string &getName () const { return _name; }
395 const int getIndex () const { return _index; }
396 SGPropertyNode * getParent () { return _parent; }
397 const SGPropertyNode * getParent () const { return _parent; }
400 bool alias (SGPropertyNode * target);
401 bool alias (const string &path);
403 bool isAlias () const;
404 SGPropertyNode * getAliasTarget ();
405 const SGPropertyNode * getAliasTarget () const;
408 const int nChildren () const { return _children.size(); }
409 SGPropertyNode * getChild (int position);
410 const SGPropertyNode * getChild (int position) const;
411 SGPropertyNode * getChild (const string &name, int index = 0,
412 bool create = false);
413 const SGPropertyNode * getChild (const string &name, int index = 0) const;
415 vector<SGPropertyNode *> getChildren (const string &name);
416 vector<const SGPropertyNode *> getChildren (const string &name) const;
419 string getPath (bool simplify = false) const;
421 // Relative or absolute paths.
422 SGPropertyNode * getRootNode ();
423 const SGPropertyNode * getRootNode () const;
424 SGPropertyNode * getNode (const string &relative_path, bool create = false);
425 const SGPropertyNode * getNode (const string &relative_path) const;
427 // Value-related stuff.
428 SGValue::Type getType () const;
430 bool getBoolValue () const;
431 int getIntValue () const;
432 long getLongValue () const;
433 float getFloatValue () const;
434 double getDoubleValue () const;
435 string getStringValue () const;
437 bool setBoolValue (bool value);
438 bool setIntValue (int value);
439 bool setLongValue (long value);
440 bool setFloatValue (float value);
441 bool setDoubleValue (double value);
442 bool setStringValue (string value);
443 bool setUnknownValue (string value);
445 bool isTied () const;
447 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
448 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
449 bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
450 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
451 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
452 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
456 // Values from paths.
457 bool hasValue (const string &relative_path) const;
458 SGValue * getValue (const string &relative_path, bool create = false);
459 const SGValue * getValue (const string &relative_path) const;
461 SGValue::Type getType (const string &relative_path) const;
463 bool getBoolValue (const string &relative_path,
464 bool defaultValue = false) const;
465 int getIntValue (const string &relative_path,
466 int defaultValue = 0) const;
467 long getLongValue (const string &relative_path,
468 long defaultValue = 0L) const;
469 float getFloatValue (const string &relative_path,
470 float defaultValue = 0.0) const;
471 double getDoubleValue (const string &relative_path,
472 double defaultValue = 0.0L) const;
473 string getStringValue (const string &relative_path,
474 string defaultValue = "") const;
476 bool setBoolValue (const string &relative_path, bool value);
477 bool setIntValue (const string &relative_path, int value);
478 bool setLongValue (const string &relative_path, long value);
479 bool setFloatValue (const string &relative_path, float value);
480 bool setDoubleValue (const string &relative_path, double value);
481 bool setStringValue (const string &relative_path, string value);
482 bool setUnknownValue (const string &relative_path, string value);
484 bool isTied (const string &relative_path) const;
486 bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
487 bool useDefault = true);
488 bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
489 bool useDefault = true);
490 bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
491 bool useDefault = true);
492 bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
493 bool useDefault = true);
494 bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
495 bool useDefault = true);
496 bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
497 bool useDefault = true);
499 bool untie (const string &relative_path);
503 SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
507 SGPropertyNode (const SGPropertyNode &node) {}
512 SGPropertyNode * _parent;
513 vector<SGPropertyNode *> _children;
514 mutable SGPropertyNode * _target;
520 ////////////////////////////////////////////////////////////////////////
522 ////////////////////////////////////////////////////////////////////////
524 bool readProperties (istream &input, SGPropertyNode * start_node,
525 const string &base = "");
526 bool readProperties (const string &file, SGPropertyNode * start_node);
527 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
528 bool writeProperties (const string &file, const SGPropertyNode * start_node);
529 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
532 #endif // __PROPS_HXX