typedef boost::tuple<std::string, Uniform::Type, std::string> UniformCacheKey;
typedef boost::tuple<ref_ptr<Uniform>, SGPropertyChangeListener*> UniformCacheValue;
- //std::map<UniformCacheKey,UniformCacheValue > uniformCache;
std::map<UniformCacheKey,ref_ptr<Uniform> > uniformCache;
typedef std::queue<DeferredPropertyListener*> DeferredListenerList;
}
UniformCacheKey key = boost::make_tuple(name, uniformType, val);
- //UniformCacheValue value = uniformCache[key];
- //ref_ptr<Uniform> uniform = value.get_head();
ref_ptr<Uniform> uniform = uniformCache[key];
if (uniform.valid()) {
SG_LOG(SG_GL,SG_DEBUG,"new uniform " << name << " value " << uniformCache.size());
uniformCache[key] = uniform = new Uniform;
- DeferredPropertyListener* updater = 0;
uniform->setName(name);
uniform->setType(uniformType);
switch (uniformType) {
case Uniform::BOOL:
- updater = initFromParameters(effect, valProp, uniform.get(),
+ initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
options);
break;
case Uniform::FLOAT:
- updater = initFromParameters(effect, valProp, uniform.get(),
+ initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
options);
break;
case Uniform::FLOAT_VEC3:
- updater = initFromParameters(effect, valProp, uniform.get(),
+ initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
vec3Names, options);
break;
case Uniform::FLOAT_VEC4:
- updater = initFromParameters(effect, valProp, uniform.get(),
+ initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
vec4Names, options);
break;
case Uniform::SAMPLER_1D_SHADOW:
case Uniform::SAMPLER_2D_SHADOW:
case Uniform::SAMPLER_CUBE:
- updater = initFromParameters(effect, valProp, uniform.get(),
+ initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
options);
break;
break;
}
- addListener(updater);
return uniform;
}
return true;
}
+void Effect::addDeferredPropertyListener(DeferredPropertyListener* listener)
+{
+ UniformFactory::instance()->addListener(listener);
+}
+
void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
{
EffectGeode* eg = dynamic_cast<EffectGeode*>(node);
// Initialize all queued listeners
UniformFactory::instance()->updateListeners(root);
-
- for (vector<SGSharedPtr<Updater> >::iterator itr = effect->_extraData.begin(),
- end = effect->_extraData.end();
- itr != end;
- ++itr) {
- InitializeWhenAdded* adder
- = dynamic_cast<InitializeWhenAdded*>(itr->ptr());
- if (adder)
- adder->initOnAdd(effect, root);
- }
}
bool Effect::Key::EqualTo::operator()(const Effect::Key& lhs,
* things, like manipulations of the global property tree, are are
* only safe in the update process.
*/
-
-class InitializeWhenAdded
-{
-public:
- InitializeWhenAdded() : _initialized(false) {};
- virtual ~InitializeWhenAdded() {};
- void initOnAdd(Effect* effect, SGPropertyNode* propRoot)
- {
- if (!_initialized) {
- initOnAddImpl(effect, propRoot);
- _initialized = true;
- }
- }
- bool getInitialized() const { return _initialized; }
-private:
- virtual void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) = 0;
- bool _initialized;
-};
-
class DeferredPropertyListener {
public:
virtual void activate(SGPropertyNode* propRoot) {};
virtual ~DeferredPropertyListener() {};
};
-
class Effect : public osg::Object
{
public:
* Build the techniques from the effect properties.
*/
bool realizeTechniques(const SGReaderWriterOptions* options = 0);
- /**
- * Updaters that should be derefed when the effect is
- * deleted. Updaters arrange to be run by listening on properties
- * or something.
- */
- struct Updater : public virtual SGReferenced
- {
- virtual ~Updater() {}
- };
- void addUpdater(Updater* data) { _extraData.push_back(data); }
+ void addDeferredPropertyListener(DeferredPropertyListener* listener);
// Callback that is added to the effect geode to initialize the
// effect.
friend struct InitializeCallback;
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
};
protected:
- std::vector<SGSharedPtr<Updater> > _extraData;
~Effect();
// Support for a cache of effects that inherit from this one, so
// Effect objects with the same parameters and techniques can be
* used.
*/
template<typename OSGParamType, typename ObjType, typename F>
-DeferredPropertyListener*
+void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
const F& setter, const SGReaderWriterOptions* options)
{
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
- ScalarChangeListener<OSGParamType, ObjType, F>* listener = 0;
if (!valProp)
- return listener;
+ return;
if (valProp->nChildren() == 0) {
setter(obj, valProp->getValue<OSGParamType>());
} else {
setDynamicVariance(obj);
std::string propName = getGlobalProperty(valProp, options);
- listener
+ ScalarChangeListener<OSGParamType, ObjType, F>* listener
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
propName);
+ effect->addDeferredPropertyListener(listener);
}
- return listener;
+ return;
}
template<typename OSGParamType, typename ObjType, typename SetterReturn>
-inline DeferredPropertyListener*
+inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType),
const SGReaderWriterOptions* options)
{
- return initFromParameters<OSGParamType>(effect, prop, obj,
+ initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), options);
}
*/
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename F>
-DeferredPropertyListener*
+void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
const F& setter,
NameItrType nameItr, const SGReaderWriterOptions* options)
{
typedef typename Bridge<OSGParamType>::sg_type sg_type;
- DeferredPropertyListener* listener = 0;
const int numComponents = props::NumComponents<sg_type>::num_components;
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp)
- return listener;
+ return;
if (valProp->nChildren() == 0) { // Has <use>?
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
} else {
if (paramNames.empty())
throw BuilderException();
std::vector<std::string>::const_iterator pitr = paramNames.begin();
- listener
+ DeferredPropertyListener* listener
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
(obj, setter),
0, pitr, pitr + numComponents);
+ effect->addDeferredPropertyListener(listener);
}
- return listener;
+ return;
}
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename SetterReturn>
-inline DeferredPropertyListener*
+inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType&),
NameItrType nameItr, const SGReaderWriterOptions* options)
{
- return initFromParameters<OSGParamType>(effect, prop, obj,
+ initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), nameItr,
options);
}
#endif
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
if (colorNode) {
- DeferredPropertyListener* listener = initFromParameters(effect, colorNode, result,
+ initFromParameters(effect, colorNode, result,
&TexEnvCombine::setConstantColor, colorFields,
options);
- if (listener != 0) {
- SG_LOG(SG_ALL,SG_ALERT,"Texture with property defined parameter");
- }
}
return result;
}
string buffer;
};
-class BufferNameChangeListener : public SGPropertyChangeListener, public InitializeWhenAdded,
- public Effect::Updater {
+class BufferNameChangeListener : public SGPropertyChangeListener,
+ public DeferredPropertyListener {
public:
BufferNameChangeListener(Pass* p, int u, const std::string& pn) : pass(p), unit(u)
{
const char* buffer = node->getStringValue();
pass->setBufferUnit(unit, buffer);
}
- void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
+ void activate(SGPropertyNode* propRoot)
{
SGPropertyNode* listenProp = makeNode(propRoot, *propName);
delete propName;
} else {
std::string propName = getGlobalProperty(nameProp, options);
BufferNameChangeListener* listener = new BufferNameChangeListener(pass, unit, propName);
- effect->addUpdater(listener);
+ effect->addDeferredPropertyListener(listener);
}
// Return white for now. Would be overridden in Technique::ProcessDrawable