diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 6acb41dc3..f2881d68f 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -166,6 +166,8 @@ namespace MWWorld , mBulletShapeManager(bulletShapeManager) , mTerrain(terrain) , mExpiryDelay(0.0) + , mMinCacheSize(0) + , mMaxCacheSize(0) { } @@ -197,6 +199,23 @@ namespace MWWorld return; } + while (mPreloadCells.size() >= mMaxCacheSize) + { + // throw out oldest cell to make room + PreloadMap::iterator oldestCell = mPreloadCells.begin(); + double oldestTimestamp = DBL_MAX; + for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end(); ++it) + { + if (it->second.mTimeStamp < oldestTimestamp) + { + oldestTimestamp = it->second.mTimeStamp; + oldestCell = it; + } + } + + mPreloadCells.erase(oldestCell); + } + osg::ref_ptr item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager(), mTerrain)); mWorkQueue->addWorkItem(item); @@ -210,11 +229,9 @@ namespace MWWorld void CellPreloader::updateCache(double timestamp) { - // TODO: add settings for a minimum/maximum size of the cache - for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();) { - if (it->second.mTimeStamp < timestamp - mExpiryDelay) + if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay) mPreloadCells.erase(it++); else ++it; @@ -229,6 +246,16 @@ namespace MWWorld mExpiryDelay = expiryDelay; } + void CellPreloader::setMinCacheSize(unsigned int num) + { + mMinCacheSize = num; + } + + void CellPreloader::setMaxCacheSize(unsigned int num) + { + mMaxCacheSize = num; + } + void CellPreloader::setWorkQueue(osg::ref_ptr workQueue) { mWorkQueue = workQueue; diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index 437395397..f78e66e75 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -38,6 +38,12 @@ namespace MWWorld /// How long to keep a preloaded cell in cache after it's no longer requested. void setExpiryDelay(double expiryDelay); + /// The minimum number of preloaded cells before unused cells get thrown out. + void setMinCacheSize(unsigned int num); + + /// The maximum number of preloaded cells. + void setMaxCacheSize(unsigned int num); + void setWorkQueue(osg::ref_ptr workQueue); private: @@ -46,6 +52,8 @@ namespace MWWorld Terrain::World* mTerrain; osg::ref_ptr mWorkQueue; double mExpiryDelay; + unsigned int mMinCacheSize; + unsigned int mMaxCacheSize; struct PreloadEntry { diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 308809bd2..cd0954260 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -463,9 +463,11 @@ namespace MWWorld mPhysics->setUnrefQueue(rendering.getUnrefQueue()); - float cacheExpiryDelay = Settings::Manager::getFloat("cache expiry delay", "Cells"); - rendering.getResourceSystem()->setExpiryDelay(cacheExpiryDelay); - mPreloader->setExpiryDelay(cacheExpiryDelay); + rendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells")); + + mPreloader->setExpiryDelay(Settings::Manager::getFloat("preload cell expiry delay", "Cells")); + mPreloader->setMinCacheSize(Settings::Manager::getInt("preload cell cache min", "Cells")); + mPreloader->setMaxCacheSize(Settings::Manager::getInt("preload cell cache max", "Cells")); } Scene::~Scene() diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 4a9a5dd65..c6c97546e 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -44,7 +44,7 @@ preload enabled = true preload exterior grid = true # Preload possible fast travel destinations. -preload fast travel = true +preload fast travel = false # Preload the locations that doors lead to. preload doors = true @@ -52,9 +52,19 @@ preload doors = true # Preloading distance threshold preload distance = 1000 -# How long to keep preloaded cells and cached models/textures/collision shapes in cache -# after they're no longer referenced/required (in seconds) -cache expiry delay = 300 +# The minimum amount of cells in the preload cache before unused cells start to get thrown out (see "preload cell expiry delay"). +# This value should be lower or equal to 'preload cell cache max'. +preload cell cache min = 12 + +# The maximum amount of cells in the preload cache. A too high value could cause you to run out of memory. +# You may need to reduce this setting when running lots of mods or high-res texture replacers. +preload cell cache max = 20 + +# How long to keep preloaded cells in cache after they're no longer referenced/required (in seconds) +preload cell expiry delay = 5 + +# How long to keep models/textures/collision shapes in cache after they're no longer referenced/required (in seconds) +cache expiry delay = 5 [Map]