From 65d6a5c77447abebb2d0d9255f30546a6abf910c Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Sat, 26 Dec 2009 23:56:21 +0100 Subject: [PATCH] Prepare effects animation code to use general functor setters --- simgear/scene/material/EffectBuilder.hxx | 113 +++++++++++++++++------ 1 file changed, 87 insertions(+), 26 deletions(-) diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx index f86b87f1..10e8004b 100644 --- a/simgear/scene/material/EffectBuilder.hxx +++ b/simgear/scene/material/EffectBuilder.hxx @@ -329,56 +329,109 @@ bool isAttributeActive(Effect* effect, const SGPropertyNode* prop); namespace effect { /** - * Bridge between types stored in properties and what OSG wants. + * Bridge between types stored in properties and what OSG or the + * effects code want. */ -template struct OSGBridge; +template struct Bridge; +/** + * Default just passes on the same type. + * + */ template -struct OSGBridge : public OSGBridge +struct Bridge { + typedef T sg_type; + static T get(const T& val) { return val; } }; +template +struct Bridge : public Bridge +{ +}; + +// Save some typing... +template +struct BridgeOSGVec +{ + typedef InType sg_type; + static OutType get(const InType& val) { return toOsg(val); } +}; template<> -struct OSGBridge +struct Bridge : public BridgeOSGVec { - typedef SGVec3d sg_type; - static osg::Vec3f getOsgType(const SGVec3d& val) { return toOsg(val); } }; template<> -struct OSGBridge +struct Bridge : public BridgeOSGVec { - typedef SGVec3d sg_type; - static osg::Vec3d getOsgType(const SGVec3d& val) { return toOsg(val); } }; template<> -struct OSGBridge +struct Bridge : public BridgeOSGVec { - typedef SGVec4d sg_type; - static osg::Vec4f getOsgType(const SGVec4d& val) { return toOsg(val); } }; template<> -struct OSGBridge +struct Bridge : public BridgeOSGVec { - typedef SGVec4d sg_type; - static osg::Vec4d getOsgType(const SGVec4d& val) { return toOsg(val); } }; +/** + * Functor for calling a function on an osg::Referenced object and a + * value (e.g., an SGVec4d from a property) which will be converted to + * the equivalent OSG type. + * + * General version, function takes obj, val + */ +template +struct OSGFunctor : public Bridge +{ + OSGFunctor(Obj* obj, const Func& func) + : _obj(obj), _func(func) {} + void operator()(const typename Bridge::sg_type& val) const + { + _func(_obj, this->get(val)); + } + osg::ref_ptr_obj; + const Func _func; +}; + +/** + * Version which uses a pointer to member function instead. + */ template -struct OSGFunctor : public OSGBridge +struct OSGFunctor + : public Bridge { - OSGFunctor(Obj* obj, void (Obj::*func)(const OSGParam&)) + typedef void (Obj::*const MemFunc)(const OSGParam&); + OSGFunctor(Obj* obj, MemFunc func) : _obj(obj), _func(func) {} - void operator()(const typename OSGBridge::sg_type& val) const + void operator()(const typename Bridge::sg_type& val) const { - ((_obj.get())->*_func)(this->getOsgType(val)); + (_obj->*_func)(this->get(val)); } osg::ref_ptr_obj; - void (Obj::*_func)(const OSGParam&); + MemFunc _func; }; +/** + * Typical convenience constructors + */ +template +OSGFunctor make_OSGFunctor(Obj* obj, const Func& func) +{ + return OSGFunctor(obj, func); +} + +template +OSGFunctor +make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&)) +{ + return OSGFunctor(obj, func); +} + template class ScalarChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded, @@ -459,6 +512,15 @@ private: Func _func; }; +template +Effect::Updater* +new_EEPropListener(const Func& func, const std::string* propName, + const Itr& namesBegin, const Itr& namesEnd) +{ + return new EffectExtendedPropListener + (func, 0, namesBegin, namesEnd); +} + /** * Initialize the value and the possible updating of an effect * attribute. If the value is specified directly, set it. Otherwise, @@ -516,24 +578,23 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, void (ObjType::*setter)(const OSGParamType&), NameItrType nameItr, const SGReaderWriterXMLOptions* options) { - typedef typename OSGBridge::sg_type sg_type; + typedef typename Bridge::sg_type sg_type; const int numComponents = props::NumComponents::num_components; const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); if (!valProp) return; if (valProp->nChildren() == 0) { // Has ? - (obj->*setter)(OSGBridge - ::getOsgType(valProp->getValue())); + (obj->*setter)(Bridge + ::get(valProp->getValue())); } else { std::vector paramNames = getVectorProperties(valProp, options,numComponents, nameItr); if (paramNames.empty()) throw BuilderException(); std::vector::const_iterator pitr = paramNames.begin(); - typedef OSGFunctor Functor; Effect::Updater* listener - = new EffectExtendedPropListener - (Functor(obj, setter), 0, pitr, pitr + numComponents); + = new_EEPropListener(make_OSGFunctor(obj, setter), 0, + pitr, pitr + numComponents); effect->addUpdater(listener); } } -- 2.39.5