]> git.tdb.fi Git - libs/gl.git/blobdiff - source/resourcemanager.h
Fix the keyword of the uniform scaling statement in Transform loader
[libs/gl.git] / source / resourcemanager.h
index 49a4c0bde3a7d33b1a02da359c486257a2e9b735..9dcd9b997a56a25214ea691d27f2f616197ae55f 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GL_RESOURCEMANAGER_H_
 #define MSP_GL_RESOURCEMANAGER_H_
 
+#include <msp/core/inttypes.h>
 #include <msp/core/mutex.h>
 #include <msp/core/semaphore.h>
 #include <msp/core/thread.h>
 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,58 +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<ResourceObserver *> 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<ManagedResource *> 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<resource_load_error> 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<capacity; }
+               UInt64 get_and_reset_loaded_data_size();
 
                void terminate();
        };
 
        typedef std::map<const Resource *, ManagedResource> ResourceMap;
-       typedef std::list<ManagedResource *> LoadQueue;
 
        LoadingPolicy policy;
        bool async_loads;
+       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:
@@ -80,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