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)19 DeleteHandler::DeleteHandler(int numberOfFramesToRetainObjects):
20     _numFramesToRetainObjects(numberOfFramesToRetainObjects),
21     _currentFrameNumber(0)
22 {
23 }
24 
~DeleteHandler()25 DeleteHandler::~DeleteHandler()
26 {
27     // flushAll();
28 }
29 
flush()30 void 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()66 void 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)101 void 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