From a81b10b4153751ee7c1cc117f8b9096dda70bb8b Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 7 Feb 2016 19:05:55 +0100 Subject: [PATCH] Make the cache expiryDelay configurable --- apps/openmw/mwworld/cellpreloader.cpp | 12 ++++++++---- apps/openmw/mwworld/cellpreloader.hpp | 4 ++++ apps/openmw/mwworld/scene.cpp | 4 ++++ components/resource/niffilemanager.cpp | 3 +-- components/resource/resourcemanager.cpp | 9 +++++++-- components/resource/resourcemanager.hpp | 6 ++++-- components/resource/resourcesystem.cpp | 10 ++++++++++ components/resource/resourcesystem.hpp | 3 +++ files/settings-default.cfg | 4 ++++ 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 429e3294d..13ce75d68 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -123,6 +123,7 @@ namespace MWWorld CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager) : mResourceSystem(resourceSystem) , mBulletShapeManager(bulletShapeManager) + , mExpiryDelay(0.0) { mWorkQueue = new SceneUtil::WorkQueue; } @@ -156,13 +157,11 @@ namespace MWWorld void CellPreloader::updateCache(double timestamp) { - // time (in seconds) to keep a preloaded cell in cache after it's no longer needed - // additionally we could support a minimum/maximum size for the cache - const double expiryTime = 60.0; + // 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 - expiryTime) + if (it->second.mTimeStamp < timestamp - mExpiryDelay) mPreloadCells.erase(it++); else ++it; @@ -172,6 +171,11 @@ namespace MWWorld mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, timestamp)); } + void CellPreloader::setExpiryDelay(double expiryDelay) + { + mExpiryDelay = expiryDelay; + } + void CellPreloader::setWorkQueue(osg::ref_ptr workQueue) { mWorkQueue = workQueue; diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index b3413b174..5a2432179 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -27,12 +27,16 @@ namespace MWWorld /// Removes preloaded cells that have not had a preload request for a while. void updateCache(double timestamp); + /// How long to keep a preloaded cell in cache after it's no longer requested. + void setExpiryDelay(double expiryDelay); + void setWorkQueue(osg::ref_ptr workQueue); private: Resource::ResourceSystem* mResourceSystem; Resource::BulletShapeManager* mBulletShapeManager; osg::ref_ptr mWorkQueue; + double mExpiryDelay; struct PreloadEntry { diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index c788df234..86f40df73 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -455,6 +455,10 @@ namespace MWWorld , mPreloadEnabled(Settings::Manager::getBool("preload enabled", "Cells")) { mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager())); + + float cacheExpiryDelay = Settings::Manager::getFloat("cache expiry delay", "Cells"); + rendering.getResourceSystem()->setExpiryDelay(cacheExpiryDelay); + mPreloader->setExpiryDelay(cacheExpiryDelay); } Scene::~Scene() diff --git a/components/resource/niffilemanager.cpp b/components/resource/niffilemanager.cpp index 3c7437520..ecb63db60 100644 --- a/components/resource/niffilemanager.cpp +++ b/components/resource/niffilemanager.cpp @@ -29,8 +29,7 @@ namespace Resource }; NifFileManager::NifFileManager(const VFS::Manager *vfs) - : ResourceManager(vfs, 0.0) // NIF files aren't needed any more when the converted objects are cached in SceneManager / BulletShapeManager, - // so we'll use expiryDelay of 0 to instantly delete NIF files after use. + : ResourceManager(vfs) { } diff --git a/components/resource/resourcemanager.cpp b/components/resource/resourcemanager.cpp index 03e6263b9..b6b38bfa2 100644 --- a/components/resource/resourcemanager.cpp +++ b/components/resource/resourcemanager.cpp @@ -5,10 +5,10 @@ namespace Resource { - ResourceManager::ResourceManager(const VFS::Manager *vfs, const double expiryDelay) + ResourceManager::ResourceManager(const VFS::Manager *vfs) : mVFS(vfs) , mCache(new Resource::ObjectCache) - , mExpiryDelay(expiryDelay) + , mExpiryDelay(0.0) { } @@ -26,6 +26,11 @@ namespace Resource mCache->clear(); } + void ResourceManager::setExpiryDelay(double expiryDelay) + { + mExpiryDelay = expiryDelay; + } + const VFS::Manager* ResourceManager::getVFS() const { return mVFS; diff --git a/components/resource/resourcemanager.hpp b/components/resource/resourcemanager.hpp index a9b6ab3d5..d2a1d1023 100644 --- a/components/resource/resourcemanager.hpp +++ b/components/resource/resourcemanager.hpp @@ -17,8 +17,7 @@ namespace Resource class ResourceManager { public: - /// @param expiryDelay how long to keep objects in cache after no longer being referenced. - ResourceManager(const VFS::Manager* vfs, const double expiryDelay = 300.0); + ResourceManager(const VFS::Manager* vfs); /// Clear cache entries that have not been referenced for longer than expiryDelay. virtual void updateCache(double referenceTime); @@ -26,6 +25,9 @@ namespace Resource /// Clear all cache entries regardless of having external references. virtual void clearCache(); + /// How long to keep objects in cache after no longer being referenced. + void setExpiryDelay (double expiryDelay); + const VFS::Manager* getVFS() const; protected: diff --git a/components/resource/resourcesystem.cpp b/components/resource/resourcesystem.cpp index a8ab6556d..5772f2b85 100644 --- a/components/resource/resourcesystem.cpp +++ b/components/resource/resourcesystem.cpp @@ -52,6 +52,16 @@ namespace Resource return mKeyframeManager.get(); } + void ResourceSystem::setExpiryDelay(double expiryDelay) + { + for (std::vector::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it) + (*it)->setExpiryDelay(expiryDelay); + + // NIF files aren't needed any more once the converted objects are cached in SceneManager / BulletShapeManager, + // so no point in using an expiry delay + mNifFileManager->setExpiryDelay(0.0); + } + void ResourceSystem::updateCache(double referenceTime) { for (std::vector::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it) diff --git a/components/resource/resourcesystem.hpp b/components/resource/resourcesystem.hpp index 30607432d..9b933ffc4 100644 --- a/components/resource/resourcesystem.hpp +++ b/components/resource/resourcesystem.hpp @@ -43,6 +43,9 @@ namespace Resource /// @note Does not delete resourceMgr. void removeResourceManager(ResourceManager* resourceMgr); + /// How long to keep objects in cache after no longer being referenced. + void setExpiryDelay(double expiryDelay); + /// @note May be called from any thread. const VFS::Manager* getVFS() const; diff --git a/files/settings-default.cfg b/files/settings-default.cfg index c03342600..4df20e709 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -43,6 +43,10 @@ preload enabled = 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 + [Map] # Size of each exterior cell in pixels in the world map. (e.g. 12 to 24).