Improvements to the DatabasePager and PagedLOD class adding support for

deleting expuired children in the database thread.
This commit is contained in:
Robert Osfield
2003-07-09 14:55:39 +00:00
parent dcbaf59753
commit 5aa47a77c2
9 changed files with 140 additions and 50 deletions

View File

@@ -31,7 +31,7 @@ Group::Group()
Group::Group(const Group& group,const CopyOp& copyop):
Node(group,copyop)
{
for(ChildList::const_iterator itr=group._children.begin();
for(NodeList::const_iterator itr=group._children.begin();
itr!=group._children.end();
++itr)
{
@@ -43,7 +43,7 @@ Group::Group(const Group& group,const CopyOp& copyop):
Group::~Group()
{
// remove reference to this from children's parent lists.
for(ChildList::iterator itr=_children.begin();
for(NodeList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
@@ -55,7 +55,7 @@ Group::~Group()
void Group::traverse(NodeVisitor& nv)
{
for(ChildList::iterator itr=_children.begin();
for(NodeList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
@@ -298,7 +298,7 @@ bool Group::computeBound() const
BoundingBox bb;
bb.init();
ChildList::const_iterator itr;
NodeList::const_iterator itr;
for(itr=_children.begin();
itr!=_children.end();
++itr)

View File

@@ -129,7 +129,7 @@ void PagedLOD::setTimeStamp(unsigned int childNo, double timeStamp)
_timeStampList[childNo] = timeStamp;
}
void PagedLOD::removeExpiredChildren(double expiryTime)
void PagedLOD::removeExpiredChildren(double expiryTime,NodeList& removedChildren)
{
for(unsigned int i=_children.size();i>0;)
{
@@ -137,6 +137,7 @@ void PagedLOD::removeExpiredChildren(double expiryTime)
if (!_fileNameList[i].empty() && _timeStampList[i]<expiryTime)
{
//std::cout<<"Removing child "<<_children[i].get()<<std::endl;
removedChildren.push_back(_children[i]);
Group::removeChild(_children[i].get());
}
}

View File

@@ -9,8 +9,13 @@ using namespace osgProducer;
DatabasePager::DatabasePager()
{
std::cout<<"Constructing DatabasePager()"<<std::endl;
//std::cout<<"Constructing DatabasePager()"<<std::endl;
_deleteRemovedSubgraphsInDatabaseThread = true;
_expiryDelay = 1.0;
_maximumTimeForCompiling = 0.005; // 5ms.
}
void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* group)
@@ -19,10 +24,10 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
// search to see if filename already exist in the file loaded list.
bool foundEntry = false;
_fileLoadedListMutex.lock();
_dataLoadedListMutex.lock();
for(DatabaseRequestList::iterator litr = _fileLoadedList.begin();
litr != _fileLoadedList.end() && !foundEntry;
for(DatabaseRequestList::iterator litr = _dataLoadedList.begin();
litr != _dataLoadedList.end() && !foundEntry;
++litr)
{
if ((*litr)->_fileName==fileName)
@@ -32,7 +37,7 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
}
}
_fileLoadedListMutex.unlock();
_dataLoadedListMutex.unlock();
if (!foundEntry)
{
@@ -78,6 +83,23 @@ void DatabasePager::run()
while(true)
{
//
// delete any children if required.
//
if (_deleteRemovedSubgraphsInDatabaseThread)
{
_childrenToDeleteListMutex.lock();
if (!_childrenToDeleteList.empty())
{
std::cout<<"In DatabasePager thread deleting "<<_childrenToDeleteList.size()<<" subgraphs"<<std::endl;
_childrenToDeleteList.clear();
}
_childrenToDeleteListMutex.unlock();
}
//
// load any subgraphs that are required.
//
osg::ref_ptr<DatabaseRequest> databaseRequest;
// get the front of the file request list.
@@ -97,11 +119,11 @@ void DatabasePager::run()
if (databaseRequest->_loadedModel.valid())
{
_fileLoadedListMutex.lock();
_dataLoadedListMutex.lock();
_fileLoadedList.push_back(databaseRequest);
_dataLoadedList.push_back(databaseRequest);
_fileLoadedListMutex.unlock();
_dataLoadedListMutex.unlock();
}
}
@@ -121,10 +143,10 @@ void DatabasePager::addLoadedDataToSceneGraph()
{
DatabaseRequestList localFileLoadedList;
// get the dat for the _fileLoadedList, leaving it empty via a std::vector<>.swap.
_fileLoadedListMutex.lock();
localFileLoadedList.swap(_fileLoadedList);
_fileLoadedListMutex.unlock();
// get the dat for the _dataLoadedList, leaving it empty via a std::vector<>.swap.
_dataLoadedListMutex.lock();
localFileLoadedList.swap(_dataLoadedList);
_dataLoadedListMutex.unlock();
// add the loaded data into the scene graph.
for(DatabaseRequestList::iterator itr=localFileLoadedList.begin();
@@ -144,13 +166,15 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
{
double expiryTime = currentFrameTime - _expiryDelay;
osg::NodeList childrenRemoved;
//std::cout<<"DatabasePager::removeExpiredSubgraphs("<<expiryTime<<") "<<std::endl;
for(PagedLODList::iterator itr=_pagedLODList.begin();
itr!=_pagedLODList.end();
++itr)
{
osg::PagedLOD* plod = itr->get();
plod->removeExpiredChildren(expiryTime);
plod->removeExpiredChildren(expiryTime,childrenRemoved);
}
for(unsigned int i=_pagedLODList.size();
@@ -171,7 +195,14 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
}
}
if (_deleteRemovedSubgraphsInDatabaseThread)
{
// transfer the removed children over to the to delete list so the database thread can delete them.
_childrenToDeleteListMutex.lock();
_childrenToDeleteList.insert(_childrenToDeleteList.begin(),childrenRemoved.begin(),childrenRemoved.end());
_childrenToDeleteListMutex.unlock();
}
// otherwise the childrenRemoved list will automatically unref() and deleting the nodes.
}
@@ -200,3 +231,8 @@ void DatabasePager::registerPagedLODs(osg::Node* subgraph)
if (subgraph) subgraph->accept(fplv);
}
void DatabasePager::compileRenderingObjects(osg::State& state)
{
// std::cout<<"Compiling rendering objects"<<std::endl;
}

View File

@@ -413,24 +413,6 @@ bool OsgCameraGroup::realize()
}
if (sfsn._foundPagedLOD)
{
std::cout << "setting up paged LOD"<<std::endl;
_databasePager = new DatabasePager;
_databasePager->registerPagedLODs(getTopMostSceneData());
for(SceneHandlerList::iterator p=_shvec.begin();
p!=_shvec.end();
++p)
{
(*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(_databasePager.get());
}
}
}

View File

@@ -296,11 +296,44 @@ bool Viewer::realize( ThreadingModel thread_model )
return realize();
}
class DatabasePagerCompileCallback : public OsgSceneHandler::Callback
{
public:
DatabasePagerCompileCallback(DatabasePager* databasePager):
_databasePager(databasePager)
{}
virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera)
{
_databasePager->compileRenderingObjects(*(sh.getSceneView()->getState()));
sh.drawImplementation(camera);
}
osg::ref_ptr<DatabasePager> _databasePager;
};
bool Viewer::realize()
{
if (_realized) return _realized;
OsgCameraGroup::realize();
// by default set up the DatabasePager.
{
_databasePager = new DatabasePager;
_databasePager->registerPagedLODs(getTopMostSceneData());
for(SceneHandlerList::iterator p=_shvec.begin();
p!=_shvec.end();
++p)
{
(*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(_databasePager.get());
(*p)->setDrawCallback(new DatabasePagerCompileCallback(_databasePager.get()));
}
}
// force a sync before we intialize the keyswitch manipulator to home
// so that Producer has a chance to set up the windows before we do