AssetManager.hxx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #ifndef SNAKE_ASSETMANAGER_HXX
  3. #define SNAKE_ASSETMANAGER_HXX
  4. #include "../SDLRenderer.hxx"
  5. #include <atomic>
  6. #include <filesystem>
  7. #include <optional>
  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. struct AssetTraits;
  33. template<>
  34. struct AssetTraits<SDL_Texture*> final {
  35. using type = SDL_Texture*;
  36. static type get(std::string const& name)
  37. {
  38. return AssetManager::instance().get_texture_asset(name);
  39. }
  40. };
  41. template<>
  42. struct AssetTraits<TTF_Font*> final {
  43. using type = TTF_Font*;
  44. static type get(std::string const& name)
  45. {
  46. return AssetManager::instance().get_font_asset(name);
  47. }
  48. };
  49. template<typename T>
  50. class Asset final {
  51. using traits = AssetTraits<T>;
  52. public:
  53. explicit Asset(std::string name)
  54. :name_{std::move(name)}
  55. {
  56. }
  57. Asset(Asset const&) = default;
  58. Asset& operator=(Asset const&) = default;
  59. operator T& () { // NOLINT(*-explicit-constructor)
  60. evaluate();
  61. return asset_.value();
  62. }
  63. operator T const& () const { // NOLINT(*-explicit-constructor)
  64. evaluate();
  65. return asset_.value();
  66. }
  67. private:
  68. void evaluate() const
  69. {
  70. if (!asset_.has_value()) {
  71. asset_ = traits::get(name_);
  72. }
  73. }
  74. std::string name_;
  75. mutable std::optional<T> asset_;
  76. };
  77. #endif // SNAKE_ASSETMANAGER_HXX