From b0562df6bb836d9c624bd7af033d4f2cde075328 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Tue, 9 Mar 2010 07:28:46 +0100 Subject: [PATCH] Cleanup of effects parameter animation --- simgear/scene/material/EffectBuilder.hxx | 125 ++++++++++++++++++----- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx index 10e8004b..54e959a1 100644 --- a/simgear/scene/material/EffectBuilder.hxx +++ b/simgear/scene/material/EffectBuilder.hxx @@ -156,6 +156,21 @@ EffectPropertyMap::EffectPropertyMap(const EffectNameValue (&attrs)[N]) _map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second)); } +// A one-way map that can be initialized using an array +template +struct SimplePropertyMap +{ + typedef std::map map_type; + map_type _map; + template + SimplePropertyMap(const EffectNameValue (&attrs)[N]) + { + for (int i = 0; i < N; ++i) + _map.insert(typename map_type::value_type(attrs[i].first, + attrs[i].second)); + } +}; + class BuilderException : public sg_exception { public: @@ -203,6 +218,42 @@ void findAttr(const effect::EffectPropertyMap& pMap, findAttr(pMap, name, result); } +// Versions that don't throw an error + +template +const T* findAttr(const effect::EffectPropertyMap& pMap, + const char* name) +{ + using namespace effect; + typename EffectPropertyMap::BMap::iterator itr + = pMap._map.get().find(name); + if (itr == pMap._map.end()) + return 0; + else + return &itr->second; +} + +template +const T* findAttr(const effect::SimplePropertyMap& pMap, + const char* name) +{ + using namespace effect; + typename SimplePropertyMap::map_type::const_iterator itr + = pMap._map.find(name); + if (itr == pMap._map.end()) + return 0; + else + return &itr->second; +} + +template class Map> +const T* findAttr(const Map& pMap, + const std::string& name) +{ + return findAttr(pMap, name.c_str()); +} + + template std::string findName(const effect::EffectPropertyMap& pMap, T value) { @@ -384,7 +435,7 @@ struct Bridge : public BridgeOSGVec * * General version, function takes obj, val */ -template +template struct OSGFunctor : public Bridge { OSGFunctor(Obj* obj, const Func& func) @@ -400,8 +451,8 @@ struct OSGFunctor : public Bridge /** * Version which uses a pointer to member function instead. */ -template -struct OSGFunctor +template +struct OSGFunctor : public Bridge { typedef void (Obj::*const MemFunc)(const OSGParam&); @@ -418,28 +469,27 @@ struct OSGFunctor /** * Typical convenience constructors */ -template -OSGFunctor make_OSGFunctor(Obj* obj, const Func& func) +template +OSGFunctor make_OSGFunctor(Obj* obj, const Func& func) { - return OSGFunctor(obj, func); + return OSGFunctor(obj, func); } -template -OSGFunctor +template +OSGFunctor make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&)) { - return OSGFunctor(obj, func); } -template +template class ScalarChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded, public Effect::Updater { public: - typedef void (ObjType::*setter_type)(const OSGParamType); - ScalarChangeListener(ObjType* obj, setter_type setter, + ScalarChangeListener(ObjType* obj, const F& setter, const std::string& propName) : _obj(obj), _setter(setter) { @@ -452,7 +502,7 @@ public: } void valueChanged(SGPropertyNode* node) { - _obj->*setter(node->getValue()); + _setter(_obj.get(), node->getValue()); } void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) { @@ -464,7 +514,7 @@ public: } private: osg::ref_ptr _obj; - setter_type _setter; + F _setter; std::string* _propName; }; @@ -533,26 +583,35 @@ new_EEPropListener(const Func& func, const std::string* propName, * For relative property names, the property root found in options is * used. */ -template +template void initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, - void (ObjType::*setter)(const OSGParamType), - const SGReaderWriterXMLOptions* options) + const F& setter, const SGReaderWriterXMLOptions* options) { const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); if (!valProp) return; if (valProp->nChildren() == 0) { - obj->*setter(valProp->getValue()); + setter(obj, valProp->getValue()); } else { std::string propName = getGlobalProperty(prop, options); - ScalarChangeListener* listener - = new ScalarChangeListener(obj, setter, - propName); + ScalarChangeListener* listener + = new ScalarChangeListener(obj, setter, + propName); effect->addUpdater(listener); } } +template +inline void +initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, + SetterReturn (ObjType::*setter)(const OSGParamType), + const SGReaderWriterXMLOptions* options) +{ + initFromParameters(effect, prop, obj, + boost::bind(setter, _1, _2), options); +} + /* * Initialize vector parameters from individual properties. * The parameter may be updated at runtime. @@ -572,10 +631,11 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, * For relative property names, the property root found in options is * used. */ -template +template void initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, - void (ObjType::*setter)(const OSGParamType&), + const F& setter, NameItrType nameItr, const SGReaderWriterXMLOptions* options) { typedef typename Bridge::sg_type sg_type; @@ -584,8 +644,7 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, if (!valProp) return; if (valProp->nChildren() == 0) { // Has ? - (obj->*setter)(Bridge - ::get(valProp->getValue())); + setter(obj, Bridge::get(valProp->getValue())); } else { std::vector paramNames = getVectorProperties(valProp, options,numComponents, nameItr); @@ -593,12 +652,24 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, throw BuilderException(); std::vector::const_iterator pitr = paramNames.begin(); Effect::Updater* listener - = new_EEPropListener(make_OSGFunctor(obj, setter), 0, - pitr, pitr + numComponents); + = new_EEPropListener(make_OSGFunctor + (obj, setter), + 0, pitr, pitr + numComponents); effect->addUpdater(listener); } } +template +inline void +initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, + SetterReturn (ObjType::*setter)(const OSGParamType&), + NameItrType nameItr, const SGReaderWriterXMLOptions* options) +{ + initFromParameters(effect, prop, obj, + boost::bind(setter, _1, _2), nameItr, + options); +} extern const char* colorFields[]; } } -- 2.39.5