]> git.tdb.fi Git - libs/gl.git/blob - source/resourcemanager.h
Make is_resource_loaded const as it should be
[libs/gl.git] / source / resourcemanager.h
1 #ifndef MSP_GL_RESOURCEMANAGER_H_
2 #define MSP_GL_RESOURCEMANAGER_H_
3
4 #include <msp/core/inttypes.h>
5 #include <msp/core/mutex.h>
6 #include <msp/core/semaphore.h>
7 #include <msp/core/thread.h>
8 #include <msp/datafile/collection.h>
9 #include "resource.h"
10
11 namespace Msp {
12 namespace GL {
13
14 class ResourceWatcher;
15
16 class resource_load_error: public std::runtime_error
17 {
18 public:
19         resource_load_error(const std::string &, const std::exception &);
20         virtual ~resource_load_error() throw() { }
21 };
22
23
24 class ResourceManager
25 {
26 public:
27         enum LoadingPolicy
28         {
29                 LOAD_IMMEDIATELY,
30                 LOAD_ON_DEMAND,
31                 LOAD_MANUALLY
32         };
33
34         struct ResourceLocation
35         {
36                 DataFile::Collection *collection;
37                 std::string name;
38
39                 ResourceLocation();
40                 ResourceLocation(DataFile::Collection &, const std::string &);
41         };
42
43 private:
44         struct ManagedResource
45         {
46                 enum State
47                 {
48                         NOT_LOADED,
49                         LOAD_QUEUED,
50                         LOADING,
51                         LOAD_FINISHED,
52                         LOADED,
53                         LOAD_ERROR
54                 };
55
56                 Resource *resource;
57                 ResourceLocation location;
58                 IO::Seekable *io;
59                 Resource::AsyncLoader *loader;
60                 State state;
61                 unsigned last_used;
62                 UInt64 data_size;
63                 std::vector<ResourceWatcher *> watchers;
64
65                 ManagedResource(Resource &);
66
67                 void start_loading();
68                 bool process(bool);
69                 void finish_loading(bool);
70                 void finish_loading();
71                 void unload();
72
73                 void add_watcher(ResourceWatcher &);
74                 void remove_watcher(ResourceWatcher &);
75         };
76
77         typedef std::list<ManagedResource *> LoadQueue;
78
79         class LoadingThread: public Thread
80         {
81         private:
82                 Semaphore sem;
83                 Mutex queue_mutex;
84                 LoadQueue async_queue;
85                 LoadQueue sync_queue;
86                 unsigned capacity;
87                 unsigned size;
88                 std::list<resource_load_error> error_queue;
89                 volatile bool done;
90
91         public:
92                 LoadingThread();
93
94         private:
95                 virtual void main();
96
97                 ManagedResource *front(LoadQueue &);
98
99         public:
100                 void add_resource(ManagedResource &);
101                 void remove_resource(ManagedResource &);
102         private:
103                 bool try_remove_resource(ManagedResource &);
104         public:
105                 bool sync();
106                 bool needs_work() const { return size<capacity; }
107
108                 void terminate();
109         };
110
111         typedef std::map<const Resource *, ManagedResource> ResourceMap;
112
113         LoadingPolicy policy;
114         bool async_loads;
115         ResourceMap resources;
116         LoadQueue queue;
117         UInt64 size_limit;
118         unsigned frame;
119         unsigned min_retain_frames;
120         unsigned max_retain_frames;
121         unsigned next_unload;
122         LoadingThread thread;
123
124 public:
125         ResourceManager();
126         ~ResourceManager();
127
128         void set_loading_policy(LoadingPolicy);
129         void set_async_loads(bool);
130         void set_size_limit(UInt64);
131         void set_min_retain_frames(unsigned);
132         void set_max_retain_frames(unsigned);
133
134         void add_resource(Resource &);
135         void *get_data_for_resource(const Resource &);
136         void set_resource_location(Resource &, DataFile::Collection &, const std::string &);
137         void set_resource_location(Resource &, const ResourceLocation &);
138         const ResourceLocation *get_resource_location(const Resource &) const;
139         void load_resource(Resource &);
140         bool is_resource_loaded(const Resource &) const;
141         void resource_used(const Resource &);
142         void remove_resource(Resource &);
143
144         void watch_resource(const Resource &, ResourceWatcher &);
145         void unwatch_resource(const Resource &, ResourceWatcher &);
146
147         void tick();
148 private:
149         void dispatch_work();
150         void unload_by_age();
151         void unload_by_size();
152 public:
153         UInt64 get_total_data_size() const;
154
155 private:
156         static bool age_order(ManagedResource *, ManagedResource *);
157 };
158
159 } // namespace GL
160 } // namespace Msp
161
162 #endif