class ResourceWatcher;
+class resource_load_error: public std::runtime_error
+{
+public:
+ resource_load_error(const std::string &, const std::string &);
+ resource_load_error(const std::string &, const std::exception &);
+ virtual ~resource_load_error() throw() { }
+};
+
+
class ResourceManager
{
public:
LOAD_MANUALLY
};
+ struct ResourceLocation
+ {
+ DataFile::Collection *collection;
+ std::string name;
+
+ ResourceLocation();
+ ResourceLocation(DataFile::Collection &, const std::string &);
+ };
+
private:
struct ManagedResource
{
- enum ResourceState
+ enum State
{
NOT_LOADED,
LOAD_QUEUED,
LOADING,
- LOADED
+ LOAD_FINISHED,
+ LOADED,
+ LOAD_ERROR
};
Resource *resource;
- DataFile::Collection *collection;
- std::string name;
+ ResourceLocation location;
+ bool load_priority;
IO::Seekable *io;
Resource::AsyncLoader *loader;
- ResourceState state;
+ State state;
unsigned last_used;
UInt64 data_size;
std::vector<ResourceWatcher *> watchers;
ManagedResource(Resource &);
void start_loading();
+ bool process(bool);
+ void finish_loading(bool);
void finish_loading();
void unload();
void remove_watcher(ResourceWatcher &);
};
+ typedef std::list<ManagedResource *> LoadQueue;
+
class LoadingThread: public Thread
{
- public:
- enum State
- {
- IDLE,
- SYNC_PENDING,
- BUSY,
- LOAD_FINISHED,
- TERMINATING
- };
-
private:
- ResourceManager &manager;
Semaphore sem;
- ManagedResource *volatile resource;
- volatile State state;
+ Mutex queue_mutex;
+ LoadQueue async_queue;
+ LoadQueue sync_queue;
+ unsigned capacity;
+ unsigned size;
+ std::list<resource_load_error> error_queue;
+ Mutex data_size_mutex;
+ UInt64 loaded_data_size;
+ volatile bool done;
public:
- LoadingThread(ResourceManager &);
+ LoadingThread();
private:
virtual void main();
+ ManagedResource *front(LoadQueue &);
+
+ public:
+ void add_resource(ManagedResource &);
+ void remove_resource(ManagedResource &);
+ private:
+ bool try_remove_resource(ManagedResource &);
public:
- void set_resource(ManagedResource *);
- ManagedResource *get_resource() const { return resource; }
- void sync();
- State get_state() const { return state; }
+ bool sync();
+ bool needs_work() const { return size<capacity; }
+ UInt64 get_and_reset_loaded_data_size();
void terminate();
};
typedef std::map<const Resource *, ManagedResource> ResourceMap;
- typedef std::list<ManagedResource *> LoadQueue;
LoadingPolicy policy;
bool async_loads;
+ mutable Mutex map_mutex;
ResourceMap resources;
LoadQueue queue;
+ UInt64 total_data_size;
UInt64 size_limit;
unsigned frame;
unsigned min_retain_frames;
void set_max_retain_frames(unsigned);
void add_resource(Resource &);
- void *get_data_for_resource(const Resource &);
+private:
+ const ManagedResource &get_managed_resource(const Resource &) const;
+ ManagedResource &get_managed_resource(const Resource &);
+public:
+ void *get_data_for_resource(const Resource &r) { return &get_managed_resource(r); }
void set_resource_location(Resource &, DataFile::Collection &, const std::string &);
+ void set_resource_location(Resource &, const ResourceLocation &);
+ const ResourceLocation *get_resource_location(const Resource &) const;
void load_resource(Resource &);
+ bool is_resource_loaded(const Resource &) const;
void resource_used(const Resource &);
void remove_resource(Resource &);
void unwatch_resource(const Resource &, ResourceWatcher &);
void tick();
- UInt64 get_total_data_size() const;
+private:
+ void dispatch_work();
+ void unload_by_age();
+ void unload_by_size();
+public:
+ UInt64 get_total_data_size() const { return total_data_size; }
+
+private:
+ static bool age_order(ManagedResource *, ManagedResource *);
};
} // namespace GL