1 #include <msp/time/utils.h>
2 #include "resourcemanager.h"
9 ResourceManager::ResourceManager():
10 policy(LOAD_ON_DEMAND),
18 ResourceManager::~ResourceManager()
22 for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
23 i->second.resource->set_manager(0);
26 void ResourceManager::set_loading_policy(LoadingPolicy p)
31 void ResourceManager::set_async_loads(bool a)
36 void ResourceManager::set_max_retain_frames(unsigned f)
38 max_retain_frames = f;
41 void ResourceManager::add_resource(Resource &r)
43 insert_unique(resources, &r, ManagedResource(r));
46 void *ResourceManager::get_data_for_resource(const Resource &r)
48 return &get_item(resources, &r);
51 void ResourceManager::set_resource_location(Resource &r, DataFile::Collection &c, const string &n)
53 ManagedResource &managed = get_item(resources, &r);
54 managed.collection = &c;
57 if(policy==LOAD_IMMEDIATELY)
61 void ResourceManager::load_resource(Resource &r)
63 ManagedResource &managed = get_item(resources, &r);
64 if(!managed.collection)
65 throw runtime_error("no location");
70 managed.start_loading();
73 queue.push_back(&managed);
76 while(!managed.loader->process()) ;
77 managed.finish_loading();
81 void ResourceManager::resource_used(const Resource &r)
83 ManagedResource *managed = reinterpret_cast<ManagedResource *>(r.get_manager_data());
84 if(!managed->loaded && !managed->loader && policy!=LOAD_MANUALLY)
85 load_resource(*managed->resource);
87 managed->last_used = frame;
88 if(max_retain_frames && !next_unload)
89 next_unload = frame+max_retain_frames;
92 void ResourceManager::remove_resource(Resource &r)
94 ManagedResource *loading = thread.get_resource();
95 if(loading && loading->resource==&r)
96 thread.set_resource(0);
98 remove_existing(resources, &r);
101 void ResourceManager::tick()
103 LoadingThread::State thread_state = thread.get_state();
104 if(thread_state==LoadingThread::SYNC_PENDING)
106 else if(thread_state==LoadingThread::IDLE && !queue.empty())
108 ManagedResource *managed = queue.front();
110 thread.set_resource(managed);
114 if(frame==next_unload)
116 unsigned unload_limit = frame-max_retain_frames;
119 for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
122 if(i->second.last_used<=unload_limit)
124 else if(!next_unload || i->second.last_used<next_unload)
125 next_unload = i->second.last_used;
129 next_unload += max_retain_frames;
134 ResourceManager::ManagedResource::ManagedResource(Resource &r):
143 void ResourceManager::ManagedResource::start_loading()
145 io = collection->open_raw(name);
146 loader = resource->load(*io);
151 throw logic_error("no loader created");
155 void ResourceManager::ManagedResource::finish_loading()
164 void ResourceManager::ManagedResource::unload()
171 ResourceManager::LoadingThread::LoadingThread(ResourceManager &m):
180 void ResourceManager::LoadingThread::main()
182 while(state!=TERMINATING)
188 Resource::AsyncLoader *ldr = resource->loader;
189 bool finished = false;
190 while(!finished && !ldr->needs_sync())
191 finished = ldr->process();
194 state = LOAD_FINISHED;
196 state = SYNC_PENDING;
201 void ResourceManager::LoadingThread::set_resource(ManagedResource *r)
206 // Force finish to clean up the loader
207 state = LOAD_FINISHED;
216 void ResourceManager::LoadingThread::sync()
219 bool finished = (s==LOAD_FINISHED);
222 Resource::AsyncLoader *ldr = resource->loader;
223 while(!finished && ldr->needs_sync())
224 finished = ldr->process();
236 resource->finish_loading();
242 void ResourceManager::LoadingThread::terminate()