AssetManager.hxx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #ifndef SNAKE_ASSETMANAGER_HXX
  3. #define SNAKE_ASSETMANAGER_HXX
  4. #include "../SDLRenderer.hxx"
  5. #include <atomic>
  6. #include <concepts>
  7. #include <filesystem>
  8. #include <thread>
  9. #include <unordered_map>
  10. #include <SDL_ttf.h>
  11. #include <boost/noncopyable.hpp>
  12. class AssetManager final : private boost::noncopyable {
  13. public:
  14. explicit AssetManager(SDLRenderer& renderer);
  15. ~AssetManager();
  16. static AssetManager& instance() noexcept;
  17. float get_progress() const;
  18. SDL_Texture* get_texture_asset(std::string const& filepath);
  19. TTF_Font* get_font_asset(std::string const& filepath);
  20. private:
  21. void load_assets(std::filesystem::path const& asset_directory);
  22. static AssetManager* instance_;
  23. std::atomic<size_t> assets_loaded_{0u};
  24. std::atomic<size_t> total_assets_{0u};
  25. std::thread loading_thread_;
  26. SDLRenderer& renderer_;
  27. std::unordered_map<std::string, SDL_Surface*> surface_assets_;
  28. std::unordered_map<std::string, SDL_Texture*> texture_assets_;
  29. std::unordered_map<std::string, TTF_Font*> font_assets_;
  30. };
  31. template<typename T>
  32. concept Pointer = std::is_pointer_v<T>;
  33. template<Pointer T>
  34. struct AssetTraits;
  35. template<>
  36. struct AssetTraits<SDL_Texture*> final {
  37. using type = SDL_Texture*;
  38. static type get(std::string const& name)
  39. {
  40. return AssetManager::instance().get_texture_asset(name);
  41. }
  42. };
  43. template<>
  44. struct AssetTraits<TTF_Font*> final {
  45. using type = TTF_Font*;
  46. static type get(std::string const& name)
  47. {
  48. return AssetManager::instance().get_font_asset(name);
  49. }
  50. };
  51. template<typename T>
  52. class Asset final {
  53. using traits = AssetTraits<T>;
  54. public:
  55. explicit Asset(std::string name)
  56. :name_{std::move(name)},
  57. asset_{nullptr}
  58. {
  59. }
  60. Asset(Asset const&) = default;
  61. Asset& operator=(Asset const&) = default;
  62. operator T&() // NOLINT(*-explicit-constructor)
  63. {
  64. evaluate();
  65. return asset_;
  66. }
  67. operator T const&() const // NOLINT(*-explicit-constructor)
  68. {
  69. evaluate();
  70. return asset_;
  71. }
  72. private:
  73. void evaluate() const
  74. {
  75. if (asset_==nullptr) {
  76. asset_ = traits::get(name_);
  77. }
  78. }
  79. std::string name_;
  80. mutable T asset_;
  81. };
  82. #endif // SNAKE_ASSETMANAGER_HXX