1 #ifndef MSP_GL_RESOURCEMANAGER_H_
2 #define MSP_GL_RESOURCEMANAGER_H_
6 #include <msp/core/mutex.h>
7 #include <msp/core/noncopyable.h>
8 #include <msp/core/semaphore.h>
9 #include <msp/core/thread.h>
10 #include <msp/datafile/collection.h>
16 class ResourceObserver;
18 class resource_load_error: public std::runtime_error
21 resource_load_error(const std::string &, const std::string &);
22 resource_load_error(const std::string &, const std::exception &);
23 virtual ~resource_load_error() throw() { }
27 class ResourceManager: public NonCopyable
37 struct ResourceLocation
39 DataFile::Collection *collection;
43 ResourceLocation(DataFile::Collection &, const std::string &);
47 struct ManagedResource
60 ResourceLocation location;
63 Resource::AsyncLoader *loader;
66 std::uint64_t data_size;
67 std::vector<ResourceObserver *> observers;
69 ManagedResource(Resource &);
73 void finish_loading(bool);
74 void finish_loading();
77 void add_observer(ResourceObserver &);
78 void remove_observer(ResourceObserver &);
81 class LoadingThread: public Thread
86 std::deque<ManagedResource *> async_queue;
87 std::deque<ManagedResource *> sync_queue;
90 std::list<resource_load_error> error_queue;
91 Mutex data_size_mutex;
92 std::uint64_t loaded_data_size;
101 ManagedResource *front(std::deque<ManagedResource *> &);
104 void add_resource(ManagedResource &);
105 void remove_resource(ManagedResource &);
107 bool try_remove_resource(ManagedResource &);
110 bool needs_work() const { return size<capacity; }
111 std::uint64_t get_and_reset_loaded_data_size();
116 LoadingPolicy policy = LOAD_ON_DEMAND;
117 bool async_loads = true;
118 mutable Mutex map_mutex;
119 std::map<const Resource *, ManagedResource> resources;
120 std::deque<ManagedResource *> queue;
121 std::uint64_t total_data_size = 0;
122 std::uint64_t size_limit = 0;
124 unsigned min_retain_frames = 30;
125 unsigned max_retain_frames = 0;
126 unsigned next_unload = 0;
127 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 &);
139 void move_resource(Resource &, Resource &);
141 const ManagedResource &get_managed_resource(const Resource &) const;
142 ManagedResource &get_managed_resource(const Resource &);
144 void *get_data_for_resource(const Resource &r) { return &get_managed_resource(r); }
145 void set_resource_location(Resource &, DataFile::Collection &, const std::string &);
146 void set_resource_location(Resource &, const ResourceLocation &);
147 const ResourceLocation *get_resource_location(const Resource &) const;
148 void load_resource(Resource &);
149 bool is_resource_loaded(const Resource &) const;
150 void resource_used(const Resource &);
151 void remove_resource(Resource &);
153 void observe_resource(const Resource &, ResourceObserver &);
154 void unobserve_resource(const Resource &, ResourceObserver &);
158 void dispatch_work();
159 void unload_by_age();
160 void unload_by_size();
162 std::uint64_t get_total_data_size() const { return total_data_size; }
165 static bool age_order(ManagedResource *, ManagedResource *);