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].
24 #pragma warn A sloppy coder has defined UNKNOWN as a macro!
29 #pragma warn A sloppy coder has defined BOOL as a macro!
34 #pragma warn A sloppy coder has defined INT as a macro!
39 #pragma warn A sloppy coder has defined FLOAT as a macro!
44 #pragma warn A sloppy coder has defined DOUBLE as a macro!
49 #pragma warn A sloppy coder has defined STRING as a macro!
55 ////////////////////////////////////////////////////////////////////////
58 // This is the mechanism that information-providing routines can
59 // use to link their own values to the property manager. Any
60 // SGValue can be tied to a raw value and then untied again.
61 ////////////////////////////////////////////////////////////////////////
65 * Abstract base class for a raw value.
67 * Unlike values, raw values are not persistent -- the raw value can
68 * change frequently, but the changes are not visible to the application.
70 * The SGValue class always keeps a *copy* of a raw value, not the
71 * original one passed to it; if you override a derived class but do
72 * not replace the clone() method, strange things will happen.
74 * All raw values must implement getValue, setValue, and clone for the
81 static const T DefaultValue; // Default for this kind of raw value.
84 virtual ~SGRawValue () {}
85 virtual T getValue () const = 0;
86 virtual bool setValue (T value) = 0;
87 virtual SGRawValue * clone () const = 0;
92 * A value managed internally.
94 * Instances of this class are created automatically, by default,
95 * by the SGValue class; ordinarily the application should not
99 class SGRawValueInternal : public SGRawValue<T>
102 SGRawValueInternal () {}
103 SGRawValueInternal (T value) : _value(value) {}
104 virtual ~SGRawValueInternal () {}
105 virtual T getValue () const { return _value; }
106 virtual bool setValue (T value) { _value = value; return true; }
107 virtual SGRawValue<T> * clone () const {
108 return new SGRawValueInternal<T>(_value);
116 * A value managed through a direct pointer.
118 * This is the most efficient way to tie an external value, but also
119 * the most dangerous, because there is no way for the supplier to
120 * perform bounds checking and derived calculations except by polling
121 * the variable to see if it has changed.
124 class SGRawValuePointer : public SGRawValue<T>
127 SGRawValuePointer (T * ptr) : _ptr(ptr) {}
128 virtual ~SGRawValuePointer () {}
129 virtual T getValue () const { return *_ptr; }
130 virtual bool setValue (T value) { *_ptr = value; return true; }
131 virtual SGRawValue<T> * clone () const {
132 return new SGRawValuePointer<T>(_ptr);
140 * A value managed through static functions.
142 * A read-only value will not have a setter; a write-only value will
146 class SGRawValueFunctions : public SGRawValue<T>
149 typedef T (*getter_t)();
150 typedef void (*setter_t)(T);
151 SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
152 : _getter(getter), _setter(setter) {}
153 virtual ~SGRawValueFunctions () {}
154 virtual T getValue () const {
155 if (_getter) return (*_getter)();
156 else return DefaultValue;
158 virtual bool setValue (T value) {
159 if (_setter) { (*_setter)(value); return true; }
162 virtual SGRawValue<T> * clone () const {
163 return new SGRawValueFunctions<T>(_getter,_setter);
172 * An indexed value managed through static functions.
174 * A read-only value will not have a setter; a write-only value will
178 class SGRawValueFunctionsIndexed : public SGRawValue<T>
181 typedef T (*getter_t)(int);
182 typedef void (*setter_t)(int,T);
183 SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
184 : _index(index), _getter(getter), _setter(setter) {}
185 virtual ~SGRawValueFunctionsIndexed () {}
186 virtual T getValue () const {
187 if (_getter) return (*_getter)(_index);
188 else return DefaultValue;
190 virtual bool setValue (T value) {
191 if (_setter) { (*_setter)(_index, value); return true; }
194 virtual SGRawValue<T> * clone () const {
195 return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
205 * A value managed through an object and access methods.
207 * A read-only value will not have a setter; a write-only value will
210 template <class C, class T>
211 class SGRawValueMethods : public SGRawValue<T>
214 typedef T (C::*getter_t)() const;
215 typedef void (C::*setter_t)(T);
216 SGRawValueMethods (C &obj, getter_t getter = 0, setter_t setter = 0)
217 : _obj(obj), _getter(getter), _setter(setter) {}
218 virtual ~SGRawValueMethods () {}
219 virtual T getValue () const {
220 if (_getter) { return (_obj.*_getter)(); }
221 else { return DefaultValue; }
223 virtual bool setValue (T value) {
224 if (_setter) { (_obj.*_setter)(value); return true; }
227 virtual SGRawValue<T> * clone () const {
228 return new SGRawValueMethods<C,T>(_obj, _getter, _setter);
238 * An indexed value managed through an object and access methods.
240 * A read-only value will not have a setter; a write-only value will
243 template <class C, class T>
244 class SGRawValueMethodsIndexed : public SGRawValue<T>
247 typedef T (C::*getter_t)(int) const;
248 typedef void (C::*setter_t)(int, T);
249 SGRawValueMethodsIndexed (C &obj, int index,
250 getter_t getter = 0, setter_t setter = 0)
251 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
252 virtual ~SGRawValueMethodsIndexed () {}
253 virtual T getValue () const {
254 if (_getter) { return (_obj.*_getter)(_index); }
255 else { return DefaultValue; }
257 virtual bool setValue (T value) {
258 if (_setter) { (_obj.*_setter)(_index, value); return true; }
261 virtual SGRawValue<T> * clone () const {
262 return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter);
273 ////////////////////////////////////////////////////////////////////////
276 // This is the value that property-list clients see. It is a
277 // persistent layer over the possibly-changing raw value; once a
278 // client gets an SGValue from the property manager, the pointer
279 // will be good for the life of the property manager itself, no
280 // matter how often the pointer is tied or untied.
281 ////////////////////////////////////////////////////////////////////////
295 SGValue (const SGValue &value);
298 Type getType () const { return _type; }
300 bool getBoolValue () const;
301 int getIntValue () const;
302 float getFloatValue () const;
303 double getDoubleValue () const;
304 string getStringValue () const;
306 bool setBoolValue (bool value);
307 bool setIntValue (int value);
308 bool setFloatValue (float value);
309 bool setDoubleValue (double value);
310 bool setStringValue (string value);
311 bool setUnknownValue (string value);
313 bool isTied () const { return _tied; }
315 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
316 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
317 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
318 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
319 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
330 // The right kind of pointer...
332 SGRawValue<bool> * bool_val;
333 SGRawValue<int> * int_val;
334 SGRawValue<float> * float_val;
335 SGRawValue<double> * double_val;
336 SGRawValue<string> * string_val;
343 ////////////////////////////////////////////////////////////////////////
344 // A node in a property tree.
345 ////////////////////////////////////////////////////////////////////////
353 virtual ~SGPropertyNode ();
356 bool hasValue () const { return (_value != 0); }
357 SGValue * getValue () { return _value; }
358 const SGValue * getValue () const { return _value; }
359 const string &getName () const { return _name; }
360 const int getIndex () const { return _index; }
361 SGPropertyNode * getParent () { return _parent; }
362 const SGPropertyNode * getParent () const { return _parent; }
365 const int nChildren () const { return _children.size(); }
366 SGPropertyNode * getChild (int position);
367 const SGPropertyNode * getChild (int position) const;
368 SGPropertyNode * getChild (const string &name, int index = 0,
369 bool create = false);
370 const SGPropertyNode * getChild (const string &name, int index = 0) const;
372 vector<SGPropertyNode *> getChildren (const string &name);
373 vector<const SGPropertyNode *> getChildren (const string &name) const;
376 string getPath (bool simplify = false) const;
378 // Relative or absolute paths.
379 SGPropertyNode * getRootNode ();
380 const SGPropertyNode * getRootNode () const;
381 SGPropertyNode * getNode (const string &relative_path, bool create = false);
382 const SGPropertyNode * getNode (const string &relative_path) const;
384 // Value-related stuff.
385 SGValue::Type getType () const;
387 bool getBoolValue () const;
388 int getIntValue () const;
389 float getFloatValue () const;
390 double getDoubleValue () const;
391 string getStringValue () const;
393 bool setBoolValue (bool value);
394 bool setIntValue (int value);
395 bool setFloatValue (float value);
396 bool setDoubleValue (double value);
397 bool setStringValue (string value);
398 bool setUnknownValue (string value);
400 bool isTied () const;
402 bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
403 bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
404 bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
405 bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
406 bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
410 // Values from paths.
411 bool hasValue (const string &relative_path) const;
412 SGValue * getValue (const string &relative_path, bool create = false);
413 const SGValue * getValue (const string &relative_path) const;
415 SGValue::Type getType (const string &relative_path) const;
417 bool getBoolValue (const string &relative_path,
418 bool defaultValue = false) const;
419 int getIntValue (const string &relative_path,
420 int defaultValue = 0) const;
421 float getFloatValue (const string &relative_path,
422 float defaultValue = 0.0) const;
423 double getDoubleValue (const string &relative_path,
424 double defaultValue = 0.0L) const;
425 string getStringValue (const string &relative_path,
426 string defaultValue = "") const;
428 bool setBoolValue (const string &relative_path, bool value);
429 bool setIntValue (const string &relative_path, int value);
430 bool setFloatValue (const string &relative_path, float value);
431 bool setDoubleValue (const string &relative_path, double value);
432 bool setStringValue (const string &relative_path, string value);
433 bool setUnknownValue (const string &relative_path, string value);
435 bool isTied (const string &relative_path) const;
437 bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
438 bool useDefault = true);
439 bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
440 bool useDefault = true);
441 bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
442 bool useDefault = true);
443 bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
444 bool useDefault = true);
445 bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
446 bool useDefault = true);
448 bool untie (const string &relative_path);
452 SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
456 SGPropertyNode (const SGPropertyNode &node) {}
461 SGPropertyNode * _parent;
462 vector<SGPropertyNode *> _children;
468 ////////////////////////////////////////////////////////////////////////
470 ////////////////////////////////////////////////////////////////////////
472 bool readProperties (istream &input, SGPropertyNode * start_node);
473 bool readProperties (const string &file, SGPropertyNode * start_node);
474 bool writeProperties (ostream &output, const SGPropertyNode * start_node);
475 bool writeProperties (const string &file, const SGPropertyNode * start_node);
476 bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
479 #endif // __PROPS_HXX