mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 20:19:57 +00:00
Add PreloadItem::abort() to avoid no longer required cells from blocking the work thread
This commit is contained in:
parent
d62c4259bd
commit
a46593fa74
2 changed files with 26 additions and 0 deletions
|
@ -55,6 +55,7 @@ namespace MWWorld
|
|||
, mKeyframeManager(keyframeManager)
|
||||
, mTerrain(terrain)
|
||||
, mPreloadInstances(preloadInstances)
|
||||
, mAbort(false)
|
||||
{
|
||||
ListModelsVisitor visitor (mMeshes);
|
||||
if (cell->getState() == MWWorld::CellStore::State_Loaded)
|
||||
|
@ -76,6 +77,11 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
virtual void abort()
|
||||
{
|
||||
mAbort = true;
|
||||
}
|
||||
|
||||
/// Preload work to be called from the worker thread.
|
||||
virtual void doWork()
|
||||
{
|
||||
|
@ -92,6 +98,9 @@ namespace MWWorld
|
|||
|
||||
for (MeshList::const_iterator it = mMeshes.begin(); it != mMeshes.end(); ++it)
|
||||
{
|
||||
if (mAbort)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
std::string mesh = *it;
|
||||
|
@ -144,6 +153,8 @@ namespace MWWorld
|
|||
Terrain::World* mTerrain;
|
||||
bool mPreloadInstances;
|
||||
|
||||
volatile bool mAbort;
|
||||
|
||||
// keep a ref to the loaded objects to make sure it stays loaded as long as this cell is in the preloaded state
|
||||
std::vector<osg::ref_ptr<const osg::Object> > mPreloadedObjects;
|
||||
};
|
||||
|
@ -187,7 +198,10 @@ namespace MWWorld
|
|||
CellPreloader::~CellPreloader()
|
||||
{
|
||||
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it)
|
||||
{
|
||||
it->second.mWorkItem->abort();
|
||||
it->second.mWorkItem->waitTillDone();
|
||||
}
|
||||
mPreloadCells.clear();
|
||||
}
|
||||
|
||||
|
@ -228,7 +242,10 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
if (oldestTimestamp + threshold < timestamp)
|
||||
{
|
||||
oldestCell->second.mWorkItem->abort();
|
||||
mPreloadCells.erase(oldestCell);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
@ -246,7 +263,10 @@ namespace MWWorld
|
|||
{
|
||||
// do the deletion in the background thread
|
||||
if (found->second.mWorkItem)
|
||||
{
|
||||
found->second.mWorkItem->abort();
|
||||
mUnrefQueue->push(mPreloadCells[cell].mWorkItem);
|
||||
}
|
||||
|
||||
mPreloadCells.erase(found);
|
||||
}
|
||||
|
@ -257,7 +277,10 @@ namespace MWWorld
|
|||
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();)
|
||||
{
|
||||
if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay)
|
||||
{
|
||||
it->second.mWorkItem->abort();
|
||||
mPreloadCells.erase(it++);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ namespace SceneUtil
|
|||
/// Internal use by the WorkQueue.
|
||||
void signalDone();
|
||||
|
||||
/// Set abort flag in order to return from doWork() as soon as possible. May not be respected by all WorkItems.
|
||||
virtual void abort() {}
|
||||
|
||||
protected:
|
||||
OpenThreads::Atomic mDone;
|
||||
OpenThreads::Mutex mMutex;
|
||||
|
|
Loading…
Reference in a new issue