+++ /dev/null
-#include <msp/time/utils.h>
-#include "resourcemanager.h"
-
-using namespace std;
-
-namespace Msp {
-namespace GL {
-
-ResourceManager::ResourceManager():
- policy(LOAD_ON_DEMAND),
- async_loads(true),
- thread(*this)
-{ }
-
-ResourceManager::~ResourceManager()
-{
- thread.terminate();
-
- for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
- i->second.resource->set_manager(0);
-}
-
-void ResourceManager::add_resource(Resource &r)
-{
- insert_unique(resources, &r, ManagedResource(r));
-}
-
-void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c, const string &n)
-{
- ManagedResource &managed = get_item(resources, &r);
- managed.collection = &c;
- managed.name = n;
-
- if(policy==LOAD_IMMEDIATELY)
- load_resource(r);
-}
-
-void ResourceManager::load_resource(const Resource &r)
-{
- ManagedResource &managed = get_item(resources, &r);
- if(!managed.collection)
- throw runtime_error("no location");
-
- if(managed.loader)
- return;
-
- managed.io = managed.collection->open_raw(managed.name);
- managed.loader = managed.resource->load(*managed.io);
-
- queue.push_back(&managed);
-}
-
-void ResourceManager::remove_resource(Resource &r)
-{
- ManagedResource *loading = thread.get_resource();
- if(loading && loading->resource==&r)
- thread.set_resource(0);
-
- remove_existing(resources, &r);
-}
-
-void ResourceManager::tick()
-{
- LoadingThread::State thread_state = thread.get_state();
- if(thread_state==LoadingThread::SYNC_PENDING)
- thread.sync();
- else if(thread_state==LoadingThread::IDLE && !queue.empty())
- {
- ManagedResource *managed = queue.front();
- queue.pop_front();
- thread.set_resource(managed);
- }
-}
-
-
-ResourceManager::ManagedResource::ManagedResource(Resource &r):
- resource(&r),
- collection(0),
- io(0),
- loader(0)
-{ }
-
-
-ResourceManager::LoadingThread::LoadingThread(ResourceManager &m):
- manager(m),
- sem(1),
- resource(0),
- state(IDLE)
-{
- launch();
-}
-
-void ResourceManager::LoadingThread::main()
-{
- while(state!=TERMINATING)
- {
- sem.wait();
-
- if(state==BUSY)
- {
- Resource::AsyncLoader *ldr = resource->loader;
- bool finished = false;
- while(!finished && !ldr->needs_sync())
- finished = ldr->process();
-
- if(finished)
- state = LOAD_FINISHED;
- else
- state = SYNC_PENDING;
- }
- }
-}
-
-void ResourceManager::LoadingThread::set_resource(ManagedResource *r)
-{
- if(state!=IDLE)
- {
- while(state==BUSY) ;
- // Force finish to clean up the loader
- state = LOAD_FINISHED;
- sync();
- }
-
- resource = r;
- state = BUSY;
- sem.signal();
-}
-
-void ResourceManager::LoadingThread::sync()
-{
- State s = state;
- bool finished = (s==LOAD_FINISHED);
- if(s==SYNC_PENDING)
- {
- Resource::AsyncLoader *ldr = resource->loader;
- while(!finished && ldr->needs_sync())
- finished = ldr->process();
-
- if(!finished)
- {
- state = BUSY;
- sem.signal();
- return;
- }
- }
-
- if(finished)
- {
- delete resource->loader;
- resource->loader = 0;
- delete resource->io;
- resource->io = 0;
- resource = 0;
- state = IDLE;
- }
-}
-
-void ResourceManager::LoadingThread::terminate()
-{
- while(state==BUSY) ;
- state = TERMINATING;
- sem.signal();
- join();
-}
-
-} // namespace GL
-} // namespace Msp