CUGL 1.3
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
CUAssetManager.h
1 //
2 // CUAssetManager.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides a class to support asset management. Assets should
6 // always be managed by a central loader. The loader ensures that the assets
7 // are in memory at all times (even when not in use) and that there is a simple
8 // way to refer to them using user-defined keys.
9 //
10 // While most game engines implement asset managers as singletons, we have
11 // elected not to do that. This way you can use a different managers for
12 // different player modes.
13 //
14 // This class uses our standard shared-pointer architecture.
15 //
16 // 1. The constructor does not perform any initialization; it just sets all
17 // attributes to their defaults.
18 //
19 // 2. All initialization takes place via init methods, which can fail if an
20 // object is initialized more than once.
21 //
22 // 3. All allocation takes place via static constructors which return a shared
23 // pointer.
24 //
25 //
26 // CUGL MIT License:
27 // This software is provided 'as-is', without any express or implied
28 // warranty. In no event will the authors be held liable for any damages
29 // arising from the use of this software.
30 //
31 // Permission is granted to anyone to use this software for any purpose,
32 // including commercial applications, and to alter it and redistribute it
33 // freely, subject to the following restrictions:
34 //
35 // 1. The origin of this software must not be misrepresented; you must not
36 // claim that you wrote the original software. If you use this software
37 // in a product, an acknowledgment in the product documentation would be
38 // appreciated but is not required.
39 //
40 // 2. Altered source versions must be plainly marked as such, and must not
41 // be misrepresented as being the original software.
42 //
43 // 3. This notice may not be removed or altered from any source distribution.
44 //
45 // Author: Walker White
46 // Version: 1/7/18
47 //
48 #ifndef __CU_ASSET_MANAGER_H__
49 #define __CU_ASSET_MANAGER_H__
50 #include <cugl/util/CUThreadPool.h>
51 #include <cugl/util/CUDebug.h>
52 #include <cugl/assets/CULoader.h>
53 #include <typeinfo>
54 #include <atomic>
55 
56 
57 namespace cugl {
58 
83 class AssetManager {
84 private:
86  CU_DISALLOW_COPY_AND_ASSIGN(AssetManager);
87 
88 #pragma mark Internal Helpers
89 protected:
91  std::unordered_map<size_t,std::shared_ptr<BaseLoader>> _handlers;
93  std::shared_ptr<ThreadPool> _workers;
94 
96  bool _preload;
97 
99  std::atomic<bool> _wait;
100 
123  bool readCategory(size_t hash, const std::shared_ptr<JsonValue>& json);
124 
158  void readCategory(size_t hash, const std::shared_ptr<JsonValue>& json,
159  LoaderCallback callback);
160 
173  bool purgeCategory(size_t hash, const std::shared_ptr<JsonValue>& json);
174 
183  void sync();
184 
192  void block();
193 
201  void resume();
202 
203 
204 #pragma mark -
205 #pragma mark Constructors
206 public:
213  AssetManager() : _preload(false), _wait(false) {}
214 
219 
227  void dispose();
228 
241  bool init();
242 
243  //
244  // Initializes a new asset manager with the given number of auxiliary threads.
245  //
246  // The asset manager will have a thread pool of the given size, allowing it
247  // load assets asynchronously. These threads have no effect on synchronous
248  // loading and will sleep when no assets are being loaded. If threads is
249  // 0, all assets must be loaded synchronously.
250  //
251  // This initializer does not attach any loaders. It simply creates an
252  // object that is ready to accept loader objects.
253  //
254  // @param threads The number of threads for asynchronous loading
255  //
256  // @return true if the asset manager was initialized successfully
257  //
258  // TODO: This class must be refactored for this to be safe to use.
259  // bool init(unsigned int threads);
260 
261 #pragma mark -
262 #pragma mark Static Constructors
263 
275  static std::shared_ptr<AssetManager> alloc() {
276  std::shared_ptr<AssetManager> result = std::make_shared<AssetManager>();
277  return (result->init() ? result : nullptr);
278  }
279 
280  //
281  // Returns a newly allocated asset manager with the given number of auxiliary threads.
282  //
283  // The asset manager will have a thread pool of the given size, allowing it
284  // load assets asynchronously. These threads have no effect on synchronous
285  // loading and will sleep when no assets are being loaded. If threads is
286  // 0, all assets must be loaded synchronously.
287  //
288  // This constructor does not attach any loaders. It simply creates an
289  // object that is ready to accept loader objects.
290  //
291  // @param threads The number of threads for asynchronous loading
292  //
293  // @return a newly allocated asset manager with the given number of auxiliary threads.
294  //
295  // TODO: This class must be refactored for this to be safe to use.
296  // static std::shared_ptr<AssetManager> alloc(unsigned int threads) {
297  // std::shared_ptr<AssetManager> result = std::make_shared<AssetManager>();
298  // return (result->init(threads) ? result : nullptr);
299  // }
300 
301 #pragma mark -
302 #pragma mark Loader Management
303 
315  template<typename T>
316  bool attach(const std::shared_ptr<BaseLoader>& loader) {
317  size_t hash = typeid(T).hash_code();
318  auto it = _handlers.find(hash);
319  if (it != _handlers.end()) {
320  return false;
321  }
322 
323  loader->setThreadPool(_workers);
324  _handlers[hash] = loader;
325  loader->setManager(this);
326  return true;
327  }
328 
336  template<typename T>
337  bool isAttached() {
338  size_t hash = typeid(T).hash_code();
339  return _handlers.find(hash) != _handlers.end();
340  }
341 
351  template<typename T>
352  bool detach() {
353  size_t hash = typeid(T).hash_code();
354  auto it = _handlers.find(hash);
355  if (it == _handlers.end()) {
356  return false;
357  }
358  it->second->setThreadPool(nullptr);
359  it->second = nullptr;
360  _handlers.erase(hash);
361  return true;
362  }
363 
370  void detachAll() {
371  for(auto it = _handlers.begin(); it != _handlers.end(); ++it) {
372  it->second = nullptr;
373  }
374  _handlers.clear();
375  }
376 
384  template<typename T>
385  std::shared_ptr<Loader<T>> access() const {
386  size_t hash = typeid(T).hash_code();
387  auto it = _handlers.find(hash);
388  if (it == _handlers.end()) {
389  CUAssertLog(false, "No loader assigned for given type");
390  return nullptr;
391  }
392 
393  return std::dynamic_pointer_cast<Loader<T>>(it->second);
394  }
395 
396 #pragma mark -
397 #pragma mark Progress Monitoring
398 
409  size_t loadCount() const;
410 
423  size_t waitCount() const;
424 
434  bool complete() const { return waitCount() == 0; }
435 
449  float progress() const {
450  size_t size = loadCount()+waitCount();
451  return (size == 0 ? 0.0f : ((float)loadCount())/size);
452  }
453 
454 
455 #pragma mark -
456 #pragma mark Loading/Unloading
457 
468  template<typename T>
469  std::shared_ptr<T> get(const std::string& key) const {
470  size_t hash = typeid(T).hash_code();
471  auto it = _handlers.find(hash);
472  if (it == _handlers.end()) {
473  CUAssertLog(false, "No loader assigned for given type");
474  return nullptr;
475  }
476 
477  std::shared_ptr<Loader<T>> loader = std::dynamic_pointer_cast<Loader<T>>(it->second);
478  return loader->get(key);
479  }
480 
492  template<typename T>
493  std::shared_ptr<T> get(const char* key) const {
494  return get<T>(std::string(key));
495  }
496 
516  template<typename T>
517  bool load(const std::string& key, const std::string& source) {
518  size_t hash = typeid(T).hash_code();
519  auto it = _handlers.find(hash);
520  if (it != _handlers.end()) {
521  std::shared_ptr<Loader<T>> loader = std::dynamic_pointer_cast<Loader<T>>(it->second);
522  return loader->load(key,source);
523  }
524 
525  CUAssertLog(false, "No loader assigned for given type");
526  return nullptr;
527  }
528 
548  template<typename T>
549  bool load(const char* key, const std::string& source) {
550  return load<T>(std::string(key),source);
551  }
552 
572  template<typename T>
573  bool load(const std::string& key, const char* source) {
574  return load<T>(key,std::string(source));
575  }
576 
596  template<typename T>
597  bool load(const char* key, const char* source) {
598  return load<T>(std::string(key),std::string(source));
599  }
600 
625  template<typename T>
626  void loadAsync(const std::string& key, const std::string& source, LoaderCallback callback) {
627  size_t hash = typeid(T).hash_code();
628  auto it = _handlers.find(hash);
629  if (it != _handlers.end()) {
630  it->second->loadAsync(key,source,callback);
631  return;
632  }
633 
634  CUAssertLog(false, "No loader assigned for given type");
635  }
636 
661  template<typename T>
662  void loadAsync(const char* key, const std::string& source, LoaderCallback callback) {
663  loadAsync<T>(std::string(key),source,callback);
664  }
665 
690  template<typename T>
691  void loadAsync(const std::string& key, const char* source, LoaderCallback callback) {
692  loadAsync<T>(key,std::string(source),callback);
693  }
694 
719  template<typename T>
720  void loadAsync(const char* key, const char* source, LoaderCallback callback) {
721  loadAsync<T>(std::string(key),std::string(source),callback);
722  }
723 
738  template<typename T>
739  void unload(const std::string& key) {
740  size_t hash = typeid(T).hash_code();
741  auto it = _handlers.find(hash);
742  if (it != _handlers.end()) {
743  it->second->unload(key);
744  return;
745  }
746 
747  CUAssertLog(false, "No loader assigned for given type");
748  }
749 
764  template<typename T>
765  void unload(const char* key) {
766  unload<T>(std::string(key));
767  }
768 
777  void unloadAll() {
778  for(auto it = _handlers.begin(); it != _handlers.end(); ++it) {
779  it->second->unloadAll();
780  }
781  }
782 
783 #pragma mark -
784 #pragma mark Directory Support
785 
810  bool loadDirectory(const std::shared_ptr<JsonValue>& json);
811 
837  bool loadDirectory(const std::string& directory);
838 
864  bool loadDirectory(const char* directory) {
865  return loadDirectory(std::string(directory));
866  }
867 
900  void loadDirectoryAsync(const std::shared_ptr<JsonValue>& json, LoaderCallback callback);
901 
934  void loadDirectoryAsync(const std::string& directory, LoaderCallback callback);
935 
968  void loadDirectoryAsync(const char* directory, LoaderCallback callback) {
969  loadDirectoryAsync(std::string(directory),callback);
970  }
971 
982  bool unloadDirectory(const std::shared_ptr<JsonValue>& json);
983 
994  bool unloadDirectory(const std::string& directory);
995 
1006  bool unloadDirectory(const char* directory) {
1007  return unloadDirectory(std::string(directory));
1008  }
1009 
1010 };
1011 
1012 }
1013 
1014 #endif /* __CU_ASSET_MANAGER_H__ */
cugl::AssetManager::access
std::shared_ptr< Loader< T > > access() const
Definition: CUAssetManager.h:385
cugl::AssetManager::loadDirectoryAsync
void loadDirectoryAsync(const char *directory, LoaderCallback callback)
Definition: CUAssetManager.h:968
cugl::AssetManager::alloc
static std::shared_ptr< AssetManager > alloc()
Definition: CUAssetManager.h:275
cugl::AssetManager::get
std::shared_ptr< T > get(const std::string &key) const
Definition: CUAssetManager.h:469
cugl::AssetManager::unloadDirectory
bool unloadDirectory(const char *directory)
Definition: CUAssetManager.h:1006
cugl::Loader
Definition: CULoader.h:749
cugl::AssetManager::AssetManager
AssetManager()
Definition: CUAssetManager.h:213
cugl::AssetManager::load
bool load(const char *key, const std::string &source)
Definition: CUAssetManager.h:549
cugl::AssetManager::loadAsync
void loadAsync(const std::string &key, const std::string &source, LoaderCallback callback)
Definition: CUAssetManager.h:626
cugl::AssetManager::unloadDirectory
bool unloadDirectory(const std::shared_ptr< JsonValue > &json)
cugl::AssetManager::_handlers
std::unordered_map< size_t, std::shared_ptr< BaseLoader > > _handlers
Definition: CUAssetManager.h:91
cugl::AssetManager::loadDirectoryAsync
void loadDirectoryAsync(const std::shared_ptr< JsonValue > &json, LoaderCallback callback)
cugl::AssetManager::get
std::shared_ptr< T > get(const char *key) const
Definition: CUAssetManager.h:493
cugl::AssetManager::unload
void unload(const std::string &key)
Definition: CUAssetManager.h:739
cugl::AssetManager::load
bool load(const std::string &key, const char *source)
Definition: CUAssetManager.h:573
cugl::Loader::get
std::shared_ptr< T > get(const std::string &key) const
Definition: CULoader.h:817
cugl::AssetManager::resume
void resume()
cugl::AssetManager::detach
bool detach()
Definition: CUAssetManager.h:352
cugl::AssetManager::complete
bool complete() const
Definition: CUAssetManager.h:434
cugl::AssetManager::load
bool load(const char *key, const char *source)
Definition: CUAssetManager.h:597
cugl::AssetManager::loadDirectory
bool loadDirectory(const std::shared_ptr< JsonValue > &json)
cugl::BaseLoader::load
bool load(const std::string &key, const std::string &source)
Definition: CULoader.h:370
cugl::AssetManager::loadAsync
void loadAsync(const std::string &key, const char *source, LoaderCallback callback)
Definition: CUAssetManager.h:691
cugl::AssetManager::loadDirectory
bool loadDirectory(const char *directory)
Definition: CUAssetManager.h:864
cugl::AssetManager::_wait
std::atomic< bool > _wait
Definition: CUAssetManager.h:99
cugl::AssetManager::~AssetManager
~AssetManager()
Definition: CUAssetManager.h:218
cugl::AssetManager::load
bool load(const std::string &key, const std::string &source)
Definition: CUAssetManager.h:517
cugl::AssetManager::purgeCategory
bool purgeCategory(size_t hash, const std::shared_ptr< JsonValue > &json)
cugl::AssetManager::readCategory
bool readCategory(size_t hash, const std::shared_ptr< JsonValue > &json)
cugl::AssetManager::loadAsync
void loadAsync(const char *key, const std::string &source, LoaderCallback callback)
Definition: CUAssetManager.h:662
cugl::AssetManager::isAttached
bool isAttached()
Definition: CUAssetManager.h:337
cugl::AssetManager::waitCount
size_t waitCount() const
cugl::AssetManager::dispose
void dispose()
cugl::AssetManager::loadCount
size_t loadCount() const
cugl::AssetManager::attach
bool attach(const std::shared_ptr< BaseLoader > &loader)
Definition: CUAssetManager.h:316
cugl::AssetManager::_workers
std::shared_ptr< ThreadPool > _workers
Definition: CUAssetManager.h:93
cugl::AssetManager::_preload
bool _preload
Definition: CUAssetManager.h:96
cugl::AssetManager::sync
void sync()
cugl::AssetManager::unload
void unload(const char *key)
Definition: CUAssetManager.h:765
cugl::AssetManager
Definition: CUAssetManager.h:83
cugl::AssetManager::init
bool init()
cugl::AssetManager::block
void block()
cugl::AssetManager::progress
float progress() const
Definition: CUAssetManager.h:449
cugl::AssetManager::unloadAll
void unloadAll()
Definition: CUAssetManager.h:777
cugl::AssetManager::loadAsync
void loadAsync(const char *key, const char *source, LoaderCallback callback)
Definition: CUAssetManager.h:720
cugl::AssetManager::detachAll
void detachAll()
Definition: CUAssetManager.h:370