1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12 */ 13 #include <osg/DeleteHandler> 14 #include <osg/Notify> 15 16 namespace osg 17 { 18 DeleteHandler(int numberOfFramesToRetainObjects)19DeleteHandler::DeleteHandler(int numberOfFramesToRetainObjects): 20 _numFramesToRetainObjects(numberOfFramesToRetainObjects), 21 _currentFrameNumber(0) 22 { 23 } 24 ~DeleteHandler()25DeleteHandler::~DeleteHandler() 26 { 27 // flushAll(); 28 } 29 flush()30void DeleteHandler::flush() 31 { 32 typedef std::list<const osg::Referenced*> DeletionList; 33 DeletionList deletionList; 34 35 { 36 // gather all the objects to delete whilst holding the mutex to the _objectsToDelete 37 // list, but delete the objects outside this scoped lock so that if any objects deleted 38 // unref their children then no deadlock happens. 39 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 40 unsigned int frameNumberToClearTo = _currentFrameNumber - _numFramesToRetainObjects; 41 42 ObjectsToDeleteList::iterator itr; 43 for(itr = _objectsToDelete.begin(); 44 itr != _objectsToDelete.end(); 45 ++itr) 46 { 47 if (itr->first > frameNumberToClearTo) break; 48 49 deletionList.push_back(itr->second); 50 51 itr->second = 0; 52 } 53 54 _objectsToDelete.erase( _objectsToDelete.begin(), itr); 55 } 56 57 for(DeletionList::iterator ditr = deletionList.begin(); 58 ditr != deletionList.end(); 59 ++ditr) 60 { 61 doDelete(*ditr); 62 } 63 64 } 65 flushAll()66void DeleteHandler::flushAll() 67 { 68 unsigned int temp_numFramesToRetainObjects = _numFramesToRetainObjects; 69 _numFramesToRetainObjects = 0; 70 71 typedef std::list<const osg::Referenced*> DeletionList; 72 DeletionList deletionList; 73 74 { 75 // gather all the objects to delete whilst holding the mutex to the _objectsToDelete 76 // list, but delete the objects outside this scoped lock so that if any objects deleted 77 // unref their children then no deadlock happens. 78 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 79 ObjectsToDeleteList::iterator itr; 80 for(itr = _objectsToDelete.begin(); 81 itr != _objectsToDelete.end(); 82 ++itr) 83 { 84 deletionList.push_back(itr->second); 85 itr->second = 0; 86 } 87 88 _objectsToDelete.erase( _objectsToDelete.begin(), _objectsToDelete.end()); 89 } 90 91 for(DeletionList::iterator ditr = deletionList.begin(); 92 ditr != deletionList.end(); 93 ++ditr) 94 { 95 doDelete(*ditr); 96 } 97 98 _numFramesToRetainObjects = temp_numFramesToRetainObjects; 99 } 100 requestDelete(const osg::Referenced * object)101void DeleteHandler::requestDelete(const osg::Referenced* object) 102 { 103 if (_numFramesToRetainObjects==0) doDelete(object); 104 else 105 { 106 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 107 _objectsToDelete.push_back(FrameNumberObjectPair(_currentFrameNumber,object)); 108 } 109 } 110 111 } // end of namespace osg 112