From 510581ad1fb3295bec34a754d4bb421b35f90b98 Mon Sep 17 00:00:00 2001 From: Justin Scofield <47263509+scawful@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:57:13 -0500 Subject: [PATCH] Refactor Overworld loading to use async tasks Refactored Overworld::LoadSprites to use std::async for concurrent sprite loading, improving efficiency. Modified Overworld::LoadOverworldMaps to wait for all async tasks and check results for errors. Updated Overworld::LoadSpritesFromMap to use mutable_current_graphics() for mutable access to current graphics. Added mutable_current_graphics method to OverworldMap class. Optimized Sprite constructor to take a const reference to avoid unnecessary copying. --- src/app/zelda3/overworld/overworld.cc | 25 ++++++++++++++++-------- src/app/zelda3/overworld/overworld_map.h | 1 + src/app/zelda3/sprite/sprite.h | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/app/zelda3/overworld/overworld.cc b/src/app/zelda3/overworld/overworld.cc index cba42d4c..be0aee59 100644 --- a/src/app/zelda3/overworld/overworld.cc +++ b/src/app/zelda3/overworld/overworld.cc @@ -281,6 +281,7 @@ absl::Status Overworld::LoadOverworldMaps() { // Wait for all tasks to complete and check their results for (auto &future : futures) { + future.wait(); RETURN_IF_ERROR(future.get()); } return absl::OkStatus(); @@ -447,13 +448,21 @@ absl::Status Overworld::LoadItems() { } absl::Status Overworld::LoadSprites() { - for (int i = 0; i < 3; i++) { - all_sprites_.emplace_back(); - } + std::vector> futures; + futures.emplace_back(std::async(std::launch::async, [this]() { + return LoadSpritesFromMap(kOverworldSpritesBeginning, 64, 0); + })); + futures.emplace_back(std::async(std::launch::async, [this]() { + return LoadSpritesFromMap(kOverworldSpritesZelda, 144, 1); + })); + futures.emplace_back(std::async(std::launch::async, [this]() { + return LoadSpritesFromMap(kOverworldSpritesAgahnim, 144, 2); + })); - RETURN_IF_ERROR(LoadSpritesFromMap(kOverworldSpritesBeginning, 64, 0)); - RETURN_IF_ERROR(LoadSpritesFromMap(kOverworldSpritesZelda, 144, 1)); - RETURN_IF_ERROR(LoadSpritesFromMap(kOverworldSpritesAgahnim, 144, 2)); + for (auto& future : futures) { + future.wait(); + RETURN_IF_ERROR(future.get()); + } return absl::OkStatus(); } @@ -484,8 +493,8 @@ absl::Status Overworld::LoadSpritesFromMap(int sprites_per_gamestate_ptr, int realX = ((b2 & 0x3F) * 16) + mapX * 512; int realY = ((b1 & 0x3F) * 16) + mapY * 512; - auto current_gfx = overworld_maps_[i].current_graphics(); - all_sprites_[game_state].emplace_back(current_gfx, (uint8_t)i, b3, + all_sprites_[game_state].emplace_back(*overworld_maps_[i].mutable_current_graphics(), + (uint8_t)i, b3, (uint8_t)(b2 & 0x3F), (uint8_t)(b1 & 0x3F), realX, realY); all_sprites_[game_state][i].Draw(); diff --git a/src/app/zelda3/overworld/overworld_map.h b/src/app/zelda3/overworld/overworld_map.h index 18c864c7..f3080197 100644 --- a/src/app/zelda3/overworld/overworld_map.h +++ b/src/app/zelda3/overworld/overworld_map.h @@ -110,6 +110,7 @@ class OverworldMap : public gfx::GfxContext { auto static_graphics(int i) const { return static_graphics_[i]; } auto large_index() const { return large_index_; } + auto mutable_current_graphics() { return ¤t_gfx_; } auto mutable_area_graphics() { return &area_graphics_; } auto mutable_area_palette() { return &area_palette_; } auto mutable_sprite_graphics(int i) { return &sprite_graphics_[i]; } diff --git a/src/app/zelda3/sprite/sprite.h b/src/app/zelda3/sprite/sprite.h index c0a8896b..985ee01f 100644 --- a/src/app/zelda3/sprite/sprite.h +++ b/src/app/zelda3/sprite/sprite.h @@ -279,7 +279,7 @@ static const std::string kSpriteDefaultNames[]{ class Sprite : public GameEntity { public: Sprite() = default; - Sprite(std::vector src, uint8_t overworld_map_id, uint8_t id, + Sprite(const std::vector& src, uint8_t overworld_map_id, uint8_t id, uint8_t x, uint8_t y, int map_x, int map_y) : map_id_(static_cast(overworld_map_id)), id_(id),