From 9c7f7f3d32b0afd502e534ec2419189a277e9e34 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 18 Jun 2002 01:26:09 +0000 Subject: [PATCH] Added a ptr() method to SGPropertyNode_ptr to get the raw pointer. Added the SGPropertyChangeListener interface and addChangeListener and firePropertyChange methods. --- simgear/misc/props.cxx | 82 +++++++++++++++++++++++++++++++++++++----- simgear/misc/props.hxx | 45 +++++++++++++++++++++++ 2 files changed, 118 insertions(+), 9 deletions(-) diff --git a/simgear/misc/props.cxx b/simgear/misc/props.cxx index fd1fb6c3..be18a0dd 100644 --- a/simgear/misc/props.cxx +++ b/simgear/misc/props.cxx @@ -360,9 +360,15 @@ inline bool SGPropertyNode::set_bool (bool val) { if (_tied) { - return _value.bool_val->setValue(val); + if (_value.bool_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { _local_val.bool_val = val; + firePropertyChange(); return true; } } @@ -371,9 +377,15 @@ inline bool SGPropertyNode::set_int (int val) { if (_tied) { - return _value.int_val->setValue(val); + if (_value.int_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { _local_val.int_val = val; + firePropertyChange(); return true; } } @@ -382,9 +394,15 @@ inline bool SGPropertyNode::set_long (long val) { if (_tied) { - return _value.long_val->setValue(val); + if (_value.long_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { _local_val.long_val = val; + firePropertyChange(); return true; } } @@ -393,9 +411,15 @@ inline bool SGPropertyNode::set_float (float val) { if (_tied) { - return _value.float_val->setValue(val); + if (_value.float_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { _local_val.float_val = val; + firePropertyChange(); return true; } } @@ -404,9 +428,15 @@ inline bool SGPropertyNode::set_double (double val) { if (_tied) { - return _value.double_val->setValue(val); + if (_value.double_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { _local_val.double_val = val; + firePropertyChange(); return true; } } @@ -415,10 +445,16 @@ inline bool SGPropertyNode::set_string (const char * val) { if (_tied) { - return _value.string_val->setValue(val); + if (_value.string_val->setValue(val)) { + firePropertyChange(); + return true; + } else { + return false; + } } else { delete [] _local_val.string_val; _local_val.string_val = copy_string(val); + firePropertyChange(); return true; } } @@ -592,7 +628,8 @@ SGPropertyNode::SGPropertyNode () _type(NONE), _tied(false), _attr(READ|WRITE), - _count(0) + _count(0), + _listeners(0) { _local_val.string_val = 0; } @@ -608,7 +645,8 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node) _type(node._type), _tied(node._tied), _attr(node._attr), - _count(0) + _count(0), + _listeners(0) // CHECK!! { _name = copy_string(node._name); _local_val.string_val = 0; @@ -690,7 +728,8 @@ SGPropertyNode::SGPropertyNode (const char * name, _type(NONE), _tied(false), _attr(READ|WRITE), - _count(0) + _count(0), + _listeners(0) { _name = copy_string(name); _local_val.string_val = 0; @@ -705,6 +744,7 @@ SGPropertyNode::~SGPropertyNode () delete [] _name; delete _path_cache; clear_value(); + delete _listeners; } @@ -812,6 +852,8 @@ SGPropertyNode::getChild (const char * name, int index, bool create) node = new SGPropertyNode(name, index, this); } _children.push_back(node); + if (_parent != 0) + _parent->firePropertyChange(); return _children[_children.size()-1]; } else { return 0; @@ -870,6 +912,8 @@ SGPropertyNode::removeChild (const char * name, int index, bool keep) node->setAttribute(REMOVED, true); ret = node; } + if (_parent != 0) + _parent->firePropertyChange(); return ret; } @@ -1939,6 +1983,26 @@ SGPropertyNode::untie (const char * relative_path) return (node == 0 ? false : node->untie()); } +void +SGPropertyNode::addChangeListener (SGPropertyChangeListener * listener) +{ + if (_listeners == 0) + _listeners = new vector; + _listeners->push_back(listener); +} + +void +SGPropertyNode::firePropertyChange (SGPropertyNode * node) +{ + if (_listeners != 0) { + for (int i = 0; i < _listeners->size(); i++) { + (*_listeners)[i]->propertyChanged(node); + } + } + if (_parent != 0) + _parent->firePropertyChange(node); +} + //////////////////////////////////////////////////////////////////////// diff --git a/simgear/misc/props.hxx b/simgear/misc/props.hxx index a03b2006..a077faca 100644 --- a/simgear/misc/props.hxx +++ b/simgear/misc/props.hxx @@ -503,6 +503,11 @@ public: */ operator const SGPropertyNode *() const; + /** + * Return the pointer. + */ + SGPropertyNode * ptr () { return _ptr; } + /** * Validity test */ @@ -513,6 +518,23 @@ private: SGPropertyNode *_ptr; }; + + +/** + * The property change listener interface. + * + *

Any class that needs to listen for property changes must implement + * this interface.

+ */ +class SGPropertyChangeListener +{ +public: + + virtual void propertyChanged (SGPropertyNode * node) = 0; + +}; + + /** * A node in a property tree. @@ -1098,9 +1120,30 @@ public: bool untie (const char * relative_path); + /** + * Add a change listener to the property. + */ + void addChangeListener (SGPropertyChangeListener * listener); + + + /** + * Fire a property change to all listeners. + */ + void firePropertyChange () + { + firePropertyChange(this); + } + + protected: + /** + * Fire a property change with an explicit target node. + */ + void firePropertyChange (SGPropertyNode * node); + + /** * Protected constructor for making new nodes on demand. */ @@ -1198,6 +1241,8 @@ private: char * string_val; } _local_val; + vector * _listeners; + /** -- 2.39.5