X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fresourcemanager.cpp;h=059c29241335d464835bb3557bb8c6c98cc93a12;hb=8ed7051d1a80c7e8b198d96575338eee6a5e2485;hp=b778175e12d7d59e8898b1f7c53b4eace1cc5cef;hpb=0464dbb64e5750ee8a00a54fbb0e2f147b83c883;p=libs%2Fgl.git diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index b778175e..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) { } @@ -20,11 +23,31 @@ ResourceManager::~ResourceManager() i->second.resource->set_manager(0); } +void ResourceManager::set_loading_policy(LoadingPolicy p) +{ + policy = p; +} + +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)); } +void *ResourceManager::get_data_for_resource(const Resource &r) +{ + return &get_item(resources, &r); +} + void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c, const string &n) { ManagedResource &managed = get_item(resources, &r); @@ -35,7 +58,7 @@ void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c load_resource(r); } -void ResourceManager::load_resource(const Resource &r) +void ResourceManager::load_resource(Resource &r) { ManagedResource &managed = get_item(resources, &r); if(!managed.collection) @@ -44,16 +67,26 @@ void ResourceManager::load_resource(const Resource &r) if(managed.loader) return; - managed.io = managed.collection->open_raw(managed.name); - managed.loader = managed.resource->load(*managed.io); - if(!managed.loader) + managed.start_loading(); + + if(async_loads) + queue.push_back(&managed); + else { - delete managed.io; - managed.io = 0; - throw logic_error("no loader created"); + while(!managed.loader->process()) ; + managed.finish_loading(); } +} + +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); - queue.push_back(&managed); + managed->last_used = frame; + if(max_retain_frames && !next_unload) + next_unload = frame+max_retain_frames; } void ResourceManager::remove_resource(Resource &r) @@ -76,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; + } } @@ -83,9 +135,38 @@ ResourceManager::ManagedResource::ManagedResource(Resource &r): resource(&r), collection(0), io(0), - loader(0) + loader(0), + loaded(false), + last_used(0) { } +void ResourceManager::ManagedResource::start_loading() +{ + io = collection->open_raw(name); + loader = resource->load(*io); + if(!loader) + { + delete io; + io = 0; + throw logic_error("no loader created"); + } +} + +void ResourceManager::ManagedResource::finish_loading() +{ + delete loader; + loader = 0; + loaded = true; + delete io; + io = 0; +} + +void ResourceManager::ManagedResource::unload() +{ + resource->unload(); + loaded = false; +} + ResourceManager::LoadingThread::LoadingThread(ResourceManager &m): manager(m), @@ -152,10 +233,7 @@ void ResourceManager::LoadingThread::sync() if(finished) { - delete resource->loader; - resource->loader = 0; - delete resource->io; - resource->io = 0; + resource->finish_loading(); resource = 0; state = IDLE; }