#endif
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+
#ifdef NONE
#pragma warn A sloppy coder has defined NONE as a macro!
* The template type of a static getter function.
*/
typedef T (*getter_t)();
- typedef T (*getter_td)(void*);
/**
* The template type of a static setter function.
*/
typedef void (*setter_t)(T);
- typedef void (*setter_td)(T,void*);
/**
* Explicit constructor.
* to write-disable the value.
*/
SGRawValueFunctions (getter_t getter = 0, setter_t setter = 0)
- : _getter(getter), _setter(setter),
- _getter_d(0), _setter_d(0), _data(0) {}
-
- /**
- * Explicit constructor.
- *
- * Create a new raw value bound to the getter and setter supplied.
- *
- * @param getter A static function for getting a value, or 0
- * to read-disable the value.
- * @param setter A static function for setting a value, or 0
- * to write-disable the value.
- * @param data A pointer to user data which gets passed to the
- * getter and setter functions. This could be used to pass the this
- * pointer to the callback function.
- */
- SGRawValueFunctions (getter_td getter = 0, setter_td setter = 0,
- void *data = NULL)
- : _setter(0), _getter(0),
- _getter_d(getter), _setter_d(setter), _data(data) {}
+ : _getter(getter), _setter(setter) {}
/**
* Destructor.
* return the default value for the type.
*/
virtual T getValue () const {
- if (_getter_d) return (*_getter_d)(_data);
- else if (_getter) return (*_getter)();
+ if (_getter) return (*_getter)();
else return SGRawValue<T>::DefaultValue;
}
* method will return false.
*/
virtual bool setValue (T value) {
- if (_setter_d) { (*_setter_d)(value,_data); return true; }
- else if (_setter) { (*_setter)(value); return true; }
+ if (_setter) { (*_setter)(value); return true; }
else return false;
}
* Create a copy of this raw value, bound to the same functions.
*/
virtual SGRawValue<T> * clone () const {
- if (_getter_d)
- return new SGRawValueFunctions<T>(_getter_d,_setter_d,_data);
- else
- return new SGRawValueFunctions<T>(_getter,_setter);
+ return new SGRawValueFunctions<T>(_getter,_setter);
}
private:
getter_t _getter;
setter_t _setter;
- getter_td _getter_d;
- setter_td _setter_d;
- void *_data;
};
{
public:
typedef T (*getter_t)(int);
- typedef T (*getter_td)(int,void*);
typedef void (*setter_t)(int,T);
- typedef void (*setter_td)(int,T,void*);
- SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter =
-0)
- : _index(index), _getter(getter), _setter(setter),
- _getter_d(0), _setter_d(0),_data(0) {}
- SGRawValueFunctionsIndexed (int index, getter_td getter = 0, setter_td setter = 0, void *data = NULL)
- : _index(index), _setter(0), _getter(0),
- _getter_d(getter), _setter_d(setter), _data(data) {}
+ SGRawValueFunctionsIndexed (int index, getter_t getter = 0, setter_t setter = 0)
+ : _index(index), _getter(getter), _setter(setter) {}
virtual ~SGRawValueFunctionsIndexed () {}
virtual T getValue () const {
- if (_getter_d) return (*_getter_d)(_index,_data);
- else if (_getter) return (*_getter)(_index);
+ if (_getter) return (*_getter)(_index);
else return SGRawValue<T>::DefaultValue;
}
virtual bool setValue (T value) {
- if (_setter_d) { (*_setter_d)(_index, value, _data); return true; }
- else if (_setter) { (*_setter)(_index, value); return true; }
+ if (_setter) { (*_setter)(_index, value); return true; }
else return false;
}
virtual SGRawValue<T> * clone () const {
- if (_getter_d)
- return new SGRawValueFunctionsIndexed<T>(_index,_getter_d,_setter_d,_data);
- else
- return new SGRawValueFunctionsIndexed<T>(_index,_getter,_setter);
+ return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter);
}
private:
int _index;
getter_t _getter;
setter_t _setter;
- getter_td _getter_d;
- setter_td _setter_d;
- void *_data;
};
* The smart pointer that manage reference counting
*/
class SGPropertyNode;
-class SGPropertyNode_ptr
-{
-public:
-
- /**
- * Default constructor
- */
- SGPropertyNode_ptr();
-
- /**
- * Copy constructor
- */
- SGPropertyNode_ptr( const SGPropertyNode_ptr &r );
-
- /**
- * Constructor from a pointer to a node
- */
- SGPropertyNode_ptr( SGPropertyNode *p );
-
- /**
- * Destructor
- */
- ~SGPropertyNode_ptr();
-
- /**
- * Assignement operator
- */
- SGPropertyNode_ptr &operator=( const SGPropertyNode_ptr &r );
-
- /**
- * Pointer access operator
- */
- SGPropertyNode *operator->();
-
- /**
- * Pointer access operator (const)
- */
- const SGPropertyNode *operator->() const;
-
- /**
- * Conversion to SGPropertyNode * operator
- */
- operator SGPropertyNode *();
-
- /**
- * Conversion to const SGPropertyNode * operator
- */
- operator const SGPropertyNode *() const;
-
- /**
- * Return the pointer.
- */
- SGPropertyNode * ptr () { return _ptr; }
-
- /**
- * Validity test
- */
- bool valid() const;
-
-private:
-
- SGPropertyNode *_ptr;
-};
-
+typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr;
+typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr;
\f
/**
/**
* A node in a property tree.
*/
-class SGPropertyNode
+class SGPropertyNode : public SGReferenced
{
public:
* Property value types.
*/
enum Type {
- NONE,
+ NONE = 0,
ALIAS,
BOOL,
INT,
ARCHIVE = 4,
REMOVED = 8,
TRACE_READ = 16,
- TRACE_WRITE = 32
+ TRACE_WRITE = 32,
+ USERARCHIVE = 64
};
/**
* Get the node's simple (XML) name.
*/
- const char * getName () const { return _name; }
+ const char * getName () const { return _name.c_str(); }
/**
vector<SGPropertyNode_ptr> getChildren (const char * name) const;
+ /**
+ * Remove child by position.
+ */
+ SGPropertyNode_ptr removeChild (int pos, bool keep = true);
+
+
/**
* Remove a child node
*/
SGPropertyNode_ptr removeChild (const char * name, int index = 0,
bool keep = true);
+ /**
+ * Remove all children with the specified name.
+ */
+ vector<SGPropertyNode_ptr> removeChildren (const char * name,
+ bool keep = true);
+
//
// Alias support.
/**
- * Add a change listener to the property.
+ * Add a change listener to the property. If "initial" is set call the
+ * listener initially.
*/
- void addChangeListener (SGPropertyChangeListener * listener);
+ void addChangeListener (SGPropertyChangeListener * listener,
+ bool initial = false);
/**
void removeChangeListener (SGPropertyChangeListener * listener);
+ /**
+ * Get the number of listeners.
+ */
+ int nListeners () const { return _listeners ? _listeners->size() : 0; }
+
+
/**
* Fire a value change event to all listeners.
*/
void fireChildRemoved (SGPropertyNode * child);
+ /**
+ * Clear any existing value and set the type to NONE.
+ */
+ void clearValue ();
+
+
protected:
void fireValueChanged (SGPropertyNode * node);
bool set_string (const char * value);
- /**
- * Clear any existing value and set the type to NONE.
- */
- void clear_value ();
-
-
/**
* Get the value as a string.
*/
/**
- * Increment reference counter
- */
- void incrementRef();
-
- /**
- * Decrement reference counter
+ * Remove this node from all nodes that link to it in their path cache.
*/
- int decrementRef();
+ void remove_from_path_caches();
- friend class SGPropertyNode_ptr;
-
-
- mutable char _buffer[MAX_STRING_LEN+1];
class hash_table;
- char * _name;
- mutable char * _display_name;
int _index;
+ string _name;
+ mutable string _display_name;
+ /// To avoid cyclic reference counting loops this shall not be a reference
+ /// counted pointer
SGPropertyNode * _parent;
vector<SGPropertyNode_ptr> _children;
vector<SGPropertyNode_ptr> _removedChildren;
- mutable char * _path;
+ vector<hash_table *> _linkedNodes;
+ mutable string _path;
+ mutable string _buffer;
hash_table * _path_cache;
Type _type;
bool _tied;
int _attr;
- int _count;
// The right kind of pointer...
union {
vector <SGPropertyChangeListener *> * _listeners;
+ /**
+ * Register/unregister node that links to this node in its path cache.
+ */
+ void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
+ bool remove_linked_node (hash_table * node);
+
+
\f
/**
- * A very simple hash table with no remove functionality.
+ * A very simple hash table.
*/
class hash_table {
public:
class entry {
public:
entry ();
- virtual ~entry ();
- virtual const char * get_key () { return _key; }
- virtual void set_key (const char * key);
- virtual SGPropertyNode * get_value () { return _value; }
- virtual void set_value (SGPropertyNode * value);
+ ~entry ();
+ const char * get_key () { return _key.c_str(); }
+ void set_key (const char * key);
+ SGPropertyNode * get_value () { return _value; }
+ void set_value (SGPropertyNode * value);
private:
- char * _key;
- SGPropertyNode * _value;
+ string _key;
+ SGSharedPtr<SGPropertyNode> _value;
};
class bucket {
public:
bucket ();
- virtual ~bucket ();
- virtual entry * get_entry (const char * key, bool create = false);
+ ~bucket ();
+ entry * get_entry (const char * key, bool create = false);
+ bool erase (SGPropertyNode * node);
+ void clear (hash_table * owner);
private:
int _length;
entry ** _entries;
friend class bucket;
hash_table ();
- virtual ~hash_table ();
- virtual SGPropertyNode * get (const char * key);
- virtual void put (const char * key, SGPropertyNode * value);
+ ~hash_table ();
+ SGPropertyNode * get (const char * key);
+ void put (const char * key, SGPropertyNode * value);
+ bool erase (SGPropertyNode * node);
private:
unsigned int hashcode (const char * key);