/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include using namespace osgDB; bool ObjectCache::ClassComp::operator() (const ObjectCache::FileNameOptionsPair& lhs, const ObjectCache::FileNameOptionsPair& rhs) const { // check if filename are the same if (lhs.first < rhs.first) return true; if (rhs.first < lhs.first) return false; // check if Options pointers are the same. if (lhs.second == rhs.second) return false; // need to compare Options pointers if (lhs.second.valid() && rhs.second.valid()) { // lhs & rhs have valid Options objects return *lhs.second < *rhs.second; } // finally use pointer comparison, expecting at least one will be NULL pointer return lhs.second < rhs.second; } //////////////////////////////////////////////////////////////////////////////////////////// // // ObjectCache // ObjectCache::ObjectCache(): osg::Referenced(true) { // OSG_NOTICE<<"Constructed ObjectCache"< lock1(_objectCacheMutex); OpenThreads::ScopedLock lock2(objectCache->_objectCacheMutex); OSG_DEBUG<<"Inserting objects to main ObjectCache "<_objectCache.size()<_objectCache.begin(), objectCache->_objectCache.end()); } void ObjectCache::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp, const Options *options) { OpenThreads::ScopedLock lock(_objectCacheMutex); _objectCache[FileNameOptionsPair(filename, osg::clone(options))] = ObjectTimeStampPair(object,timestamp); OSG_DEBUG<<"Adding "<getOptionString() : "")<<"' to ObjectCache "< lock(_objectCacheMutex); ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options)); if (itr!=_objectCache.end()) { osg::ref_ptr o = itr->first.second; if (o.valid()) { OSG_DEBUG<<"Found "<getOptionString()<< "' in ObjectCache "<second.first.get(); } else return 0; } osg::ref_ptr ObjectCache::getRefFromObjectCache(const std::string& fileName, const Options *options) { OpenThreads::ScopedLock lock(_objectCacheMutex); ObjectCacheMap::iterator itr; itr = _objectCache.find(FileNameOptionsPair(fileName, options)); if (itr!=_objectCache.end()) { osg::ref_ptr o = itr->first.second; if (o.valid()) { OSG_DEBUG<<"Found "<getOptionString()<< "' in ObjectCache "<second.first.get(); } else return 0; } void ObjectCache::updateTimeStampOfObjectsInCacheWithExternalReferences(double referenceTime) { OpenThreads::ScopedLock lock(_objectCacheMutex); // look for objects with external references and update their time stamp. for(ObjectCacheMap::iterator itr=_objectCache.begin(); itr!=_objectCache.end(); ++itr) { // if ref count is greater the 1 the object has an external reference. if (itr->second.first->referenceCount()>1) { // so update it time stamp. itr->second.second = referenceTime; } } } void ObjectCache::removeExpiredObjectsInCache(double expiryTime) { OpenThreads::ScopedLock lock(_objectCacheMutex); // Remove expired entries from object cache ObjectCacheMap::iterator oitr = _objectCache.begin(); while(oitr != _objectCache.end()) { if (oitr->second.second<=expiryTime) { _objectCache.erase(oitr++); } else { ++oitr; } } } void ObjectCache::removeFromObjectCache(const std::string& fileName, const Options *options) { OpenThreads::ScopedLock lock(_objectCacheMutex); ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options)); if (itr!=_objectCache.end()) _objectCache.erase(itr); } void ObjectCache::clear() { OpenThreads::ScopedLock lock(_objectCacheMutex); _objectCache.clear(); } void ObjectCache::releaseGLObjects(osg::State* state) { OpenThreads::ScopedLock lock(_objectCacheMutex); for(ObjectCacheMap::iterator itr = _objectCache.begin(); itr != _objectCache.end(); ++itr) { osg::Object* object = itr->second.first.get(); object->releaseGLObjects(state); } }