AssetManager.cxx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "AssetManager.hxx"
  2. #include <cassert>
  3. #include <filesystem>
  4. #include <format>
  5. #include <SDL_image.h>
  6. AssetManager* AssetManager::instance_ = nullptr;
  7. AssetManager::AssetManager(SDLRenderer& renderer)
  8. :renderer_{renderer}
  9. {
  10. namespace fs = std::filesystem;
  11. assert(instance_==nullptr);
  12. auto current_path = fs::current_path();
  13. auto const asset_directory =
  14. fs::exists(current_path/"assets") ? current_path/"assets" :
  15. fs::exists(current_path.parent_path()/"assets") ? current_path.parent_path()/"assets" :
  16. fs::path{};
  17. if (asset_directory.empty()) {
  18. throw std::runtime_error("Assets directory not found.");
  19. }
  20. total_assets_ = std::distance(fs::directory_iterator(asset_directory),
  21. fs::directory_iterator());
  22. loading_thread_ = std::thread{&AssetManager::load_assets, this, asset_directory};
  23. instance_ = this;
  24. }
  25. AssetManager::~AssetManager()
  26. {
  27. assert(instance_!=nullptr);
  28. if (loading_thread_.joinable()) {
  29. loading_thread_.join();
  30. }
  31. for (auto& kv: texture_assets_) {
  32. SDL_DestroyTexture(kv.second);
  33. SDL_Log("Unloaded texture %s successfully.", kv.first.c_str());
  34. }
  35. for (auto& kv: font_assets_) {
  36. TTF_CloseFont(kv.second);
  37. SDL_Log("Unloaded font %s successfully.", kv.first.c_str());
  38. }
  39. instance_ = nullptr;
  40. }
  41. void AssetManager::load_assets(std::filesystem::path const& asset_directory)
  42. {
  43. for (auto const& entry: std::filesystem::directory_iterator(asset_directory)) {
  44. auto const path = entry.path().string();
  45. auto const ext = entry.path().extension();
  46. if (ext==".png" || ext==".jpg") {
  47. SDL_Surface* temp_surface = IMG_Load(path.c_str());
  48. auto const texture = SDL_CreateTextureFromSurface(renderer_, temp_surface);
  49. SDL_FreeSurface(temp_surface);
  50. if (texture==nullptr) {
  51. throw SDLError{std::format("Failed to load texture {}.", path)};
  52. }
  53. texture_assets_[path] = texture;
  54. SDL_Log("Loaded texture %s successfully.", path.c_str());
  55. }
  56. else if (ext==".ttf") {
  57. auto const font = TTF_OpenFont(path.c_str(), 16);
  58. if (font==nullptr) {
  59. throw SDLError{std::format("Failed to load font {}.", path)};
  60. }
  61. font_assets_[path] = font;
  62. SDL_Log("Loaded font %s successfully.", path.c_str());
  63. }
  64. ++assets_loaded_;
  65. }
  66. }
  67. float AssetManager::get_progress() const
  68. {
  69. return static_cast<float>(assets_loaded_)/static_cast<float>(total_assets_);
  70. }
  71. SDL_Texture* AssetManager::get_texture_asset(std::string const& filepath)
  72. {
  73. return texture_assets_[filepath];
  74. }
  75. TTF_Font* AssetManager::get_font_asset(std::string const& filepath)
  76. {
  77. return font_assets_[filepath];
  78. }
  79. AssetManager& AssetManager::instance() noexcept
  80. {
  81. assert(instance_!=nullptr);
  82. return *instance_;
  83. }