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)
|
, mKeyframeManager(keyframeManager)
|
||||||
, mTerrain(terrain)
|
, mTerrain(terrain)
|
||||||
, mPreloadInstances(preloadInstances)
|
, mPreloadInstances(preloadInstances)
|
||||||
|
, mAbort(false)
|
||||||
{
|
{
|
||||||
ListModelsVisitor visitor (mMeshes);
|
ListModelsVisitor visitor (mMeshes);
|
||||||
if (cell->getState() == MWWorld::CellStore::State_Loaded)
|
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.
|
/// Preload work to be called from the worker thread.
|
||||||
virtual void doWork()
|
virtual void doWork()
|
||||||
{
|
{
|
||||||
|
@ -92,6 +98,9 @@ namespace MWWorld
|
||||||
|
|
||||||
for (MeshList::const_iterator it = mMeshes.begin(); it != mMeshes.end(); ++it)
|
for (MeshList::const_iterator it = mMeshes.begin(); it != mMeshes.end(); ++it)
|
||||||
{
|
{
|
||||||
|
if (mAbort)
|
||||||
|
break;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string mesh = *it;
|
std::string mesh = *it;
|
||||||
|
@ -144,6 +153,8 @@ namespace MWWorld
|
||||||
Terrain::World* mTerrain;
|
Terrain::World* mTerrain;
|
||||||
bool mPreloadInstances;
|
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
|
// 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;
|
std::vector<osg::ref_ptr<const osg::Object> > mPreloadedObjects;
|
||||||
};
|
};
|
||||||
|
@ -187,7 +198,10 @@ namespace MWWorld
|
||||||
CellPreloader::~CellPreloader()
|
CellPreloader::~CellPreloader()
|
||||||
{
|
{
|
||||||
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it)
|
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it)
|
||||||
|
{
|
||||||
|
it->second.mWorkItem->abort();
|
||||||
it->second.mWorkItem->waitTillDone();
|
it->second.mWorkItem->waitTillDone();
|
||||||
|
}
|
||||||
mPreloadCells.clear();
|
mPreloadCells.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +242,10 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldestTimestamp + threshold < timestamp)
|
if (oldestTimestamp + threshold < timestamp)
|
||||||
|
{
|
||||||
|
oldestCell->second.mWorkItem->abort();
|
||||||
mPreloadCells.erase(oldestCell);
|
mPreloadCells.erase(oldestCell);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +263,10 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
// do the deletion in the background thread
|
// do the deletion in the background thread
|
||||||
if (found->second.mWorkItem)
|
if (found->second.mWorkItem)
|
||||||
|
{
|
||||||
|
found->second.mWorkItem->abort();
|
||||||
mUnrefQueue->push(mPreloadCells[cell].mWorkItem);
|
mUnrefQueue->push(mPreloadCells[cell].mWorkItem);
|
||||||
|
}
|
||||||
|
|
||||||
mPreloadCells.erase(found);
|
mPreloadCells.erase(found);
|
||||||
}
|
}
|
||||||
|
@ -257,7 +277,10 @@ namespace MWWorld
|
||||||
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();)
|
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();)
|
||||||
{
|
{
|
||||||
if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay)
|
if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay)
|
||||||
|
{
|
||||||
|
it->second.mWorkItem->abort();
|
||||||
mPreloadCells.erase(it++);
|
mPreloadCells.erase(it++);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,9 @@ namespace SceneUtil
|
||||||
/// Internal use by the WorkQueue.
|
/// Internal use by the WorkQueue.
|
||||||
void signalDone();
|
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:
|
protected:
|
||||||
OpenThreads::Atomic mDone;
|
OpenThreads::Atomic mDone;
|
||||||
OpenThreads::Mutex mMutex;
|
OpenThreads::Mutex mMutex;
|
||||||
|
|
Loading…
Reference in a new issue