diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index 2a76498e..354957da 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -51,10 +51,8 @@ constexpr const char *kDungeonEditorName = ICON_MD_CASTLE " Dungeon Editor"; constexpr const char *kMusicEditorName = ICON_MD_MUSIC_NOTE " Music Editor"; void EditorManager::Initialize(const std::string &filename) { - // Create a blank editor set - auto blank_editor_set = std::make_unique(); - editor_sets_[nullptr] = std::move(blank_editor_set); - current_editor_set_ = editor_sets_[nullptr].get(); + // Point to a blank editor set when no ROM is loaded + current_editor_set_ = &blank_editor_set_; if (!filename.empty()) { PRINT_IF_ERROR(OpenRomOrProject(filename)); @@ -378,9 +376,10 @@ absl::Status EditorManager::DrawRomSelector() { if (current_rom_ && current_rom_->is_loaded()) { SetNextItemWidth(GetWindowWidth() / 6); if (BeginCombo("##ROMSelector", current_rom_->short_name().c_str())) { - for (const auto &rom : roms_) { + for (const auto &session : sessions_) { + const Rom* rom = &session.rom; if (MenuItem(rom->short_name().c_str())) { - RETURN_IF_ERROR(SetCurrentRom(rom.get())); + RETURN_IF_ERROR(SetCurrentRom(const_cast(rom))); } } EndCombo(); @@ -506,19 +505,17 @@ void EditorManager::DrawMenuBar() { absl::Status EditorManager::LoadRom() { auto file_name = FileDialogWrapper::ShowOpenFileDialog(); - auto new_rom = std::make_unique(); - RETURN_IF_ERROR(new_rom->LoadFromFile(file_name)); + Rom temp_rom; + RETURN_IF_ERROR(temp_rom.LoadFromFile(file_name)); - current_rom_ = new_rom.get(); - roms_.push_back(std::move(new_rom)); - - // Create new editor set for this ROM - auto editor_set = std::make_unique(current_rom_); - for (auto *editor : editor_set->active_editors_) { + sessions_.emplace_back(std::move(temp_rom)); + RomSession &session = sessions_.back(); + // Wire editor contexts + for (auto *editor : session.editors.active_editors_) { editor->set_context(&context_); } - current_editor_set_ = editor_set.get(); - editor_sets_[current_rom_] = std::move(editor_set); + current_rom_ = &session.rom; + current_editor_set_ = &session.editors; static RecentFilesManager manager("recent_files.txt"); manager.Load(); @@ -575,42 +572,37 @@ absl::Status EditorManager::OpenRomOrProject(const std::string &filename) { RETURN_IF_ERROR(current_project_.Open(filename)); RETURN_IF_ERROR(OpenProject()); } else { - auto new_rom = std::make_unique(); - RETURN_IF_ERROR(new_rom->LoadFromFile(filename)); - current_rom_ = new_rom.get(); - roms_.push_back(std::move(new_rom)); - - // Create new editor set for this ROM - auto editor_set = std::make_unique(current_rom_); - for (auto *editor : editor_set->active_editors_) { + Rom temp_rom; + RETURN_IF_ERROR(temp_rom.LoadFromFile(filename)); + sessions_.emplace_back(std::move(temp_rom)); + RomSession &session = sessions_.back(); + for (auto *editor : session.editors.active_editors_) { editor->set_context(&context_); } - current_editor_set_ = editor_set.get(); - editor_sets_[current_rom_] = std::move(editor_set); + current_rom_ = &session.rom; + current_editor_set_ = &session.editors; RETURN_IF_ERROR(LoadAssets()); } return absl::OkStatus(); } absl::Status EditorManager::OpenProject() { - auto new_rom = std::make_unique(); - RETURN_IF_ERROR(new_rom->LoadFromFile(current_project_.rom_filename_)); - current_rom_ = new_rom.get(); - roms_.push_back(std::move(new_rom)); + Rom temp_rom; + RETURN_IF_ERROR(temp_rom.LoadFromFile(current_project_.rom_filename_)); - if (!current_rom_->resource_label()->LoadLabels( + if (!temp_rom.resource_label()->LoadLabels( current_project_.labels_filename_)) { return absl::InternalError( "Could not load labels file, update your project file."); } - // Create new editor set for this ROM - auto editor_set = std::make_unique(current_rom_); - for (auto *editor : editor_set->active_editors_) { + sessions_.emplace_back(std::move(temp_rom)); + RomSession &session = sessions_.back(); + for (auto *editor : session.editors.active_editors_) { editor->set_context(&context_); } - current_editor_set_ = editor_set.get(); - editor_sets_[current_rom_] = std::move(editor_set); + current_rom_ = &session.rom; + current_editor_set_ = &session.editors; static RecentFilesManager manager("recent_files.txt"); manager.Load(); @@ -640,24 +632,16 @@ absl::Status EditorManager::SetCurrentRom(Rom *rom) { return absl::InvalidArgumentError("Invalid ROM pointer"); } - auto it = editor_sets_.find(rom); - if (it == editor_sets_.end()) { - // Create new editor set if it doesn't exist - auto editor_set = std::make_unique(rom); - for (auto *editor : editor_set->active_editors_) { - editor->set_context(&context_); + for (auto &session : sessions_) { + if (&session.rom == rom) { + current_rom_ = &session.rom; + current_editor_set_ = &session.editors; + return absl::OkStatus(); } - current_editor_set_ = editor_set.get(); - - editor_sets_[rom] = std::move(editor_set); - current_rom_ = rom; - RETURN_IF_ERROR(LoadAssets()); - } else { - current_editor_set_ = it->second.get(); - current_rom_ = rom; } - - return absl::OkStatus(); + // If ROM wasn't found in existing sessions, treat as new session. + // Copying an external ROM object is avoided; instead, fail. + return absl::NotFoundError("ROM not found in existing sessions"); } } // namespace editor diff --git a/src/app/editor/editor_manager.h b/src/app/editor/editor_manager.h index c8b393ed..bdc5e08c 100644 --- a/src/app/editor/editor_manager.h +++ b/src/app/editor/editor_manager.h @@ -3,7 +3,8 @@ #define IMGUI_DEFINE_MATH_OPERATORS -#include +#include +#include #include "absl/status/status.h" #include "app/core/project.h" @@ -26,8 +27,44 @@ namespace yaze { namespace editor { -// Forward declaration -class EditorSet; +/** + * @class EditorSet + * @brief Contains a complete set of editors for a single ROM instance + */ +class EditorSet { + public: + explicit EditorSet(Rom* rom = nullptr) + : assembly_editor_(rom), + dungeon_editor_(rom), + graphics_editor_(rom), + music_editor_(rom), + overworld_editor_(rom), + palette_editor_(rom), + screen_editor_(rom), + sprite_editor_(rom), + settings_editor_(rom), + message_editor_(rom), + memory_editor_(rom) { + active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_, + &palette_editor_, &sprite_editor_, &message_editor_, + &music_editor_, &screen_editor_, &settings_editor_, + &assembly_editor_}; + } + + AssemblyEditor assembly_editor_; + DungeonEditor dungeon_editor_; + GraphicsEditor graphics_editor_; + MusicEditor music_editor_; + OverworldEditor overworld_editor_; + PaletteEditor palette_editor_; + ScreenEditor screen_editor_; + SpriteEditor sprite_editor_; + SettingsEditor settings_editor_; + MessageEditor message_editor_; + MemoryEditorWithDiffChecker memory_editor_; + + std::vector active_editors_; +}; /** * @class EditorManager @@ -91,56 +128,27 @@ class EditorManager { absl::Status status_; emu::Emulator emulator_; - std::vector> roms_; - std::unordered_map> editor_sets_; + + struct RomSession { + Rom rom; + EditorSet editors; + + RomSession() = default; + explicit RomSession(Rom&& r) + : rom(std::move(r)), editors(&rom) {} + }; + + std::deque sessions_; Rom* current_rom_ = nullptr; EditorSet* current_editor_set_ = nullptr; Editor* current_editor_ = nullptr; + EditorSet blank_editor_set_{}; Project current_project_; EditorContext context_; std::unique_ptr popup_manager_; }; -/** - * @class EditorSet - * @brief Contains a complete set of editors for a single ROM instance - */ -class EditorSet { - public: - explicit EditorSet(Rom* rom = nullptr) - : assembly_editor_(rom), - dungeon_editor_(rom), - graphics_editor_(rom), - music_editor_(rom), - overworld_editor_(rom), - palette_editor_(rom), - screen_editor_(rom), - sprite_editor_(rom), - settings_editor_(rom), - message_editor_(rom), - memory_editor_(rom) { - active_editors_ = {&overworld_editor_, &dungeon_editor_, &graphics_editor_, - &palette_editor_, &sprite_editor_, &message_editor_, - &music_editor_, &screen_editor_, &settings_editor_, - &assembly_editor_}; - } - - AssemblyEditor assembly_editor_; - DungeonEditor dungeon_editor_; - GraphicsEditor graphics_editor_; - MusicEditor music_editor_; - OverworldEditor overworld_editor_; - PaletteEditor palette_editor_; - ScreenEditor screen_editor_; - SpriteEditor sprite_editor_; - SettingsEditor settings_editor_; - MessageEditor message_editor_; - MemoryEditorWithDiffChecker memory_editor_; - - std::vector active_editors_; -}; - } // namespace editor } // namespace yaze