From 8ed7051d1a80c7e8b198d96575338eee6a5e2485 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 8 Sep 2014 21:28:22 +0300 Subject: [PATCH] Implement automatic resource unloading based on age --- source/resourcemanager.cpp | 40 +++++++++++++++++++++++++++++++++++++- source/resourcemanager.h | 7 +++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index cc69b895..059c2924 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -9,6 +9,9 @@ namespace GL { ResourceManager::ResourceManager(): policy(LOAD_ON_DEMAND), async_loads(true), + frame(0), + max_retain_frames(0), + next_unload(0), thread(*this) { } @@ -30,6 +33,11 @@ void ResourceManager::set_async_loads(bool a) async_loads = a; } +void ResourceManager::set_max_retain_frames(unsigned f) +{ + max_retain_frames = f; +} + void ResourceManager::add_resource(Resource &r) { insert_unique(resources, &r, ManagedResource(r)); @@ -75,6 +83,10 @@ void ResourceManager::resource_used(const Resource &r) ManagedResource *managed = reinterpret_cast(r.get_manager_data()); if(!managed->loaded && !managed->loader && policy!=LOAD_MANUALLY) load_resource(*managed->resource); + + managed->last_used = frame; + if(max_retain_frames && !next_unload) + next_unload = frame+max_retain_frames; } void ResourceManager::remove_resource(Resource &r) @@ -97,6 +109,25 @@ void ResourceManager::tick() queue.pop_front(); thread.set_resource(managed); } + + ++frame; + if(frame==next_unload) + { + unsigned unload_limit = frame-max_retain_frames; + next_unload = 0; + + for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i) + if(i->second.loaded) + { + if(i->second.last_used<=unload_limit) + i->second.unload(); + else if(!next_unload || i->second.last_usedsecond.last_used; + } + + if(next_unload) + next_unload += max_retain_frames; + } } @@ -105,7 +136,8 @@ ResourceManager::ManagedResource::ManagedResource(Resource &r): collection(0), io(0), loader(0), - loaded(false) + loaded(false), + last_used(0) { } void ResourceManager::ManagedResource::start_loading() @@ -129,6 +161,12 @@ void ResourceManager::ManagedResource::finish_loading() io = 0; } +void ResourceManager::ManagedResource::unload() +{ + resource->unload(); + loaded = false; +} + ResourceManager::LoadingThread::LoadingThread(ResourceManager &m): manager(m), diff --git a/source/resourcemanager.h b/source/resourcemanager.h index 1e3cb54f..07b0aaf0 100644 --- a/source/resourcemanager.h +++ b/source/resourcemanager.h @@ -29,11 +29,13 @@ private: IO::Seekable *io; Resource::AsyncLoader *loader; bool loaded; + unsigned last_used; ManagedResource(Resource &); void start_loading(); void finish_loading(); + void unload(); }; class LoadingThread: public Thread @@ -76,6 +78,10 @@ private: bool async_loads; ResourceMap resources; LoadQueue queue; + unsigned frame; + unsigned min_retain_frames; + unsigned max_retain_frames; + unsigned next_unload; LoadingThread thread; public: @@ -84,6 +90,7 @@ public: void set_loading_policy(LoadingPolicy); void set_async_loads(bool); + void set_max_retain_frames(unsigned); void add_resource(Resource &); void *get_data_for_resource(const Resource &); -- 2.43.0