void valueChanged(SGPropertyNode* node)
{
- _tniq->refreshValidity();
+ if (_tniq.valid())
+ _tniq->refreshValidity();
}
protected:
- osg::ref_ptr<Technique> _tniq;
+ osg::observer_ptr<Technique> _tniq;
};
template<typename T>
#include <boost/functional/hash.hpp>
#include <osg/Object>
+#include <osg/observer_ptr>
#include <osgDB/ReaderWriter>
#include <simgear/props/props.hxx>
bool operator()(const Key& lhs, const Key& rhs) const;
};
};
- typedef std::tr1::unordered_map<Key, osg::ref_ptr<Effect>,
+ typedef std::tr1::unordered_map<Key, osg::observer_ptr<Effect>,
boost::hash<Key>, Key::EqualTo> Cache;
Cache* getCache()
{
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
const SGReaderWriterOptions* options);
protected:
- typedef map<TexTuple, ref_ptr<T> > TexMap;
+ typedef map<TexTuple, observer_ptr<T> > TexMap;
TexMap texMap;
const string _type;
};
{
TexTuple attrs = makeTexTuple(effect, props, options, _type);
typename TexMap::iterator itr = texMap.find(attrs);
+
if (itr != texMap.end())
- return itr->second.get();
+ {
+ T* tex = itr->second.get();
+ if (tex)
+ return tex;
+ }
+
T* tex = new T;
setAttrs(attrs, tex, options);
- texMap.insert(make_pair(attrs, tex));
+ if (itr == texMap.end())
+ texMap.insert(make_pair(attrs, tex));
+ else
+ itr->second = tex; // update existing, but empty observer
return tex;
}
using namespace effect;
typedef vector<const SGPropertyNode*> RawPropVector;
-typedef map<const string, ref_ptr<Effect> > EffectMap;
+typedef map<const string, observer_ptr<Effect> > EffectMap;
namespace
{
{
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
EffectMap::iterator itr = effectMap.find(name);
- if (itr != effectMap.end())
+ if ((itr != effectMap.end())&&
+ itr->second.valid())
return itr->second.get();
}
string effectFileName(name);
itr = cache->find(key);
if (itr != cache->end()) {
effect = itr->second.get();
- effect->generator = parent->generator; // Copy the generators
+ if (effect.valid())
+ effect->generator = parent->generator; // Copy the generators
}
}
if (!effect.valid()) {
lock(effectMutex);
pair<Effect::Cache::iterator, bool> irslt
= cache->insert(make_pair(key, effect));
- if (!irslt.second)
- effect = irslt.first->second;
+ if (!irslt.second) {
+ ref_ptr<Effect> old = irslt.first->second.get();
+ if (old.valid())
+ effect = old; // Another thread beat us in creating it! Discard our own...
+ else
+ irslt.first->second = effect; // update existing, but empty observer
+ }
effect->generator = parent->generator; // Copy the generators
}
} else {
namespace
{
-typedef std::map<std::string, osg::ref_ptr<Effect> > EffectMap;
+typedef std::map<std::string, osg::observer_ptr<Effect> > EffectMap;
EffectMap effectMap;
}
// Create a new Effect for the texture, if required.
EffectMap::iterator iter = effectMap.find(texture);
- if (iter == effectMap.end()) {
+
+ if (iter != effectMap.end()) {
+ effect = iter->second.get();
+ }
+
+ if (!effect.valid())
+ {
SGPropertyNode_ptr pcloudEffect = new SGPropertyNode;
makeChild(pcloudEffect, "inherits-from")->setValue("Effects/cloud");
setValue(makeChild(makeChild(makeChild(pcloudEffect, "parameters"),
texture);
ref_ptr<SGReaderWriterOptions> options;
options = SGReaderWriterOptions::fromPath(texture_root.str());
- if ((effect = makeEffect(pcloudEffect, true, options.get())))
- effectMap.insert(EffectMap::value_type(texture, effect));
- } else {
- effect = iter->second.get();
+ effect = makeEffect(pcloudEffect, true, options.get());
+ if (effect.valid())
+ {
+ if (iter == effectMap.end())
+ effectMap.insert(EffectMap::value_type(texture, effect));
+ else
+ iter->second = effect; // update existing, but empty observer
+ }
}
}
// The density of the cloud is the shading applied
// to cloud sprites on the opposite side of the cloud
- // from the sun. For an invidual cloud instance a value
+ // from the sun. For an individual cloud instance a value
// between min_density and max_density is chosen.
float min_density;
float max_density;
static float sprite_density;
osg::Geometry* createOrthQuad(float w, float h, int varieties_x, int varieties_y);
-
};
}
}
-typedef std::map<std::string, osg::ref_ptr<Effect> > EffectMap;
+typedef std::map<std::string, osg::observer_ptr<Effect> > EffectMap;
static EffectMap treeEffectMap;
for (i = forestList.begin(); i != forestList.end(); ++i) {
TreeBin* forest = *i;
- Effect* effect = 0;
+ ref_ptr<Effect> effect;
EffectMap::iterator iter = treeEffectMap.find(forest->texture);
- if (iter == treeEffectMap.end()) {
+
+ if (iter != treeEffectMap.end())
+ effect = iter->second.get();
+
+ if (!effect.valid())
+ {
SGPropertyNode_ptr effectProp = new SGPropertyNode;
makeChild(effectProp, "inherits-from")->setStringValue("Effects/tree");
SGPropertyNode* params = makeChild(effectProp, "parameters");
params->getChild("texture", 0, true)->getChild("image", 0, true)
->setStringValue(forest->texture);
effect = makeEffect(effectProp, true, options);
- treeEffectMap.insert(EffectMap::value_type(forest->texture, effect));
- } else {
- effect = iter->second.get();
+ if (iter == treeEffectMap.end())
+ treeEffectMap.insert(EffectMap::value_type(forest->texture, effect));
+ else
+ iter->second = effect; // update existing, but empty observer
}
-
+
// Now, create a quadtree for the forest.
ShaderGeometryQuadtree
quadtree(GetTreeCoord(), AddTreesLeafObject(),
namespace
{
typedef boost::tuple<float, osg::Vec3, float, float, bool> PointParams;
-typedef std::map<PointParams, ref_ptr<Effect> > EffectMap;
+typedef std::map<PointParams, observer_ptr<Effect> > EffectMap;
EffectMap effectMap;
PointParams pointParams(size, attenuation, minSize, maxSize, directional);
ScopedLock<Mutex> lock(lightMutex);
EffectMap::iterator eitr = effectMap.find(pointParams);
- if (eitr != effectMap.end())
+ if ((eitr != effectMap.end())&&
+ eitr->second.valid())
return eitr->second.get();
// Basic stuff; no sprite or attenuation support
Pass *basicPass = new Pass;
spritePass->setTextureAttribute(0, attrFact->getStandardTexEnv());
Pass *combinedPass = clone(spritePass, CopyOp::SHALLOW_COPY);
combinedPass->setAttributeAndModes(point);
- Effect* effect = new Effect;
+ ref_ptr<Effect> effect = new Effect;
std::vector<std::string> parameterExtensions;
if (SGSceneFeatures::instance()->getEnablePointSpriteLights())
Technique* basicTniq = new Technique(true);
basicTniq->passes.push_back(basicPass);
effect->techniques.push_back(basicTniq);
- effectMap.insert(std::make_pair(pointParams, effect));
- return effect;
+ if (eitr == effectMap.end())
+ effectMap.insert(std::make_pair(pointParams, effect));
+ else
+ eitr->second = effect; // update existing, but empty observer
+ return effect.release();
}