Selaa lähdekoodia

:recycle: moved surface -> texture back into asset manager

Felix Bytow 1 vuosi sitten
vanhempi
sitoutus
71a43d82f0
5 muutettua tiedostoa jossa 74 lisäystä ja 52 poistoa
  1. 4 0
      .idea/codeStyles/Project.xml
  2. 49 20
      game/AssetManager.cxx
  3. 3 2
      game/AssetManager.hxx
  4. 14 25
      game/SplashState.cxx
  5. 4 5
      game/SplashState.hxx

+ 4 - 0
.idea/codeStyles/Project.xml

@@ -41,6 +41,10 @@
       <option name="TAG_PREFIX_OF_LINE_COMMENT" value="AT" />
       <option name="TYPE_QUALIFIERS_PLACEMENT" value="AFTER" />
     </Objective-C-extensions>
+    <RiderCodeStyleSettings>
+      <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="2" type="long" />
+      <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="2" type="long" />
+    </RiderCodeStyleSettings>
     <files>
       <extensions>
         <pair source="cpp" header="hpp" fileNamingConvention="NONE" />

+ 49 - 20
game/AssetManager.cxx

@@ -9,23 +9,26 @@
 AssetManager* AssetManager::instance_ = nullptr;
 
 AssetManager::AssetManager(SDLRenderer& renderer)
