#include <iostream>
using std::cerr;
using std::endl;
+using std::find;
using std::sort;
#else
{
if (_tied) {
if (_value.bool_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
}
} else {
_local_val.bool_val = val;
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
{
if (_tied) {
if (_value.int_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
}
} else {
_local_val.int_val = val;
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
{
if (_tied) {
if (_value.long_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
}
} else {
_local_val.long_val = val;
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
{
if (_tied) {
if (_value.float_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
}
} else {
_local_val.float_val = val;
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
{
if (_tied) {
if (_value.double_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
}
} else {
_local_val.double_val = val;
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
{
if (_tied) {
if (_value.string_val->setValue(val)) {
- firePropertyChange();
+ fireValueChanged();
return true;
} else {
return false;
} else {
delete [] _local_val.string_val;
_local_val.string_val = copy_string(val);
- firePropertyChange();
+ fireValueChanged();
return true;
}
}
node = new SGPropertyNode(name, index, this);
}
_children.push_back(node);
- if (_parent != 0)
- _parent->firePropertyChange();
- return _children[_children.size()-1];
+ fireChildAdded(node);
+ return node;
} else {
return 0;
}
}
node->setAttribute(REMOVED, true);
ret = node;
+ fireChildRemoved(node);
}
- if (_parent != 0)
- _parent->firePropertyChange();
return ret;
}
if (_listeners == 0)
_listeners = new vector<SGPropertyChangeListener *>;
_listeners->push_back(listener);
+ listener->register_property(this);
+}
+
+void
+SGPropertyNode::removeChangeListener (SGPropertyChangeListener * listener)
+{
+ vector<SGPropertyChangeListener *>::iterator it =
+ find(_listeners->begin(), _listeners->end(), listener);
+ if (it != _listeners->end()) {
+ _listeners->erase(it);
+ listener->unregister_property(this);
+ if (_listeners->empty()) {
+ vector<SGPropertyChangeListener *> * tmp = _listeners;
+ _listeners = 0;
+ delete tmp;
+ }
+ }
+}
+
+void
+SGPropertyNode::fireValueChanged ()
+{
+ fireValueChanged(this);
+}
+
+void
+SGPropertyNode::fireChildAdded (SGPropertyNode * child)
+{
+ fireChildAdded(this, child);
+}
+
+void
+SGPropertyNode::fireChildRemoved (SGPropertyNode * child)
+{
+ fireChildRemoved(this, child);
+}
+
+void
+SGPropertyNode::fireValueChanged (SGPropertyNode * node)
+{
+ if (_listeners != 0) {
+ for (int i = 0; i < _listeners->size(); i++) {
+ (*_listeners)[i]->valueChanged(node);
+ }
+ }
+ if (_parent != 0)
+ _parent->fireValueChanged(node);
+}
+
+void
+SGPropertyNode::fireChildAdded (SGPropertyNode * parent,
+ SGPropertyNode * child)
+{
+ if (_listeners != 0) {
+ for (int i = 0; i < _listeners->size(); i++) {
+ (*_listeners)[i]->childAdded(parent, child);
+ }
+ }
+ if (_parent != 0)
+ _parent->fireChildAdded(parent, child);
}
void
-SGPropertyNode::firePropertyChange (SGPropertyNode * node)
+SGPropertyNode::fireChildRemoved (SGPropertyNode * parent,
+ SGPropertyNode * child)
{
if (_listeners != 0) {
for (int i = 0; i < _listeners->size(); i++) {
- (*_listeners)[i]->propertyChanged(node);
+ (*_listeners)[i]->childRemoved(parent, child);
}
}
if (_parent != 0)
- _parent->firePropertyChange(node);
+ _parent->fireChildRemoved(parent, child);
}
}
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGPropertyChangeListener.
+////////////////////////////////////////////////////////////////////////
+
+SGPropertyChangeListener::~SGPropertyChangeListener ()
+{
+ // This will come back and remove
+ // the current item each time. Is
+ // that OK?
+ vector<SGPropertyNode *>::iterator it;
+ for (it = _properties.begin(); it != _properties.end(); it++)
+ (*it)->removeChangeListener(this);
+}
+
+void
+SGPropertyChangeListener::valueChanged (SGPropertyNode * node)
+{
+ // NO-OP
+}
+
+void
+SGPropertyChangeListener::childAdded (SGPropertyNode * node,
+ SGPropertyNode * child)
+{
+ // NO-OP
+}
+
+void
+SGPropertyChangeListener::childRemoved (SGPropertyNode * parent,
+ SGPropertyNode * child)
+{
+ // NO-OP
+}
+
+void
+SGPropertyChangeListener::register_property (SGPropertyNode * node)
+{
+ _properties.push_back(node);
+}
+
+void
+SGPropertyChangeListener::unregister_property (SGPropertyNode * node)
+{
+ vector<SGPropertyNode *>::iterator it =
+ find(_properties.begin(), _properties.end(), node);
+ if (it != _properties.end())
+ _properties.erase(it);
+}
+
+
// end of props.cxx
class SGPropertyChangeListener
{
public:
+ virtual ~SGPropertyChangeListener ();
+ virtual void valueChanged (SGPropertyNode * node);
+ virtual void childAdded (SGPropertyNode * parent, SGPropertyNode * child);
+ virtual void childRemoved (SGPropertyNode * parent, SGPropertyNode * child);
- virtual void propertyChanged (SGPropertyNode * node) = 0;
+protected:
+ friend class SGPropertyNode;
+ virtual void register_property (SGPropertyNode * node);
+ virtual void unregister_property (SGPropertyNode * node);
+private:
+ vector<SGPropertyNode *> _properties;
};
/**
- * Fire a property change to all listeners.
+ * Remove a change listener from the property.
*/
- void firePropertyChange ()
- {
- firePropertyChange(this);
- }
+ void removeChangeListener (SGPropertyChangeListener * listener);
-protected:
+ /**
+ * Fire a value change event to all listeners.
+ */
+ void fireValueChanged ();
/**
- * Fire a property change with an explicit target node.
+ * Fire a child-added event to all listeners.
*/
- void firePropertyChange (SGPropertyNode * node);
+ void fireChildAdded (SGPropertyNode * child);
+
+
+ /**
+ * Fire a child-removed event to all listeners.
+ */
+ void fireChildRemoved (SGPropertyNode * child);
+
+
+protected:
+ void fireValueChanged (SGPropertyNode * node);
+ void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
+ void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
/**
* Protected constructor for making new nodes on demand.