resource_manager.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "resource_manager.h"
  6. #include "resource_registry.h"
  7. #include "temp_allocator.h"
  8. #include "sort_map.h"
  9. #include "array.h"
  10. namespace crown
  11. {
  12. const ResourceManager::ResourceEntry ResourceManager::ResourceEntry::NOT_FOUND = { 0xffffffffu, NULL };
  13. ResourceManager::ResourceManager(Filesystem& fs)
  14. : _resource_heap("resource", default_allocator())
  15. , _loader(fs, _resource_heap)
  16. , _rm(default_allocator())
  17. , _autoload(false)
  18. {
  19. }
  20. ResourceManager::~ResourceManager()
  21. {
  22. const ResourceMap::Entry* begin = sort_map::begin(_rm);
  23. const ResourceMap::Entry* end = sort_map::end(_rm);
  24. for (; begin != end; begin++)
  25. {
  26. resource_on_offline(begin->key.type, begin->key.name, *this);
  27. resource_on_unload(begin->key.type, _resource_heap, begin->value.data);
  28. }
  29. }
  30. void ResourceManager::load(StringId64 type, StringId64 name)
  31. {
  32. ResourcePair id = make_pair(type, name);
  33. ResourceEntry& entry = sort_map::get(_rm, id, ResourceEntry::NOT_FOUND);
  34. if (entry == ResourceEntry::NOT_FOUND)
  35. {
  36. _loader.load(type, name);
  37. return;
  38. }
  39. entry.references++;
  40. }
  41. void ResourceManager::unload(StringId64 type, StringId64 name)
  42. {
  43. flush();
  44. ResourcePair id = make_pair(type, name);
  45. ResourceEntry& entry = sort_map::get(_rm, id, ResourceEntry::NOT_FOUND);
  46. if (--entry.references == 0)
  47. {
  48. resource_on_offline(type, name, *this);
  49. resource_on_unload(type, _resource_heap, entry.data);
  50. sort_map::remove(_rm, id);
  51. sort_map::sort(_rm);
  52. }
  53. }
  54. void ResourceManager::reload(StringId64 type, StringId64 name)
  55. {
  56. const ResourcePair id = make_pair(type, name);
  57. const ResourceEntry& entry = sort_map::get(_rm, id, ResourceEntry::NOT_FOUND);
  58. const uint32_t old_refs = entry.references;
  59. unload(type, name);
  60. load(type, name);
  61. flush();
  62. ResourceEntry& new_entry = sort_map::get(_rm, id, ResourceEntry::NOT_FOUND);
  63. new_entry.references = old_refs;
  64. }
  65. bool ResourceManager::can_get(StringId64 type, StringId64 name)
  66. {
  67. return _autoload ? true : sort_map::has(_rm, make_pair(type, name));
  68. }
  69. const void* ResourceManager::get(StringId64 type, StringId64 name)
  70. {
  71. const ResourcePair id = make_pair(type, name);
  72. char type_buf[StringId64::STRING_LENGTH];
  73. char name_buf[StringId64::STRING_LENGTH];
  74. CE_ASSERT(can_get(type, name), "Resource not loaded #ID(%s-%s)", type.to_string(type_buf), name.to_string(name_buf));
  75. CE_UNUSED(type_buf);
  76. CE_UNUSED(name_buf);
  77. if (_autoload && !sort_map::has(_rm, id))
  78. {
  79. load(type, name);
  80. flush();
  81. }
  82. const ResourceEntry& entry = sort_map::get(_rm, id, ResourceEntry::NOT_FOUND);
  83. return entry.data;
  84. }
  85. void ResourceManager::enable_autoload(bool enable)
  86. {
  87. _autoload = enable;
  88. }
  89. void ResourceManager::flush()
  90. {
  91. _loader.flush();
  92. complete_requests();
  93. }
  94. void ResourceManager::complete_requests()
  95. {
  96. TempAllocator1024 ta;
  97. Array<ResourceData> loaded(ta);
  98. _loader.get_loaded(loaded);
  99. for (uint32_t i = 0; i < array::size(loaded); i++)
  100. complete_request(loaded[i].type, loaded[i].name, loaded[i].data);
  101. }
  102. void ResourceManager::complete_request(StringId64 type, StringId64 name, void* data)
  103. {
  104. ResourceEntry entry;
  105. entry.references = 1;
  106. entry.data = data;
  107. sort_map::set(_rm, make_pair(type, name), entry);
  108. sort_map::sort(_rm);
  109. resource_on_online(type, name, *this);
  110. }
  111. } // namespace crown