#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 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:
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(); }
/**
/**
- * Remove a child node (returns true if at least one node had to remain,
- * because it was tied, aliased, or refcounted through SGPropertyNode_ptr.
+ * Remove child by position.
*/
- bool removeChild (const char * name, int index = 0, bool keep = true);
+ 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 nodes, or all with a given name.
+ * Remove all children with the specified name.
*/
- bool removeChildren(const char * name = 0);
+ vector<SGPropertyNode_ptr> removeChildren (const char * name,
+ bool keep = true);
//
/**
- * 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.
*/
/**
- * Increment reference counter
- */
- void incrementRef();
-
- /**
- * Decrement reference counter
+ * Remove this node from all nodes that link to it in their path cache.
*/
- int decrementRef();
-
- friend class SGPropertyNode_ptr;
-
+ void remove_from_path_caches();
- 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);
- virtual void erase(const char * key);
+ ~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);
- virtual void erase(const char * key);
+ ~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);