+ callback_map["subscribe"] = &PropsChannel::subscribe;
+ callback_map["unsubscribe"] = &PropsChannel::unsubscribe;
+}
+
+PropsChannel::~PropsChannel() {
+ // clean up all registered listeners
+ BOOST_FOREACH(SGPropertyNode_ptr l, _listeners) {
+ l->removeChangeListener( this );
+ }
+}
+
+void PropsChannel::subscribe(const ParameterList ¶m) {
+ if (! check_args(param,1,"subscribe")) return;
+
+ std::string command = param[0];
+ const char* p = param[1].c_str();
+ if (!p) return;
+
+ //SG_LOG(SG_GENERAL, SG_ALERT, p << std::endl);
+ push( command.c_str() ); push ( " " );
+ push( p );
+ push( getTerminator() );
+
+ SGPropertyNode *n = globals->get_props()->getNode( p,true );
+ if ( n->isTied() ) {
+ error("Error:Tied properties cannot register listeners");
+ return;
+ }
+
+ if (n) {
+ n->addChangeListener( this );
+ _listeners.push_back( n ); // housekeeping, save for deletion in dtor later on
+ } else {
+ error("listener could not be added");
+ }
+}
+
+void PropsChannel::unsubscribe(const ParameterList ¶m) {
+ if (!check_args(param,1,"unsubscribe")) return;
+
+ try {
+ SGPropertyNode *n = globals->get_props()->getNode( param[1].c_str() );
+ if (n)
+ n->removeChangeListener( this );
+ } catch (sg_exception&) {
+ error("Error:Listener could not be removed");
+ }
+}
+
+
+//TODO: provide support for different types of subscriptions MODES ? (child added/removed, thesholds, min/max)
+void PropsChannel::valueChanged(SGPropertyNode* ptr) {
+ //SG_LOG(SG_GENERAL, SG_ALERT, __FILE__<< "@"<<__LINE__ << ":" << __FUNCTION__ << std::endl);
+ std::stringstream response;
+ response << ptr->getPath(true) << "=" << ptr->getStringValue() << getTerminator(); //TODO: use hashes, echo several properties at once
+ push( response.str().c_str() );