bool ResourceCache::cloneOrCreateInstanceNode(InstanceResource* res, osg::ref_ptr<osg::Node>& output, const osgDB::Options* readOptions) { output = 0L; std::string key = res->getConfig().toJSON(false); // exclusive lock (since it's an LRU) { Threading::ScopedMutexLock exclusive( _instanceMutex ); // Deep copy everything except for images. Some models may share imagery so we only want one copy of it at a time. osg::CopyOp copyOp = osg::CopyOp::DEEP_COPY_ALL & ~osg::CopyOp::DEEP_COPY_IMAGES & ~osg::CopyOp::DEEP_COPY_TEXTURES; // double check to avoid race condition InstanceCache::Record rec; if ( _instanceCache.get(key, rec) && rec.value().valid() ) { output = osg::clone(rec.value().get(), copyOp); } else { // still not there, make it. output = res->createNode(readOptions); if ( output.valid() ) { _instanceCache.insert( key, output.get() ); output = osg::clone(output.get(), copyOp); } } } return output.valid(); }
bool ResourceCache::getOrCreateInstanceNode(InstanceResource* res, osg::ref_ptr<osg::Node>& output, const osgDB::Options* readOptions) { output = 0L; std::string key = res->getConfig().toJSON(false); // exclusive lock (since it's an LRU) { Threading::ScopedMutexLock exclusive( _instanceMutex ); // double check to avoid race condition InstanceCache::Record rec; if ( _instanceCache.get(key, rec) && rec.value().valid() ) { output = rec.value().get(); } else { // still not there, make it. output = res->createNode(readOptions); if ( output.valid() ) { _instanceCache.insert( key, output.get() ); } } } return output.valid(); }
osg::Node* ResourceCache::getInstanceNode( InstanceResource* res ) { osg::Node* result = 0L; if ( _threadSafe ) { // first check if it exists { Threading::ScopedReadLock shared( _mutex ); InstanceCache::Record rec = _instanceCache.get( res ); if ( rec.valid() ) { result = rec.value(); } } // no? exclusive lock and create it. if ( !result ) { Threading::ScopedWriteLock exclusive( _mutex ); // double check to avoid race condition InstanceCache::Record rec = _instanceCache.get( res ); if ( rec.valid() ) { result = rec.value(); } else { // still not there, make it. result = res->createNode( _dbOptions.get() ); if ( result ) _instanceCache.insert( res, result ); } } } else { InstanceCache::Record rec = _instanceCache.get( res ); if ( rec.valid() ) { result = rec.value(); } else { result = res->createNode( _dbOptions.get() ); if ( result ) _instanceCache.insert( res, result ); } } return result; }
bool ResourceCache::cloneOrCreateInstanceNode(InstanceResource* res, osg::ref_ptr<osg::Node>& output, osgDB::Options *localoptions, osgDB::Archive* ar) { output = 0L; std::string key = res->getConfig().toJSON(false); // exclusive lock (since it's an LRU) { Threading::ScopedMutexLock exclusive( _instanceMutex ); // double check to avoid race condition InstanceCache::Record rec; if ( _instanceCache.get(key, rec) && rec.value().valid() ) { output = osg::clone(rec.value().get(), osg::CopyOp::DEEP_COPY_ALL); } else { // still not there, make it. if (ar) { std::string modelname = res->uri().get().base(); osgDB::ReaderWriter::ReadResult r = ar->readNode(modelname, localoptions); if (r.validNode()) output = r.getNode(); } else { if (localoptions) output = res->createNode(localoptions); else output = res->createNode(_dbOptions.get()); } if ( output.valid() ) { _instanceCache.insert( key, output.get() ); output = osg::clone(output.get(), osg::CopyOp::DEEP_COPY_ALL); } } } return output.valid(); }
bool SubstituteModelFilter::findResource(const URI& uri, const InstanceSymbol* symbol, FilterContext& context, std::set<URI>& missing, osg::ref_ptr<InstanceResource>& output ) { // be careful about refptrs here since _instanceCache is an LRU. InstanceCache::Record rec; if ( _instanceCache.get(uri, rec) ) { // found it in the cache: output = rec.value().get(); } else if ( _resourceLib.valid() ) { // look it up in the resource library: output = _resourceLib->getInstance( uri.base(), context.getDBOptions() ); } else { // create it on the fly: output = symbol->createResource(); output->uri() = uri; _instanceCache.insert( uri, output.get() ); } // failed to find the instance. if ( !output.valid() ) { if ( missing.find(uri) == missing.end() ) { missing.insert(uri); OE_WARN << LC << "Failed to locate resource: " << uri.full() << std::endl; } } return output.valid(); }