]> git.tdb.fi Git - libs/gl.git/blob - source/resourcemanager.h
Add methods to query the state of a resource
[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 private:
35         struct ManagedResource
36         {
37                 enum State
38                 {
39                         NOT_LOADED,
40                         LOAD_QUEUED,
41                         LOADING,
42                         LOAD_FINISHED,
43                         LOADED,
44                         LOAD_ERROR
45                 };
46
47                 Resource *resource;
48                 DataFile::Collection *collection;
49                 std::string name;
50                 IO::Seekable *io;
51                 Resource::AsyncLoader *loader;
52                 State state;
53                 unsigned last_used;
54                 UInt64 data_size;
55                 std::vector<ResourceWatcher *> watchers;
56
57                 ManagedResource(Resource &);
58
59                 void start_loading();
60                 bool process(bool);
61                 void finish_loading(bool);
62                 void finish_loading();
63                 void unload();
64
65                 void add_watcher(ResourceWatcher &);
66                 void remove_watcher(ResourceWatcher &);
67         };
68
69         typedef std::list<ManagedResource *> LoadQueue;
70
71         class LoadingThread: public Thread
72         {
73         private:
74                 Semaphore sem;
75                 Mutex queue_mutex;
76                 LoadQueue async_queue;
77                 LoadQueue sync_queue;
78                 unsigned capacity;
79                 unsigned size;
80                 std::list<resource_load_error> error_queue;
81                 volatile bool done;
82
83         public:
84                 LoadingThread();
85
86         private:
87                 virtual void main();
88
89                 ManagedResource *front(LoadQueue &);
90
91         public:
92                 void add_resource(ManagedResource &);
93                 void remove_resource(ManagedResource &);
94         private:
95                 bool try_remove_resource(ManagedResource &);
96         public:
97                 bool sync();
98                 bool needs_work() const { return size<capacity; }
99
100                 void terminate();
101         };
102
103         typedef std::map<const Resource *, ManagedResource> ResourceMap;
104
105         LoadingPolicy policy;
106         bool async_loads;
107         ResourceMap resources;
108         LoadQueue queue;
109         UInt64 size_limit;
110         unsigned frame;
111         unsigned min_retain_frames;
112         unsigned max_retain_frames;
113         unsigned next_unload;
114         LoadingThread thread;
115
116 public:
117         ResourceManager();
118         ~ResourceManager();
119
120         void set_loading_policy(LoadingPolicy);
121         void set_async_loads(bool);
122         void set_size_limit(UInt64);
123         void set_min_retain_frames(unsigned);
124         void set_max_retain_frames(unsigned);
125
126         void add_resource(Resource &);
127         void *get_data_for_resource(const Resource &);
128         void set_resource_location(Resource &, DataFile::Collection &, const std::string &);
129         void load_resource(Resource &);
130         bool is_resource_loaded(const Resource &);
131         void resource_used(const Resource &);
132         void remove_resource(Resource &);
133
134         void watch_resource(const Resource &, ResourceWatcher &);
135         void unwatch_resource(const Resource &, ResourceWatcher &);
136
137         void tick();
138 private:
139         void dispatch_work();
140         void unload_by_age();
141         void unload_by_size();
142 public:
143         UInt64 get_total_data_size() const;
144
145 private:
146         static bool age_order(ManagedResource *, ManagedResource *);
147 };
148
149 } // namespace GL
150 } // namespace Msp
151
152 #endif