X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fresourcemanager.cpp;h=cdd032264345dae5d81d11bf17f10e3da9ed09d3;hb=5ae4b00;hp=059c29241335d464835bb3557bb8c6c98cc93a12;hpb=8ed7051d1a80c7e8b198d96575338eee6a5e2485;p=libs%2Fgl.git diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index 059c2924..cdd03226 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -1,5 +1,7 @@ +#include #include #include "resourcemanager.h" +#include "resourcewatcher.h" using namespace std; @@ -9,7 +11,9 @@ namespace GL { ResourceManager::ResourceManager(): policy(LOAD_ON_DEMAND), async_loads(true), + size_limit(0), frame(0), + min_retain_frames(30), max_retain_frames(0), next_unload(0), thread(*this) @@ -19,8 +23,8 @@ ResourceManager::~ResourceManager() { thread.terminate(); - for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i) - i->second.resource->set_manager(0); + while(!resources.empty()) + resources.begin()->second.resource->set_manager(0); } void ResourceManager::set_loading_policy(LoadingPolicy p) @@ -33,6 +37,16 @@ void ResourceManager::set_async_loads(bool a) async_loads = a; } +void ResourceManager::set_size_limit(UInt64 s) +{ + size_limit = s; +} + +void ResourceManager::set_min_retain_frames(unsigned f) +{ + min_retain_frames = f; +} + void ResourceManager::set_max_retain_frames(unsigned f) { max_retain_frames = f; @@ -98,11 +112,25 @@ void ResourceManager::remove_resource(Resource &r) remove_existing(resources, &r); } +void ResourceManager::watch_resource(const Resource &r, ResourceWatcher &w) +{ + get_item(resources, &r).add_watcher(w); +} + +void ResourceManager::unwatch_resource(const Resource &r, ResourceWatcher &w) +{ + get_item(resources, &r).remove_watcher(w); +} + void ResourceManager::tick() { LoadingThread::State thread_state = thread.get_state(); - if(thread_state==LoadingThread::SYNC_PENDING) + bool check_total_size = false; + if(thread_state==LoadingThread::SYNC_PENDING || thread_state==LoadingThread::LOAD_FINISHED) + { thread.sync(); + check_total_size = true; + } else if(thread_state==LoadingThread::IDLE && !queue.empty()) { ManagedResource *managed = queue.front(); @@ -128,6 +156,40 @@ void ResourceManager::tick() if(next_unload) next_unload += max_retain_frames; } + + if(check_total_size) + { + while(get_total_data_size()>size_limit) + { + unsigned unload_limit = frame-min_retain_frames; + ManagedResource *best = 0; + UInt64 best_impact = 0; + for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i) + if(i->second.loaded && i->second.last_usedsecond.data_size*(frame-i->second.last_used); + if(!best || impact>best_impact) + { + best = &i->second; + best_impact = impact; + } + } + + if(!best) + break; + + best->unload(); + } + } +} + +UInt64 ResourceManager::get_total_data_size() const +{ + UInt64 total = 0; + for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i) + if(i->second.loaded) + total += i->second.data_size; + return total; } @@ -137,7 +199,8 @@ ResourceManager::ManagedResource::ManagedResource(Resource &r): io(0), loader(0), loaded(false), - last_used(0) + last_used(0), + data_size(0) { } void ResourceManager::ManagedResource::start_loading() @@ -159,12 +222,32 @@ void ResourceManager::ManagedResource::finish_loading() loaded = true; delete io; io = 0; + data_size = resource->get_data_size(); + + for(vector::const_iterator i=watchers.begin(); i!=watchers.end(); ++i) + (*i)->resource_loaded(*resource); } void ResourceManager::ManagedResource::unload() { resource->unload(); loaded = false; + + for(vector::const_iterator i=watchers.begin(); i!=watchers.end(); ++i) + (*i)->resource_unloaded(*resource); +} + +void ResourceManager::ManagedResource::add_watcher(ResourceWatcher &w) +{ + if(find(watchers.begin(), watchers.end(), &w)==watchers.end()) + watchers.push_back(&w); +} + +void ResourceManager::ManagedResource::remove_watcher(ResourceWatcher &w) +{ + vector::iterator end = remove(watchers.begin(), watchers.end(), &w); + if(end!=watchers.end()) + watchers.erase(end, watchers.end()); }