Opening it when the load is queued can cause large numbers of open files
to be created at once and dissipate slowly as the queue is processed.
if(!managed.collection)
throw runtime_error("no location");
if(!managed.collection)
throw runtime_error("no location");
+ if(managed.state!=ManagedResource::NOT_LOADED)
- managed.start_loading();
-
+ {
+ managed.state = ManagedResource::LOAD_QUEUED;
queue.push_back(&managed);
queue.push_back(&managed);
+ managed.start_loading();
while(!managed.loader->process()) ;
managed.finish_loading();
}
while(!managed.loader->process()) ;
managed.finish_loading();
}
void ResourceManager::resource_used(const Resource &r)
{
ManagedResource *managed = reinterpret_cast<ManagedResource *>(r.get_manager_data());
void ResourceManager::resource_used(const Resource &r)
{
ManagedResource *managed = reinterpret_cast<ManagedResource *>(r.get_manager_data());
- if(!managed->loaded && !managed->loader && policy!=LOAD_MANUALLY)
+ if(managed->state==ManagedResource::NOT_LOADED && policy!=LOAD_MANUALLY)
load_resource(*managed->resource);
managed->last_used = frame;
load_resource(*managed->resource);
managed->last_used = frame;
next_unload = 0;
for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
next_unload = 0;
for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
+ if(i->second.state==ManagedResource::LOADED)
{
if(i->second.last_used<=unload_limit)
i->second.unload();
{
if(i->second.last_used<=unload_limit)
i->second.unload();
ManagedResource *best = 0;
UInt64 best_impact = 0;
for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
ManagedResource *best = 0;
UInt64 best_impact = 0;
for(ResourceMap::iterator i=resources.begin(); i!=resources.end(); ++i)
- if(i->second.loaded && i->second.last_used<unload_limit)
+ if(i->second.state==ManagedResource::LOADED && i->second.last_used<unload_limit)
{
UInt64 impact = i->second.data_size*(frame-i->second.last_used);
if(!best || impact>best_impact)
{
UInt64 impact = i->second.data_size*(frame-i->second.last_used);
if(!best || impact>best_impact)
{
UInt64 total = 0;
for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i)
{
UInt64 total = 0;
for(ResourceMap::const_iterator i=resources.begin(); i!=resources.end(); ++i)
+ if(i->second.state==ManagedResource::LOADED)
total += i->second.data_size;
return total;
}
total += i->second.data_size;
return total;
}
collection(0),
io(0),
loader(0),
collection(0),
io(0),
loader(0),
last_used(0),
data_size(0)
{ }
last_used(0),
data_size(0)
{ }
io = 0;
throw logic_error("no loader created");
}
io = 0;
throw logic_error("no loader created");
}
}
void ResourceManager::ManagedResource::finish_loading()
{
delete loader;
loader = 0;
}
void ResourceManager::ManagedResource::finish_loading()
{
delete loader;
loader = 0;
delete io;
io = 0;
data_size = resource->get_data_size();
delete io;
io = 0;
data_size = resource->get_data_size();
void ResourceManager::ManagedResource::unload()
{
resource->unload();
void ResourceManager::ManagedResource::unload()
{
resource->unload();
for(vector<ResourceWatcher *>::const_iterator i=watchers.begin(); i!=watchers.end(); ++i)
(*i)->resource_unloaded(*resource);
for(vector<ResourceWatcher *>::const_iterator i=watchers.begin(); i!=watchers.end(); ++i)
(*i)->resource_unloaded(*resource);
+ resource->start_loading();
state = BUSY;
sem.signal();
}
state = BUSY;
sem.signal();
}
private:
struct ManagedResource
{
private:
struct ManagedResource
{
+ enum ResourceState
+ {
+ NOT_LOADED,
+ LOAD_QUEUED,
+ LOADING,
+ LOADED
+ };
+
Resource *resource;
DataFile::Collection *collection;
std::string name;
IO::Seekable *io;
Resource::AsyncLoader *loader;
Resource *resource;
DataFile::Collection *collection;
std::string name;
IO::Seekable *io;
Resource::AsyncLoader *loader;
unsigned last_used;
UInt64 data_size;
std::vector<ResourceWatcher *> watchers;
unsigned last_used;
UInt64 data_size;
std::vector<ResourceWatcher *> watchers;