resource_loader.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2012-2017 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "config.h"
  6. #include "dynamic_string.h"
  7. #include "filesystem.h"
  8. #include "memory.h"
  9. #include "os.h"
  10. #include "path.h"
  11. #include "queue.h"
  12. #include "resource_loader.h"
  13. #include "temp_allocator.h"
  14. namespace crown
  15. {
  16. ResourceLoader::ResourceLoader(Filesystem& data_filesystem)
  17. : _data_filesystem(data_filesystem)
  18. , _requests(default_allocator())
  19. , _loaded(default_allocator())
  20. , _exit(false)
  21. {
  22. _thread.start(ResourceLoader::thread_proc, this);
  23. }
  24. ResourceLoader::~ResourceLoader()
  25. {
  26. _exit = true;
  27. _thread.stop();
  28. }
  29. bool ResourceLoader::can_load(StringId64 type, StringId64 name)
  30. {
  31. TempAllocator128 ta;
  32. DynamicString type_str(ta);
  33. DynamicString name_str(ta);
  34. type.to_string(type_str);
  35. name.to_string(name_str);
  36. DynamicString res_path(ta);
  37. res_path += type_str;
  38. res_path += '-';
  39. res_path += name_str;
  40. DynamicString path(ta);
  41. path::join(path, CROWN_DATA_DIRECTORY, res_path.c_str());
  42. return _data_filesystem.exists(path.c_str());
  43. }
  44. void ResourceLoader::add_request(const ResourceRequest& rr)
  45. {
  46. ScopedMutex sm(_mutex);
  47. queue::push_back(_requests, rr);
  48. }
  49. void ResourceLoader::flush()
  50. {
  51. while (num_requests()) {}
  52. }
  53. u32 ResourceLoader::num_requests()
  54. {
  55. ScopedMutex sm(_mutex);
  56. return queue::size(_requests);
  57. }
  58. void ResourceLoader::add_loaded(ResourceRequest rr)
  59. {
  60. ScopedMutex sm(_loaded_mutex);
  61. queue::push_back(_loaded, rr);
  62. }
  63. void ResourceLoader::get_loaded(Array<ResourceRequest>& loaded)
  64. {
  65. ScopedMutex sm(_loaded_mutex);
  66. const u32 num = queue::size(_loaded);
  67. array::reserve(loaded, num);
  68. for (u32 i = 0; i < num; ++i)
  69. {
  70. array::push_back(loaded, queue::front(_loaded));
  71. queue::pop_front(_loaded);
  72. }
  73. }
  74. s32 ResourceLoader::run()
  75. {
  76. while (!_exit)
  77. {
  78. _mutex.lock();
  79. if (queue::empty(_requests))
  80. {
  81. _mutex.unlock();
  82. os::sleep(16);
  83. continue;
  84. }
  85. ResourceRequest rr = queue::front(_requests);
  86. _mutex.unlock();
  87. TempAllocator128 ta;
  88. DynamicString type_str(ta);
  89. DynamicString name_str(ta);
  90. rr.type.to_string(type_str);
  91. rr.name.to_string(name_str);
  92. DynamicString res_path(ta);
  93. res_path += type_str;
  94. res_path += '-';
  95. res_path += name_str;
  96. DynamicString path(ta);
  97. path::join(path, CROWN_DATA_DIRECTORY, res_path.c_str());
  98. File* file = _data_filesystem.open(path.c_str(), FileOpenMode::READ);
  99. rr.data = rr.load_function(*file, *rr.allocator);
  100. _data_filesystem.close(*file);
  101. add_loaded(rr);
  102. _mutex.lock();
  103. queue::pop_front(_requests);
  104. _mutex.unlock();
  105. }
  106. return 0;
  107. }
  108. s32 ResourceLoader::thread_proc(void* thiz)
  109. {
  110. return ((ResourceLoader*)thiz)->run();
  111. }
  112. } // namespace crown