-    :renderer_{renderer}
+  : renderer_{renderer}
 {
   namespace fs = std::filesystem;
 
   assert(instance_==nullptr);
 
-  auto current_path = fs::current_path();
+  auto const current_path = fs::current_path();
   auto const asset_directory =
-      fs::exists(current_path/"assets") ? current_path/"assets" :
-      fs::exists(current_path.parent_path()/"assets") ? current_path.parent_path()/"assets" :
-      fs::path{};
-  if (asset_directory.empty()) {
+    fs::exists(current_path / "assets")
+      ? current_path / "assets"
+      : fs::exists(current_path.parent_path() / "assets")
+      ? current_path.parent_path() / "assets"
+      : fs::path{};
+  if (asset_directory.empty())
+  {
     throw std::runtime_error("Assets directory not found.");
   }
 
   total_assets_ = std::distance(fs::directory_iterator(asset_directory),
-      fs::directory_iterator());
+                                fs::directory_iterator());
 
   loading_thread_ = std::thread{&AssetManager::load_assets, this, asset_directory};
   instance_ = this;
@@ -34,14 +37,21 @@ AssetManager::AssetManager(SDLRenderer& renderer)
 AssetManager::~AssetManager()
 {
   assert(instance_!=nullptr);
-  if (loading_thread_.joinable()) {
+  if (loading_thread_.joinable())
+  {
     loading_thread_.join();
   }
-  for (auto& kv: image_assets_) {
+  for (auto const& kv : surface_assets_)
+  {
     SDL_FreeSurface(kv.second);
+  }
+  for (auto const& kv : texture_assets_)
+  {
+    SDL_DestroyTexture(kv.second);
     SDL_Log("Unloaded texture %s successfully.", kv.first.c_str());
   }
-  for (auto& kv: font_assets_) {
+  for (auto const& kv : font_assets_)
+  {
     TTF_CloseFont(kv.second);
     SDL_Log("Unloaded font %s successfully.", kv.first.c_str());
   }
@@ -50,21 +60,26 @@ AssetManager::~AssetManager()
 
 void AssetManager::load_assets(std::filesystem::path const& asset_directory)
 {
-  for (auto const& entry: std::filesystem::directory_iterator(asset_directory)) {
+  for (auto const& entry : std::filesystem::directory_iterator(asset_directory))
+  {
     auto const path = entry.path().string();
     auto const ext = entry.path().extension();
     auto const filename = entry.path().filename().string();
-    if (ext==".png" || ext==".jpg") {
+    if (ext == ".png" || ext == ".jpg")
+    {
       auto const surface = IMG_Load(path.c_str());
-      if (surface==nullptr) {
+      if (surface == nullptr)
+      {
         throw SDLError{std::format("Failed to load texture {}.", path)};
       }
-      image_assets_[filename] = surface;
+      surface_assets_[filename] = surface;
       SDL_Log("Loaded texture %s successfully.", filename.c_str());
     }
-    else if (ext==".ttf") {
+    else if (ext == ".ttf")
+    {
       auto const font = TTF_OpenFont(path.c_str(), 16);
-      if (font==nullptr) {
+      if (font == nullptr)
+      {
         throw SDLError{std::format("Failed to load font {}.", path)};
       }
       font_assets_[filename] = font;
@@ -76,12 +91,26 @@ void AssetManager::load_assets(std::filesystem::path const& asset_directory)
 
 float AssetManager::get_progress() const
 {
-  return static_cast<float>(assets_loaded_)/static_cast<float>(total_assets_);
+  return static_cast<float>(assets_loaded_) / static_cast<float>(total_assets_);
 }
 
-SDL_Surface* AssetManager::get_image_asset(std::string const& filepath)
+SDL_Texture* AssetManager::get_texture_asset(std::string const& filepath)
 {
-  return image_assets_[filepath];
+  auto const it = texture_assets_.find(filepath);
+  if (it == std::end(texture_assets_))
+  {
+    auto const surf_it = surface_assets_.find(filepath);
+    if (surf_it == std::end(surface_assets_))
+      return nullptr;
+
+    auto const texture = SDL_CreateTextureFromSurface(renderer_, surf_it->second);
+    texture_assets_[filepath] = texture;
+    SDL_FreeSurface(surf_it->second);
+    surface_assets_.erase(surf_it);
+
+    return texture;
+  }
+  return it->second;
 }
 
 TTF_Font* AssetManager::get_font_asset(std::string const& filepath)
@@ -93,4 +122,4 @@ AssetManager& AssetManager::instance() noexcept
 {
   assert(instance_!=nullptr);
   return *instance_;
-}
+}

+ 3 - 2
game/AssetManager.hxx

@@ -27,7 +27,7 @@ public:
 
   float get_progress() const;
 
-  SDL_Surface* get_image_asset(std::string const& filepath);
+  SDL_Texture* get_texture_asset(std::string const& filepath);
 
   TTF_Font* get_font_asset(std::string const& filepath);
 
@@ -42,7 +42,8 @@ private:
 
   SDLRenderer& renderer_;
 
-  std::unordered_map<std::string, SDL_Surface*> image_assets_;
+  std::unordered_map<std::string, SDL_Surface*> surface_assets_;
+  std::unordered_map<std::string, SDL_Texture*> texture_assets_;
   std::unordered_map<std::string, TTF_Font*> font_assets_;
 };
 

+ 14 - 25
game/SplashState.cxx

@@ -6,41 +6,35 @@ using namespace std::chrono_literals;
 
 void SplashState::update(GameStateManager& gsm, std::chrono::milliseconds delta_time)
 {
-    time_in_state_ += delta_time;
-    auto const key_state = SDL_GetKeyboardState(nullptr);
-    if (time_in_state_>13'000ms || key_state[SDL_SCANCODE_SPACE] || key_state[SDL_SCANCODE_RETURN])
-      gsm.replace_state(GameStates::MainMenu);
+  time_in_state_ += delta_time;
+  auto const key_state = SDL_GetKeyboardState(nullptr);
+  if (time_in_state_ > 13'000ms || key_state[SDL_SCANCODE_SPACE] || key_state[SDL_SCANCODE_RETURN])
+    gsm.replace_state(GameStates::MainMenu);
 }
 
 void SplashState::render(SDLRenderer& renderer)
 {
-  if (logo_==nullptr) {
-    // right now this is required here as we need the renderer and the main thread
-    logo_ = SDL_CreateTextureFromSurface(
-        renderer,
-        AssetManager::instance().get_image_asset("logo.jpg")
-    );
-    SDL_SetTextureBlendMode(logo_, SDL_BLENDMODE_BLEND);
-  }
-
   SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
   SDL_RenderClear(renderer);
 
   int w, h;
   SDL_GetRendererOutputSize(renderer, &w, &h);
 
-  if (time_in_state_>=2'000ms && time_in_state_<4'000ms) {
-    auto const progress = static_cast<float>(time_in_state_.count()-2'000)/2'000.0f;
+  if (time_in_state_ >= 2'000ms && time_in_state_ < 4'000ms)
+  {
+    auto const progress = static_cast<float>(time_in_state_.count() - 2'000) / 2'000.0f;
     auto const alpha = static_cast<int>(std::lerp(SDL_ALPHA_TRANSPARENT, SDL_ALPHA_OPAQUE, progress));
     SDL_SetTextureAlphaMod(logo_, alpha);
     SDL_RenderCopy(renderer, logo_, nullptr, nullptr);
   }
-  else if (time_in_state_>=4'000ms && time_in_state_<9'000ms) {
+  else if (time_in_state_ >= 4'000ms && time_in_state_ < 9'000ms)
+  {
     SDL_SetTextureAlphaMod(logo_, SDL_ALPHA_OPAQUE);
     SDL_RenderCopy(renderer, logo_, nullptr, nullptr);
   }
-  else if (time_in_state_>=9'000ms && time_in_state_<11'000ms) {
-    auto const progress = static_cast<float>(time_in_state_.count()-11'000)/2'000.0f;
+  else if (time_in_state_ >= 9'000ms && time_in_state_ < 11'000ms)
+  {
+    auto const progress = static_cast<float>(time_in_state_.count() - 11'000) / 2'000.0f;
     auto const alpha = static_cast<int>(std::lerp(SDL_ALPHA_OPAQUE, SDL_ALPHA_TRANSPARENT, progress));
     SDL_SetTextureAlphaMod(logo_, alpha);
     SDL_RenderCopy(renderer, logo_, nullptr, nullptr);
@@ -52,11 +46,6 @@ void SplashState::render(SDLRenderer& renderer)
 void SplashState::on_enter()
 {
   time_in_state_ = 0ms;
-  logo_ = nullptr;
+  logo_ = AssetManager::instance().get_texture_asset("logo.jpg");
+  SDL_SetTextureBlendMode(logo_, SDL_BLENDMODE_BLEND);
 }
-
-void SplashState::on_leave()
-{
-  SDL_DestroyTexture(logo_);
-  logo_ = nullptr;
-}

+ 4 - 5
game/SplashState.hxx

@@ -7,19 +7,18 @@
 
 #include <SDL.h>
 
-class SplashState final : public GameState {
+class SplashState final : public GameState
+{
 public:
   void on_enter() override;
 
-  void on_leave() override;
-
   void update(GameStateManager& gsm, std::chrono::milliseconds delta_time) override;
 
   void render(SDLRenderer& renderer) override;
 
 private:
-  std::chrono::milliseconds time_in_state_;
-  SDL_Texture* logo_;
+  std::chrono::milliseconds time_in_state_{0};
+  SDL_Texture* logo_{nullptr};
 };
 
 #endif // SNAKE_SPLASHSTATE_HXX