1 #ifndef MSP_GL_RESOURCEMANAGER_H_
2 #define MSP_GL_RESOURCEMANAGER_H_
6 #include <msp/core/mutex.h>
7 #include <msp/core/semaphore.h>
8 #include <msp/core/thread.h>
9 #include <msp/datafile/collection.h>
15 class ResourceObserver;
17 class resource_load_error: public std::runtime_error
20 resource_load_error(const std::string &, const std::string &);
21 resource_load_error(const std::string &, const std::exception &);
22 virtual ~resource_load_error() throw() { }
36 struct ResourceLocation
38 DataFile::Collection *collection;
42 ResourceLocation(DataFile::Collection &, const std::string &);
46 struct ManagedResource
59 ResourceLocation location;
62 Resource::AsyncLoader *loader;
65 std::uint64_t data_size;
66 std::vector<ResourceObserver *> observers;
68 ManagedResource(Resource &);
72 void finish_loading(bool);
73 void finish_loading();
76 void add_observer(ResourceObserver &);
77 void remove_observer(ResourceObserver &);
80 class LoadingThread: public Thread
85 std::deque<ManagedResource *> async_queue;
86 std::deque<ManagedResource *> sync_queue;
89 std::list<resource_load_error> error_queue;
90 Mutex data_size_mutex;
91 std::uint64_t loaded_data_size;
100 ManagedResource *front(std::deque<ManagedResource *> &);
103 void add_resource(ManagedResource &);
104 void remove_resource(ManagedResource &);
106 bool try_remove_resource(ManagedResource &);
109 bool needs_work() const { return size<capacity; }
110 std::uint64_t get_and_reset_loaded_data_size();
115 LoadingPolicy policy;
117 mutable Mutex map_mutex;
118 std::map<const Resource *, ManagedResource> resources;
119 std::deque<ManagedResource *> queue;
120 std::uint64_t total_data_size;
121 std::uint64_t size_limit;
123 unsigned min_retain_frames;
124 unsigned max_retain_frames;
125 unsigned next_unload;
126 LoadingThread thread;
132 void set_loading_policy(LoadingPolicy);
133 void set_async_loads(bool);
134 void set_size_limit(std::uint64_t);
135 void set_min_retain_frames(unsigned);
136 void set_max_retain_frames(unsigned);
138 void add_resource(Resource &);
140 const ManagedResource &get_managed_resource(const Resource &) const;
141 ManagedResource &get_managed_resource(const Resource &);
143 void *get_data_for_resource(const Resource &r) { return &get_managed_resource(r); }
144 void set_resource_location(Resource &, DataFile::Collection &, const std::string &);
145 void set_resource_location(Resource &, const ResourceLocation &);
146 const ResourceLocation *get_resource_location(const Resource &) const;
147 void load_resource(Resource &);
148 bool is_resource_loaded(const Resource &) const;
149 void resource_used(const Resource &);
150 void remove_resource(Resource &);
152 void observe_resource(const Resource &, ResourceObserver &);
153 void unobserve_resource(const Resource &, ResourceObserver &);
157 void dispatch_work();
158 void unload_by_age();
159 void unload_by_size();
161 std::uint64_t get_total_data_size() const { return total_data_size; }
164 static bool age_order(ManagedResource *, ManagedResource *);