X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fresourcemanager.cpp;h=733cfaff8c4c37ba5ae1ffbd605ceb3f8d6a58df;hb=da5629982b65a4cbf31abc30a0cf930801fcc940;hp=7bf4412f41c7bdbc7d372ab08aba0d9280f1cdfc;hpb=d184ad8a88156a5b0cfe926e5aa66fd574556560;p=libs%2Fgl.git diff --git a/source/resourcemanager.cpp b/source/resourcemanager.cpp index 7bf4412f..733cfaff 100644 --- a/source/resourcemanager.cpp +++ b/source/resourcemanager.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include "resourcemanager.h" #include "resourcewatcher.h" @@ -8,6 +11,15 @@ using namespace std; namespace Msp { namespace GL { +resource_load_error::resource_load_error(const string &name, const string &err): + runtime_error(format("%s: %s", name, err)) +{ } + +resource_load_error::resource_load_error(const string &name, const exception &exc): + runtime_error(format("%s: %s: %s", name, Debug::demangle(typeid(exc).name()), exc.what())) +{ } + + ResourceManager::ResourceManager(): policy(LOAD_ON_DEMAND), async_loads(true), @@ -62,19 +74,29 @@ void *ResourceManager::get_data_for_resource(const Resource &r) } void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c, const string &n) +{ + set_resource_location(r, ResourceLocation(c, n)); +} + +void ResourceManager::set_resource_location(Resource &r, const ResourceLocation &l) { ManagedResource &managed = get_item(resources, &r); - managed.collection = &c; - managed.name = n; + managed.location = l; if(policy==LOAD_IMMEDIATELY) load_resource(r); } +const ResourceManager::ResourceLocation *ResourceManager::get_resource_location(const Resource &r) const +{ + const ManagedResource &managed = get_item(resources, &r); + return managed.location.collection ? &managed.location : 0; +} + void ResourceManager::load_resource(Resource &r) { ManagedResource &managed = get_item(resources, &r); - if(!managed.collection) + if(!managed.location.collection) throw runtime_error("no location"); if(managed.state!=ManagedResource::NOT_LOADED) @@ -93,9 +115,17 @@ void ResourceManager::load_resource(Resource &r) } } +bool ResourceManager::is_resource_loaded(const Resource &r) const +{ + ManagedResource *managed = reinterpret_cast(r.get_manager_data()); + return managed ? managed->state==ManagedResource::LOADED : false; +} + void ResourceManager::resource_used(const Resource &r) { ManagedResource *managed = reinterpret_cast(r.get_manager_data()); + if(!managed) + return; if(managed->state==ManagedResource::NOT_LOADED && policy!=LOAD_MANUALLY) load_resource(*managed->resource); @@ -228,9 +258,18 @@ bool ResourceManager::age_order(ManagedResource *mr1, ManagedResource *mr2) } +ResourceManager::ResourceLocation::ResourceLocation(): + collection(0) +{ } + +ResourceManager::ResourceLocation::ResourceLocation(DataFile::Collection &c, const string &n): + collection(&c), + name(n) +{ } + + ResourceManager::ManagedResource::ManagedResource(Resource &r): resource(&r), - collection(0), io(0), loader(0), state(NOT_LOADED), @@ -240,7 +279,10 @@ ResourceManager::ManagedResource::ManagedResource(Resource &r): void ResourceManager::ManagedResource::start_loading() { - io = collection->open_raw(name); + io = location.collection->open_raw(location.name); + if(!io) + throw resource_load_error(location.name, "open failed"); + loader = resource->load(*io); if(!loader) { @@ -329,7 +371,16 @@ void ResourceManager::LoadingThread::main() if(ManagedResource *managed = front(async_queue)) { - managed->process(false); + try + { + managed->process(false); + } + catch(const exception &e) + { + MutexLock lock(queue_mutex); + error_queue.push_back(resource_load_error(managed->location.name, e)); + managed->state = ManagedResource::LOAD_ERROR; + } MutexLock lock(queue_mutex); sync_queue.splice(sync_queue.end(), async_queue, async_queue.begin()); @@ -398,6 +449,14 @@ bool ResourceManager::LoadingThread::sync() { { MutexLock lock(queue_mutex); + + if(!error_queue.empty()) + { + resource_load_error err = error_queue.front(); + error_queue.pop_front(); + throw err; + } + unsigned async_size = async_queue.size(); if(async_size==0 && size==capacity) ++capacity; @@ -408,7 +467,7 @@ bool ResourceManager::LoadingThread::sync() bool any_finished = false; while(ManagedResource *managed = front(sync_queue)) { - if(managed->process(true)) + if(managed->state==ManagedResource::LOAD_ERROR || managed->process(true)) { managed->finish_loading(); any_finished = true;