AssetManager.cxx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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: image_assets_) {
  32. SDL_FreeSurface(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. auto const filename = entry.path().filename().string();
  47. if (ext==".png" || ext==".jpg") {
  48. auto const surface = IMG_Load(path.c_str());
  49. if (surface==nullptr) {
  50. throw SDLError{std::format("Failed to load texture {}.", path)};
  51. }
  52. image_assets_[filename] = surface;
  53. SDL_Log("Loaded texture %s successfully.", filename.c_str());
  54. }
  55. else if (ext==".ttf") {
  56. auto const font = TTF_OpenFont(path.c_str(), 16);
  57. if (font==nullptr) {
  58. throw SDLError{std::format("Failed to load font {}.", path)};
  59. }
  60. font_assets_[filename] = font;
  61. SDL_Log("Loaded font %s successfully.", filename.c_str());
  62. }
  63. ++assets_loaded_;
  64. }
  65. }
  66. float AssetManager::get_progress() const
  67. {
  68. return static_cast<float>(assets_loaded_)/static_cast<float>(total_assets_);
  69. }
  70. SDL_Surface* AssetManager::get_image_asset(std::string const& filepath)
  71. {
  72. return image_assets_[filepath];
  73. }
  74. TTF_Font* AssetManager::get_font_asset(std::string const& filepath)
  75. {
  76. return font_assets_[filepath];
  77. }
  78. AssetManager& AssetManager::instance() noexcept
  79. {
  80. assert(instance_!=nullptr);
  81. return *instance_;
  82. }