diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 7d961af4..f94be67a 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -1356,6 +1356,28 @@ void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv) } } +void Effect::UpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) +{ + EffectGeode* eg = dynamic_cast(node); + if (!eg) + return; + Effect* effect = eg->getEffect(); + if (!effect) + return; + + for (vector >::iterator itr = effect->_extraData.begin(), + end = effect->_extraData.end(); + itr != end; + ++itr) { + PropertyPoller * poller + = dynamic_cast(itr->ptr()); + if (poller) + poller->pollProperties(effect); + } + + traverse(node, nv); +} + bool Effect::Key::EqualTo::operator()(const Effect::Key& lhs, const Effect::Key& rhs) const { diff --git a/simgear/scene/material/Effect.hxx b/simgear/scene/material/Effect.hxx index 0966dc1a..346c52c2 100644 --- a/simgear/scene/material/Effect.hxx +++ b/simgear/scene/material/Effect.hxx @@ -73,6 +73,17 @@ private: bool _initialized; }; +class PropertyPoller +{ +public: + PropertyPoller() {}; + virtual ~PropertyPoller() {}; + virtual void pollProperties(Effect* effect) + { + } +private: +}; + class Effect : public osg::Object { public: @@ -121,6 +132,17 @@ public: { void doUpdate(osg::Node* node, osg::NodeVisitor* nv); }; + friend struct UpdateCallback; + struct UpdateCallback : public osg::NodeCallback + { + UpdateCallback() {} + UpdateCallback(const UpdateCallback& nc, const osg::CopyOp& copyop) + : osg::NodeCallback(nc, copyop) + { + } + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); + }; protected: std::vector > _extraData; ~Effect(); diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx index a919f10b..52e2cf1c 100644 --- a/simgear/scene/material/EffectBuilder.hxx +++ b/simgear/scene/material/EffectBuilder.hxx @@ -496,19 +496,17 @@ make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&)) template class ScalarChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded, + public PropertyPoller, public Effect::Updater { public: ScalarChangeListener(ObjType* obj, const F& setter, const std::string& propName) - : _obj(obj), _setter(setter) + : _obj(obj), _setter(setter), _propName(propName) { - _propName = new std::string(propName); } virtual ~ScalarChangeListener() { - delete _propName; - _propName = 0; } void valueChanged(SGPropertyNode* node) { @@ -516,16 +514,20 @@ public: } void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) { - SGPropertyNode* listenProp = makeNode(propRoot, *_propName); - delete _propName; - _propName = 0; - if (listenProp) - listenProp->addChangeListener(this, true); + _listenProp = makeNode(propRoot, _propName); +// if ( _listenProp.valid() ) +// _listenProp->addChangeListener(this, true); + } + void pollProperties(Effect* effect) + { + if( false == _listenProp.valid() ) return; + valueChanged(_listenProp); } private: + SGPropertyNode_ptr _listenProp; osg::ref_ptr _obj; F _setter; - std::string* _propName; + std::string _propName; }; template diff --git a/simgear/scene/material/EffectGeode.cxx b/simgear/scene/material/EffectGeode.cxx index c2967639..2355bb67 100644 --- a/simgear/scene/material/EffectGeode.cxx +++ b/simgear/scene/material/EffectGeode.cxx @@ -52,7 +52,9 @@ void EffectGeode::setEffect(Effect* effect) _effect = effect; if (!_effect) return; + //TODO: do we leak the callbacks or does the geode own pointer afterwards? addUpdateCallback(new Effect::InitializeCallback); + addUpdateCallback(new Effect::UpdateCallback); } void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)