X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fresourcemanager.h;h=9dcd9b997a56a25214ea691d27f2f616197ae55f;hp=fb4353350f4c2138a1b4a4d1d541b08bf1016f61;hb=13cf58be0e455227e8e5ae418b276a11c7873869;hpb=7db48f2836ec42c6e2dbeff336634a03bc6d7a62 diff --git a/source/resourcemanager.h b/source/resourcemanager.h index fb435335..9dcd9b99 100644 --- a/source/resourcemanager.h +++ b/source/resourcemanager.h @@ -1,6 +1,7 @@ #ifndef MSP_GL_RESOURCEMANAGER_H_ #define MSP_GL_RESOURCEMANAGER_H_ +#include #include #include #include @@ -10,6 +11,17 @@ namespace Msp { namespace GL { +class ResourceObserver; + +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: @@ -20,57 +32,100 @@ public: LOAD_MANUALLY }; -private: - struct ManagedResource + struct ResourceLocation { - Resource *resource; DataFile::Collection *collection; std::string name; - IO::Seekable *io; - Resource::AsyncLoader *loader; - ManagedResource(Resource &); + ResourceLocation(); + ResourceLocation(DataFile::Collection &, const std::string &); }; - class LoadingThread: public Thread +private: + struct ManagedResource { - public: enum State { - IDLE, - SYNC_PENDING, - BUSY, + NOT_LOADED, + LOAD_QUEUED, + LOADING, LOAD_FINISHED, - TERMINATING + LOADED, + LOAD_ERROR }; + Resource *resource; + ResourceLocation location; + bool load_priority; + IO::Seekable *io; + Resource::AsyncLoader *loader; + State state; + unsigned last_used; + UInt64 data_size; + std::vector observers; + + ManagedResource(Resource &); + + void start_loading(); + bool process(bool); + void finish_loading(bool); + void finish_loading(); + void unload(); + + void add_observer(ResourceObserver &); + void remove_observer(ResourceObserver &); + }; + + typedef std::list LoadQueue; + + class LoadingThread: public Thread + { 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 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 LoadQueue; + typedef std::map ResourceMap; LoadingPolicy policy; bool async_loads; - std::map resources; - std::list queue; + mutable Mutex map_mutex; + ResourceMap resources; + LoadQueue queue; + UInt64 total_data_size; + UInt64 size_limit; + unsigned frame; + unsigned min_retain_frames; + unsigned max_retain_frames; + unsigned next_unload; LoadingThread thread; public: @@ -79,13 +134,41 @@ public: void set_loading_policy(LoadingPolicy); void set_async_loads(bool); + void set_size_limit(UInt64); + void set_min_retain_frames(unsigned); + void set_max_retain_frames(unsigned); void add_resource(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 load_resource(const Resource &); + 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 observe_resource(const Resource &, ResourceObserver &); + void unobserve_resource(const Resource &, ResourceObserver &); + + // Deprecated names + void watch_resource(const Resource &r, ResourceObserver &o) { observe_resource(r, o); } + void unwatch_resource(const Resource &r, ResourceObserver &o) { unobserve_resource(r, o); } + void tick(); +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