AssetManager.hxx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. SDL_Surface* get_surface_asset(std::string const& filepath);
  20. TTF_Font* get_font_asset(std::string const& filepath);
  21. private:
  22. void load_assets(std::filesystem::path const& asset_directory);
  23. static AssetManager* instance_;
  24. std::atomic<size_t> assets_loaded_{0u};
  25. std::atomic<size_t> total_assets_{0u};
  26. std::thread loading_thread_;
  27. SDLRenderer& renderer_;
  28. std::unordered_map<std::string, SDL_Surface*> surface_assets_;
  29. std::unordered_map<std::string, SDL_Texture*> texture_assets_;
  30. std::unordered_map<std::string, TTF_Font*> font_assets_;
  31. };
  32. template<typename T>
  33. concept Pointer = std::is_pointer_v<T>;
  34. template<Pointer T>
  35. struct AssetTraits;
  36. template<>
  37. struct AssetTraits<SDL_Texture*> final {
  38. using type = SDL_Texture*;
  39. static type get(std::string const& name)
  40. {
  41. return AssetManager::instance().get_texture_asset(name);
  42. }
  43. };
  44. template<>
  45. struct AssetTraits<TTF_Font*> final {
  46. using type = TTF_Font*;
  47. static type get(std::string const& name)
  48. {
  49. return AssetManager::instance().get_font_asset(name);
  50. }
  51. };
  52. template<typename T>
  53. class Asset final {
  54. using traits = AssetTraits<T>;
  55. public:
  56. explicit Asset(std::string name)
  57. :name_{std::move(name)},
  58. asset_{nullptr}
  59. {
  60. }
  61. Asset(Asset const&) = default;
  62. Asset& operator=(Asset const&) = default;
  63. operator T&() // NOLINT(*-explicit-constructor)
  64. {
  65. evaluate();
  66. return asset_;
  67. }
  68. operator T const&() const // NOLINT(*-explicit-constructor)
  69. {
  70. evaluate();
  71. return asset_;
  72. }
  73. private:
  74. void evaluate() const
  75. {
  76. if (asset_==nullptr) {
  77. asset_ = traits::get(name_);
  78. }
  79. }
  80. std::string name_;
  81. mutable T asset_;
  82. };
  83. #endif // SNAKE_ASSETMANAGER_HXX