CUGL
Cornell University Game Library
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 zlib 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/16
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 
55 
56 namespace cugl {
57 
82 class AssetManager {
83 private:
85  CU_DISALLOW_COPY_AND_ASSIGN(AssetManager);
86 
87 protected:
89  std::unordered_map<size_t,std::shared_ptr<BaseLoader>> _handlers;
91  std::shared_ptr<ThreadPool> _workers;
92 
94  bool _preload;
95 
118  bool readCategory(size_t hash, const std::shared_ptr<JsonValue>& json);
119 
153  void readCategory(size_t hash, const std::shared_ptr<JsonValue>& json,
154  LoaderCallback callback);
155 
156 #pragma mark -
157 #pragma mark Constructors
158 public:
165  AssetManager() : _preload(false) {}
166 
171 
179  void dispose();
180 
193  bool init() {
194  return init(2);
195  }
196 
212  bool init(unsigned int threads);
213 
214 #pragma mark -
215 #pragma mark Static Constructors
216 
228  static std::shared_ptr<AssetManager> alloc() {
229  std::shared_ptr<AssetManager> result = std::make_shared<AssetManager>();
230  return (result->init() ? result : nullptr);
231  }
232 
248  static std::shared_ptr<AssetManager> alloc(unsigned int threads) {
249  std::shared_ptr<AssetManager> result = std::make_shared<AssetManager>();
250  return (result->init(threads) ? result : nullptr);
251  }
252 
253 #pragma mark -
254 #pragma mark Loader Management
255 
267  template<typename T>
268  bool attach(const std::shared_ptr<BaseLoader>& loader) {
269  size_t hash = typeid(T).hash_code();
270  auto it = _handlers.find(hash);
271  if (it != _handlers.end()) {
272  return false;
273  }
274 
275  loader->setThreadPool(_workers);
276  _handlers[hash] = loader;
277  return true;
278  }
279 
287  template<typename T>
288  bool isAttached() {
289  size_t hash = typeid(T).hash_code();
290  return _handlers.find(hash) != _handlers.end();
291  }
292 
302  template<typename T>
303  bool detach() {
304  size_t hash = typeid(T).hash_code();
305  auto it = _handlers.find(hash);
306  if (it == _handlers.end()) {
307  return false;
308  }
309  it->second->setThreadPool(nullptr);
310  it->second = nullptr;
311  _handlers.erase(hash);
312  return true;
313  }
314 
321  void detachAll() {
322  for(auto it = _handlers.begin(); it != _handlers.end(); ++it) {
323  it->second = nullptr;
324  }
325  _handlers.clear();
326  }
327 
335  template<typename T>
336  std::shared_ptr<Loader<T>> access() {
337  size_t hash = typeid(T).hash_code();
338  auto it = _handlers.find(hash);
339  if (it == _handlers.end()) {
340  CUAssertLog(false, "No loader assigned for given type");
341  return nullptr;
342  }
343 
344  return std::dynamic_pointer_cast<Loader<T>>(it->second);
345  }
346 
347 #pragma mark -
348 #pragma mark Progress Monitoring
349 
360  size_t loadCount() const;
361 
374  size_t waitCount() const;
375 
385  bool complete() const { return waitCount() == 0; }
386 
400  float progress() const {
401  size_t size = loadCount()+waitCount();
402  return (size == 0 ? 0.0f : ((float)loadCount())/size);
403  }
404 
405 
406 #pragma mark -
407 #pragma mark Loading/Unloading
408 
419  template<typename T>
420  std::shared_ptr<T> get(const std::string& key) const {
421  size_t hash = typeid(T).hash_code();
422  auto it = _handlers.find(hash);
423  if (it == _handlers.end()) {
424  CUAssertLog(false, "No loader assigned for given type");
425  return nullptr;
426  }
427 
428  std::shared_ptr<Loader<T>> loader = std::dynamic_pointer_cast<Loader<T>>(it->second);
429  return loader->get(key);
430  }
431 
443  template<typename T>
444  std::shared_ptr<T> get(const char* key) const {
445  return get<T>(std::string(key));
446  }
447 
467  template<typename T>
468  bool load(const std::string& key, const std::string& source) {
469  size_t hash = typeid(T).hash_code();
470  auto it = _handlers.find(hash);
471  if (it != _handlers.end()) {
472  std::shared_ptr<Loader<T>> loader = std::dynamic_pointer_cast<Loader<T>>(it->second);
473  return loader->load(key,source);
474  }
475 
476  CUAssertLog(false, "No loader assigned for given type");
477  return nullptr;
478  }
479 
499  template<typename T>
500  bool load(const char* key, const std::string& source) {
501  return load<T>(std::string(key),source);
502  }
503 
523  template<typename T>
524  bool load(const std::string& key, const char* source) {
525  return load<T>(key,std::string(source));
526  }
527 
547  template<typename T>
548  bool load(const char* key, const char* source) {
549  return load<T>(std::string(key),std::string(source));
550  }
551 
576  template<typename T>
577  void loadAsync(const std::string& key, const std::string& source, LoaderCallback callback) {
578  size_t hash = typeid(T).hash_code();
579  auto it = _handlers.find(hash);
580  if (it != _handlers.end()) {
581  it->second->loadAsync(key,source,callback);
582  return;
583  }
584 
585  CUAssertLog(false, "No loader assigned for given type");
586  }
587 
612  template<typename T>
613  void loadAsync(const char* key, const std::string& source, LoaderCallback callback) {
614  loadAsync<T>(std::string(key),source,callback);
615  }
616 
641  template<typename T>
642  void loadAsync(const std::string& key, const char* source, LoaderCallback callback) {
643  loadAsync<T>(key,std::string(source),callback);
644  }
645 
670  template<typename T>
671  void loadAsync(const char* key, const char* source, LoaderCallback callback) {
672  loadAsync<T>(std::string(key),std::string(source),callback);
673  }
674 
689  template<typename T>
690  void unload(const std::string& key) {
691  size_t hash = typeid(T).hash_code();
692  auto it = _handlers.find(hash);
693  if (it != _handlers.end()) {
694  it->second->unload(key);
695  return;
696  }
697 
698  CUAssertLog(false, "No loader assigned for given type");
699  }
700 
715  template<typename T>
716  void unload(const char* key) {
717  unload<T>(std::string(key));
718  }
719 
728  void unloadAll() {
729  for(auto it = _handlers.begin(); it != _handlers.end(); ++it) {
730  it->second->unloadAll();
731  }
732  }
733 
734 #pragma mark -
735 #pragma mark Directory Support
736 
761  bool loadDirectory(const std::shared_ptr<JsonValue>& json);
762 
788  bool loadDirectory(const std::string& directory);
789 
815  bool loadDirectory(const char* directory) {
816  return loadDirectory(std::string(directory));
817  }
818 
851  void loadDirectoryAsync(const std::shared_ptr<JsonValue>& json, LoaderCallback callback);
852 
885  void loadDirectoryAsync(const std::string& directory, LoaderCallback callback);
886 
919  void loadDirectoryAsync(const char* directory, LoaderCallback callback) {
920  loadDirectoryAsync(std::string(directory),callback);
921  }
922 
923 };
924 
925 }
926 
927 #endif /* __CU_ASSET_MANAGER_H__ */
void loadAsync(const std::string &key, const char *source, LoaderCallback callback)
Definition: CUAssetManager.h:642
AssetManager()
Definition: CUAssetManager.h:165
bool init()
Definition: CUAssetManager.h:193
void unload(const char *key)
Definition: CUAssetManager.h:716
~AssetManager()
Definition: CUAssetManager.h:170
void loadDirectoryAsync(const std::shared_ptr< JsonValue > &json, LoaderCallback callback)
bool _preload
Definition: CUAssetManager.h:94
void loadDirectoryAsync(const char *directory, LoaderCallback callback)
Definition: CUAssetManager.h:919
std::function< void(const std::string &key, bool success)> LoaderCallback
Definition: CULoader.h:81
bool detach()
Definition: CUAssetManager.h:303
float progress() const
Definition: CUAssetManager.h:400
bool load(const std::string &key, const std::string &source)
Definition: CUAssetManager.h:468
bool load(const char *key, const std::string &source)
Definition: CUAssetManager.h:500
void loadAsync(const std::string &key, const std::string &source, LoaderCallback callback)
Definition: CUAssetManager.h:577
bool attach(const std::shared_ptr< BaseLoader > &loader)
Definition: CUAssetManager.h:268
static std::shared_ptr< AssetManager > alloc(unsigned int threads)
Definition: CUAssetManager.h:248
bool load(const std::string &key, const char *source)
Definition: CUAssetManager.h:524
void unload(const std::string &key)
Definition: CUAssetManager.h:690
bool complete() const
Definition: CUAssetManager.h:385
void unloadAll()
Definition: CUAssetManager.h:728
bool loadDirectory(const char *directory)
Definition: CUAssetManager.h:815
void loadAsync(const char *key, const char *source, LoaderCallback callback)
Definition: CUAssetManager.h:671
void loadAsync(const char *key, const std::string &source, LoaderCallback callback)
Definition: CUAssetManager.h:613
std::unordered_map< size_t, std::shared_ptr< BaseLoader > > _handlers
Definition: CUAssetManager.h:89
bool load(const std::string &key, const std::string &source)
Definition: CULoader.h:316
bool load(const char *key, const char *source)
Definition: CUAssetManager.h:548
Definition: CULoader.h:675
size_t loadCount() const
bool loadDirectory(const std::shared_ptr< JsonValue > &json)
size_t waitCount() const
bool isAttached()
Definition: CUAssetManager.h:288
Definition: CUAssetManager.h:82
Definition: CUAnimationNode.h:52
std::shared_ptr< ThreadPool > _workers
Definition: CUAssetManager.h:91
std::shared_ptr< Loader< T > > access()
Definition: CUAssetManager.h:336
bool readCategory(size_t hash, const std::shared_ptr< JsonValue > &json)
static std::shared_ptr< AssetManager > alloc()
Definition: CUAssetManager.h:228
void detachAll()
Definition: CUAssetManager.h:321
std::shared_ptr< T > get(const std::string &key) const
Definition: CULoader.h:743