yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
editor_manager.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_EDITOR_MANAGER_H
2#define YAZE_APP_EDITOR_EDITOR_MANAGER_H
3
4#define IMGUI_DEFINE_MATH_OPERATORS
5
6#include <atomic>
7#include <cstddef>
8#include <functional>
9#include <memory>
10#include <optional>
11#include <string>
12#include <vector>
13
14#include "absl/status/status.h"
15#include "absl/strings/string_view.h"
20#include "app/editor/editor.h"
52#include "app/emu/emulator.h"
53#include "app/startup_flags.h"
54#include "core/project.h"
56#include "imgui/imgui.h"
57#include "rom/rom.h"
58#include "util/log.h"
59#include "yaze_config.h"
61
62// Forward declarations for gRPC-dependent types
63namespace yaze {
64class CanvasAutomationServiceImpl;
65}
66
67namespace yaze::editor {
68class AgentEditor;
69class AgentUiController;
70namespace workflow {
72} // namespace workflow
73} // namespace yaze::editor
74
75namespace yaze {
76
77// Forward declaration for AppConfig
78struct AppConfig;
79
80namespace editor {
81
82std::optional<EditorType> ParseEditorTypeFromString(absl::string_view name);
83class EditorManagerLayoutTestPeer;
84
101
102 public:
109
115
116 // Constructor and destructor must be defined in .cc file for std::unique_ptr
117 // with forward-declared types
120
121 void Initialize(gfx::IRenderer* renderer, const std::string& filename = "");
122
123 // Processes startup flags to open a specific editor and panels.
124 void OpenEditorAndPanelsFromFlags(const std::string& editor_name,
125 const std::string& panels_str);
126
127 // Apply startup actions based on AppConfig
128 void ProcessStartupActions(const AppConfig& config);
129 void ApplyStartupVisibility(const AppConfig& config);
130 void SetStartupLoadHints(const AppConfig& config);
131
134
135 absl::Status Update();
136 void DrawMainMenuBar();
137
138 // Host visibility/focus lifecycle hook (e.g., OS space switching).
139 void HandleHostVisibilityChanged(bool visible);
140
141 auto emulator() -> emu::Emulator& { return emulator_; }
142 auto quit() const { return quit_; }
143 auto version() const { return version_; }
144
151 return right_drawer_manager_.get();
152 }
157 // Native (macOS) menu mirrors these bindings; see native_menu_bridge.h.
162 return window_manager_;
163 }
168 return session_coordinator_.get();
169 }
170 [[deprecated("Use window_host() instead.")]] PanelHost* panel_host() {
171 return window_host_.get();
172 }
173 [[deprecated("Use window_host() instead.")]] const PanelHost* panel_host()
174 const {
175 return window_host_.get();
176 }
178 const WindowHost* window_host() const { return window_host_.get(); }
179
180 // Layout offset calculation for dockspace adjustment
181 // Delegates to LayoutCoordinator for cleaner separation of concerns
191
192 absl::Status SetCurrentRom(Rom* rom);
193 Rom* GetCurrentRom() const override {
194 return session_coordinator_ ? session_coordinator_->GetCurrentRom()
195 : nullptr;
196 }
197 auto GetCurrentGameData() const -> zelda3::GameData* {
198 return session_coordinator_ ? session_coordinator_->GetCurrentGameData()
199 : nullptr;
200 }
202 return session_coordinator_ ? session_coordinator_->GetCurrentEditorSet()
203 : nullptr;
204 }
205 auto GetCurrentEditor() const -> Editor* override { return current_editor_; }
206 EditorContextSnapshot GetEditorContextSnapshot(const std::string& category);
207 std::string GetCurrentRomHash() const {
209 }
220 std::vector<editor::RomFileManager::BackupEntry> GetRomBackups() const;
221 bool IsRomBackupRestorePending() const;
222 absl::Status RestoreRomBackup(const std::string& backup_path);
223 absl::Status DiscardPendingRomBackupRestore();
224 absl::Status PruneRomBackups();
225 void ConfirmRomWrite();
230
231 // Write conflict warning (ASM-owned address protection)
232 const std::vector<core::WriteConflict>& pending_write_conflicts() const {
234 }
237 void SetCurrentEditor(Editor* editor) override {
238 current_editor_ = editor;
239 // Update ContentRegistry context for panel access
241 // Update help panel's editor context for context-aware help
242 if (right_drawer_manager_ && editor) {
243 right_drawer_manager_->SetActiveEditor(editor->type());
244 }
245 }
247 size_t GetCurrentSessionId() const {
248 return session_coordinator_ ? session_coordinator_->GetActiveSessionId()
249 : 0;
250 }
253
254 // Session management helpers (compact, zero-based UI ordering)
255 size_t GetCurrentSessionIndex() const;
256
257 // Get current session's feature flags (falls back to global if no session)
259 size_t current_index = GetCurrentSessionIndex();
261 current_index < session_coordinator_->GetTotalSessionCount()) {
262 auto* session = static_cast<RomSession*>(
263 session_coordinator_->GetSession(current_index));
264 if (session) {
265 return &session->feature_flags;
266 }
267 }
268 return &core::FeatureFlags::get(); // Fallback to global
269 }
270
271 void SetFontGlobalScale(float scale) {
273 ImGui::GetIO().FontGlobalScale = scale;
274 auto status = user_settings_.Save();
275 if (!status.ok()) {
276 LOG_WARN("EditorManager", "Failed to save user settings: %s",
277 status.ToString().c_str());
278 }
279 }
280
282 const UserSettings& user_settings() const { return user_settings_; }
283
284 // Workspace management (delegates to WorkspaceManager)
286 void SaveWorkspacePreset(const std::string& name) {
288 }
289 void LoadWorkspacePreset(const std::string& name) {
291 }
292
293 // Jump-to functionality for cross-editor navigation
294 void SwitchToEditor(EditorType editor_type, bool force_visible = false,
295 bool from_dialog = false) override;
296 void DismissEditorSelection() override;
297
298 // True when an editor (not the dashboard picker) is in front of the user.
299 bool HasOpenEditor() const;
300
301 // True while something needs a new frame without user input: the emulator
302 // or music playback, queued texture uploads, or queued deferred actions.
303 // Controller idles otherwise.
304 bool WantsContinuousFrames() const;
305
306 // Panel-based editor registry
307 static bool IsPanelBasedEditor(EditorType type);
308 bool IsSidebarVisible() const {
309 return ui_coordinator_ ? ui_coordinator_->IsPanelSidebarVisible() : false;
310 }
311 void SetSidebarVisible(bool visible) {
312 if (ui_coordinator_) {
313 ui_coordinator_->SetPanelSidebarVisible(visible);
314 }
315 }
316
317 // Lazy asset loading helpers
318 absl::Status EnsureEditorAssetsLoaded(EditorType type);
319 absl::Status EnsureGameDataLoaded();
320
321 // Session management
322 void CreateNewSession();
324 void CloseCurrentSession();
325 void RemoveSession(size_t index);
326
327 // File > Close ROM. Closes the active ROM session even when it is the only
328 // one (the app returns to the welcome surface). Unsaved work goes through
329 // the kUnsavedSessionChanges confirmation first.
330 void CloseRom();
331 bool CanCloseRom() const;
332
333 // File > Revert to Saved. Reloads the active ROM from its backing file,
334 // discarding in-memory ROM edits after the kUnsavedSessionChanges
335 // confirmation. Returns an error only when the revert cannot start or the
336 // reload fails; returns OK while the confirmation is pending.
337 absl::Status RevertRomToSaved();
338 bool CanRevertRom() const;
339 void SwitchToSession(size_t index);
340 void RequestSwitchToSession(size_t index) override { SwitchToSession(index); }
341 void RequestCloseSession(size_t index) override { RemoveSession(index); }
342 size_t GetActiveSessionCount() const;
343
344 // Workspace layout management
345 // Window management - inline delegation (reduces EditorManager bloat)
350 if (ui_coordinator_)
351 ui_coordinator_->ShowAllWindows();
352 }
354 if (ui_coordinator_)
355 ui_coordinator_->HideAllWindows();
356 }
357
358 // Layout presets (inline delegation)
362
363 // Panel layout presets (command palette accessible)
364 void ApplyLayoutPreset(const std::string& preset_name);
365 bool ApplyLayoutProfile(const std::string& profile_id);
367 void RestoreTemporaryLayoutSnapshot(bool clear_after_restore = false);
369
370 // Named, session-scoped layout snapshots (in-memory, multi-slot).
371 bool SaveLayoutSnapshotAs(const std::string& name);
372 bool RestoreLayoutSnapshot(const std::string& name,
373 bool remove_after_restore = false);
374 bool DeleteLayoutSnapshot(const std::string& name);
375 std::vector<std::string> ListLayoutSnapshots() const;
376
378 bool HasPreviousEditorLayout() const;
380
381 // Helper methods
382 std::string GenerateUniqueEditorTitle(EditorType type,
383 size_t session_index) const;
384 bool HasDuplicateSession(const std::string& filepath);
385 void RenameSession(size_t index, const std::string& new_name);
386 void Quit();
387
389 std::string GetPendingUnsavedSessionActionPrompt() const;
390 std::string GetPendingUnsavedSessionActionSaveLabel() const;
395
396 // Deferred action queue - actions executed safely on next frame
397 // Use this to avoid modifying ImGui state during menu/popup rendering
398 void QueueDeferredAction(std::function<void()> action) {
399 deferred_actions_.push_back(std::move(action));
400 pending_editor_deferred_actions_.fetch_add(1, std::memory_order_relaxed);
401 }
402
403 UiSyncState GetUiSyncStateSnapshot() const;
404
405 // Public for SessionCoordinator to configure new sessions
406 void ConfigureSession(RomSession* session) override;
407
408#ifdef YAZE_WITH_GRPC
409 void SetCanvasAutomationService(CanvasAutomationServiceImpl* service) {
410 canvas_automation_service_ = service;
411 }
412#endif
413
414 // UI visibility controls (public for MenuOrchestrator)
415 // UI visibility controls - inline for performance (single-line wrappers
416 // delegating to UICoordinator)
418 if (ui_coordinator_)
419 ui_coordinator_->SetImGuiDemoVisible(true);
420 }
422 if (ui_coordinator_)
423 ui_coordinator_->SetImGuiMetricsVisible(true);
424 }
425
426#ifdef YAZE_ENABLE_TESTING
427 void ShowTestDashboard() { show_test_dashboard_ = true; }
428#endif
429
430#ifdef YAZE_BUILD_AGENT_UI
431 void ShowAIAgent();
432 void ShowChatHistory();
433 AgentEditor* GetAgentEditor();
434 AgentUiController* GetAgentUiController() { return agent_ui_.get(); }
435#else
436 AgentEditor* GetAgentEditor() { return nullptr; }
438#endif
439#ifdef YAZE_BUILD_AGENT_UI
440 void ShowProposalDrawer() { proposal_drawer_.Show(); }
441#endif
442
443 // ROM and Project operations (public for MenuOrchestrator)
444 absl::Status LoadRom();
445 // Normal Save includes project drafts. Explicit ROM writes remain SaveRom.
446 absl::Status SaveCurrentSession();
447 absl::Status SaveCurrentSessionAs();
448 absl::Status SaveRom();
449 absl::Status SaveRomAs(const std::string& filename);
450 absl::Status ResumePendingRomSave();
451 // User opens (Open ROM, recent files, the web drop zone, backups) show ROM
452 // load options for a raw ROM with no remembered choice. Startup,
453 // test-harness, and automation opens pass kNoPrompt: they still apply a
454 // remembered choice but never wait on the dialog.
456 absl::Status OpenRomOrProject(
457 const std::string& filename,
459 // Main-thread semantic automation; returns JSON including actual identity.
460 std::string ExecuteEditorControl(const std::string& request);
461 absl::Status CreateNewProject(
462 const std::string& template_name = "Basic ROM Hack");
463 absl::Status CreateNewProjectFromRom(
464 const std::string& template_name, const std::string& rom_path,
465 const std::string& project_name,
466 const std::string& project_path = std::string());
467 absl::Status FinalizeNewProject(
468 const std::string& project_name,
469 const std::string& project_path = std::string());
470 absl::Status OpenProject();
471 absl::Status CreateLyraTerrain();
472 absl::Status OpenLyraTerrain();
473 absl::Status OpenLyraTerrainFromPath(const std::string& path);
474 absl::Status SaveProject();
475 absl::Status SaveProjectAs();
476 absl::Status SaveProjectAs(const std::string& filepath);
477 absl::Status AutosaveActiveSession();
478 absl::Status BuildCurrentProject();
481 absl::Status RunCurrentProject();
482 // Reopens ROM load options for the active raw-ROM session.
483 void ShowRomLoadOptions();
485
496 absl::Status ImportProject(const std::string& project_path);
497 absl::Status RepairCurrentProject();
498
499 // Project management
500 absl::Status LoadProjectWithRom(bool allow_dialogs = true);
501 absl::Status SwapProjectRom(
502 const std::string& rom_path,
503 const std::optional<std::string>& expected_sha256 = std::nullopt);
504 absl::Status ReloadProjectRom();
507 return &current_project_;
508 }
509 // True only for the session whose project is currently restored into
510 // current_project_. SessionCoordinator also performs transient switches
511 // while drawing inactive sessions, so its active session is not sufficient
512 // for routing project mutations or saves.
513 bool IsCurrentProjectContextOwnedBySession(size_t session_id) const {
514 return active_project_context_session_id_.has_value() &&
516 }
518 bool IsCurrentProjectDirty() const;
519 // Rebuilds the process-wide label provider from the current project; call
520 // after mutating current_project_.resource_labels in place.
523
524 // Show project management panel in right sidebar
526
527 // Show project file editor
533
534 private:
535 absl::Status DrawRomSelector() = delete; // Moved to UICoordinator
536 // DrawContextSensitivePanelControl removed - card control moved to sidebar
537
538 // Optional loading_handle for WASM progress tracking (0 = create new)
539 absl::Status LoadAssets(uint64_t loading_handle = 0);
540 absl::Status LoadAssetsForMode(uint64_t loading_handle = 0);
541 absl::Status LoadAssetsLazy(uint64_t loading_handle = 0);
542 absl::Status InitializeEditorForType(EditorType type, EditorSet* editor_set,
543 Rom* rom);
544 void ResetAssetState(RomSession* session);
545 void MarkEditorInitialized(RomSession* session, EditorType type);
546 void MarkEditorLoaded(RomSession* session, EditorType type);
549 Editor* GetEditorByType(EditorType type, EditorSet* editor_set) const;
550 Editor* ResolveEditorForCategory(const std::string& category);
551 void SyncEditorContextForCategory(const std::string& category);
552 bool EditorRequiresGameData(EditorType type) const;
553 bool EditorInitRequiresGameData(EditorType type) const;
554 std::vector<EditorType> CollectEditorsToPreload(EditorSet* editor_set) const;
555
556 // Testing system
560 // Returns a preferred startup category. Honors the last-active category
561 // (including Emulator). Never defaults to Emulator when nothing was saved.
562 std::string GetPreferredStartupCategory(
563 const std::string& saved_category,
564 const std::vector<std::string>& available_categories) const;
565
566 // Session event handlers (EventBus subscribers)
567 void HandleSessionSwitched(size_t new_index, RomSession* session,
568 bool transient = false);
569 void HandleSessionCreated(size_t index, RomSession* session);
570 void HandleSessionClosed(size_t index);
571 // Initialization helpers (extracted from constructor for readability)
572 void SubscribeToEvents();
574 void RegisterEditors();
576 void InitializeServices();
578 // After a ROM or project loads: stay in the open editor, open the Settings
579 // default editor, or show the editor picker, in that order.
580 void ShowPostLoadSurface();
581 // Applies load options remembered for the active ROM file to the runtime
582 // flags. Call before assets load. False when none match the file and its
583 // ZSCustomOverworld byte, or when a project owns the flags.
586 // Ends a raw ROM open: shows the load options dialog when asked to, or the
587 // post-load surface plus the remembered-choice toast.
588 void FinishRawRomOpen(bool remembered_load_options, bool ask_for_load_options,
589 bool is_first_time_rom_path);
592 std::string rom_key;
594 };
598 const RomLoadOptionsOwner& owner) const;
599 // Closes the dialog without applying options. When it still had an owner,
600 // a toast says why, so the dialog never disappears without a reason.
601 void CloseRomLoadOptions(const char* reason);
606 void ProcessInput();
607 void UpdateEditorState();
609 void DrawInterface();
611 void UpdateSystemUIs();
612 void RunEmulator();
614
615 void HandleSessionRomLoaded(size_t index, Rom* rom);
616
617 // UI action event handler (EventBus subscriber for UIActionRequestEvent)
619
620 bool quit_ = false;
621
622 // Note: All show_* flags are being moved to UICoordinator
623 // Access via ui_coordinator_->IsXxxVisible() or SetXxxVisible()
624
625 // Workspace dialog flags (managed by EditorManager, not UI)
629
630 // Note: Most UI visibility flags have been moved to UICoordinator
631 // Access via ui_coordinator_->IsXxxVisible() or SetXxxVisible()
632
633 // Agent proposal drawer
636
637 // Agent UI (chat + editor), no-op when agent UI is disabled. Never null:
638 // allocated in the constructor and never reset.
639 std::unique_ptr<AgentUiController> agent_ui_;
640
641 // Project file editor
643
644 // Editor selection and the Welcome screen are managed by UICoordinator.
645 std::unique_ptr<DashboardPanel> dashboard_panel_;
648 std::optional<RomLoadOptionsOwner> rom_load_options_owner_;
650 // False while the previous frame drew the editor surface. Drawers left open
651 // by an editor close when the Welcome screen replaces that surface; drawers
652 // opened on the Welcome screen (File > Settings, the drawers button,
653 // Ctrl/Cmd+,, --editor=Settings) stay open. Starts true: at launch there is
654 // no editor surface to leave.
660 std::vector<std::string> startup_panel_hints_;
661
662 // Properties panel for selection editing
664
665 // Project management panel for version control and ROM management
666 std::unique_ptr<ProjectManagementPanel> project_management_panel_;
667
668 std::string version_ = "";
669 absl::Status status_;
671
672 public:
673 private:
675 // Tracks which session is currently active so delegators (menus, popups,
676 // shortcuts) stay in sync without relying on per-editor context.
677
679
682 std::string previous_path;
683 std::string candidate_path;
684 };
685 std::optional<PendingProjectRomSelection> pending_project_rom_selection_;
689 // current_project_ is a stable-address working copy owned by the active
690 // user-facing session. Stable IDs survive UI-index compaction.
692 // The global FeatureFlags singleton is also rebound during transient frame
693 // iteration, so track which session currently owns its value separately.
695 // Non-owning view of the active session's VersionManager. Each RomSession
696 // owns its manager so EditorSet dependency pointers remain valid while that
697 // session is inactive.
700 std::unique_ptr<PopupManager> popup_manager_;
706
707 // New delegated components (dependency injection architecture)
709 window_manager_; // Window management with session awareness
710 std::unique_ptr<WindowHost> window_host_;
712 std::unique_ptr<MenuOrchestrator> menu_orchestrator_;
715 std::unique_ptr<UICoordinator> ui_coordinator_;
718 std::unique_ptr<SessionCoordinator> session_coordinator_;
719 std::unique_ptr<LayoutManager>
720 layout_manager_; // DockBuilder layout management
721 LayoutCoordinator layout_coordinator_; // Facade for layout operations
722 std::unique_ptr<RightDrawerManager>
723 right_drawer_manager_; // Right-side drawer system
724 StatusBar status_bar_; // Bottom status bar
725 std::unique_ptr<ActivityBar> activity_bar_;
727
730 void CaptureCurrentRomIdentity(bool preserve_editing_source = false);
737 bool publish_lyra = true);
740 const project::YazeProject& project);
743 absl::Status SaveActiveProjectEditingWork(bool allow_dialogs = true);
744 // Saves project work; when ROM work is also pending, the ROM save that
745 // follows publishes the one native-save receipt for both.
746 absl::Status SaveProjectWorkBeforeRomSave(bool allow_dialogs);
748 bool include_recent_files);
750 bool IsPlanningOnlyProjectSave(const RomSession& session);
751 absl::Status PrepareRawProjectFileSave(const std::string& filepath,
752 const std::string& contents);
753 absl::Status CommitRawProjectFileSave(const std::string& filepath,
754 const std::string& contents);
755 absl::Status ReplaceActiveSessionRom(Rom&& rom, const std::string& filepath);
757 void RebaseCleanProjectFileDraft(const std::string& filepath);
759 std::optional<size_t> previous_session_id);
761 size_t previous_session_count);
763 absl::StatusOr<const project::YazeProject*>
765 ProjectWorkflowStatus MakeBuildStatus(const std::string& summary,
766 const std::string& detail,
768 const std::string& output_tail = "",
769 bool can_cancel = false) const;
770 ProjectWorkflowStatus MakeRunStatus(const std::string& summary,
771 const std::string& detail,
772 ProjectWorkflowState state) const;
773 absl::StatusOr<std::string> RunProjectBuildCommand();
774 absl::StatusOr<std::string> ResolveProjectBuildCommand();
775 absl::StatusOr<std::string> ResolveProjectRunTarget() const;
776 absl::Status CheckRomWritePolicy(
777 const std::optional<std::string>& target_filename = std::nullopt);
778 absl::Status CheckOracleRomSafetyPreSave(Rom* rom);
779 absl::Status SaveRomInternal(
780 const std::optional<std::string>& save_as_filename);
781 // rom_written=false records a project-only Save: the ROM is bound as it is
782 // on disk and is never rewritten.
783 absl::Status RecordCompletedNativeSave(const project::YazeProject& project,
784 const std::string& saved_rom,
785 bool save_as, bool rom_written = true);
787 std::string NativeSaveEditingSourcePath() const;
788 absl::Status RetireNativeSaveTransfer(
789 const std::string& state, const std::string& editing_source_path = "");
792 void FinishPendingRomSaveAttempt(const absl::Status& status);
793 void CancelPendingRomSave(bool hide_popups = false);
794 absl::Status StartPendingRomSave(
795 const std::optional<std::string>& save_as_filename);
796 absl::Status LoadRomInternal();
797 bool ActivateExistingSessionForOpen(const std::string& filename);
798 absl::Status OpenRomOrProjectInternal(
799 const std::string& filename, bool allow_dialogs = true,
801 absl::Status OpenProjectInternal();
802 absl::Status ValidateLyraTerrainProjectContext() const;
803 absl::Status ValidateProjectRomSelection(const std::string& rom_path);
804
823
824 std::optional<size_t> ResolveSessionIndexById(size_t session_id) const;
827 const PendingUnsavedSessionAction& action);
828 absl::Status RevertRomToSavedInternal();
829 bool SessionHasPendingUnsavedWork(size_t session_index) const;
830 bool SessionHasPendingRomWork(size_t session_index) const;
832 bool HasPendingDungeonChangesForSession(size_t session_index) const;
833 int PendingDungeonRoomCountForSession(size_t session_index) const;
834 size_t PendingPaletteColorCountForSession(size_t session_index) const;
835 int ModifiedSessionCount() const;
836 std::string DescribePendingUnsavedWork(size_t session_index) const;
837 std::string CompactPendingUnsavedWorkLabel(size_t session_index) const;
838 std::string DescribeAllPendingUnsavedWork() const;
839
840 float autosave_timer_ = 0.0f;
841 bool settings_dirty_ = false;
844 std::optional<PendingUnsavedSessionAction> pending_unsaved_session_action_;
845
846 // ROM lifecycle state (hash, write policy, confirmation dialogs, backups)
847 // Mutable because some const accessors delegate to it.
850 std::optional<std::string> save_as_filename;
851 size_t session_index = SIZE_MAX;
852 Rom* rom = nullptr;
853 };
854 std::optional<PendingRomSave> pending_rom_save_;
855 // Set while Save Current Session persists project work ahead of a ROM save
856 // whose own native receipt will complete that project Save.
858
859 // Deferred action queue - executed at the start of each frame
860 std::vector<std::function<void()>> deferred_actions_;
862 std::atomic<uint64_t> ui_sync_frame_id_{0};
863 std::unique_ptr<BackgroundCommandTask> active_project_build_;
865
866 // Core Event Bus and Context
868 std::unique_ptr<GlobalEditorContext> editor_context_;
869 std::unique_ptr<workflow::HackWorkflowBackend> hack_workflow_backend_;
870
871#ifdef YAZE_WITH_GRPC
872 CanvasAutomationServiceImpl* canvas_automation_service_ = nullptr;
873#endif
874
875 // RAII helper for clean session context switching
877 public:
878 SessionScope(EditorManager* manager, size_t session_index);
880
881 private:
886 };
887
888 void ConfigureEditorDependencies(EditorSet* editor_set, Rom* rom,
889 size_t session_id);
891};
892
893} // namespace editor
894} // namespace yaze
895
896#endif // YAZE_APP_EDITOR_EDITOR_MANAGER_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:52
static Flags & get()
Definition features.h:122
Manages project versioning (Git) and ROM artifact snapshots.
Comprehensive AI Agent Platform & Bot Creator.
Central coordinator for all agent UI components.
Handles editor switching, layout initialization, and jump-to navigation.
SessionScope(EditorManager *manager, size_t session_index)
The EditorManager controls the main editor window and manages the various editor classes.
void ApplyProjectSaveSettings(project::YazeProject *project, bool include_recent_files)
std::optional< RomLoadOptionsOwner > rom_load_options_owner_
std::unique_ptr< SessionCoordinator > session_coordinator_
RomLifecycleManager rom_lifecycle_
void SaveWorkspacePreset(const std::string &name)
StartupVisibility welcome_mode_override_
std::unique_ptr< AgentUiController > agent_ui_
void ConfirmPendingUnsavedSessionActionSaveAndContinue()
std::optional< PendingRomSave > pending_rom_save_
std::vector< EditorType > CollectEditorsToPreload(EditorSet *editor_set) const
void SwitchToEditor(EditorType editor_type, bool force_visible=false, bool from_dialog=false) override
std::unique_ptr< GlobalEditorContext > editor_context_
void RestoreProjectEditingStateForSession(RomSession *session)
auto GetCurrentGameData() const -> zelda3::GameData *
bool RomLoadOptionsOwnerMatchesCurrentSession(const RomLoadOptionsOwner &owner) const
bool MaybeGuardPendingSessionAction(PendingUnsavedSessionAction action)
absl::Status SaveRomAs(const std::string &filename)
bool HasAnySessionPendingUnsavedWork() const
project::YazeProject current_project_
void HandleSessionSwitched(size_t new_index, RomSession *session, bool transient=false)
absl::Status CompletePendingProjectNativeSave()
absl::Status ValidateLyraTerrainProjectContext() const
std::unique_ptr< RightDrawerManager > right_drawer_manager_
void SetCurrentEditor(Editor *editor) override
bool SaveLayoutSnapshotAs(const std::string &name)
absl::Status PrepareRawProjectFileSave(const std::string &filepath, const std::string &contents)
absl::Status LoadAssetsForMode(uint64_t loading_handle=0)
std::string GetPreferredStartupCategory(const std::string &saved_category, const std::vector< std::string > &available_categories) const
const WorkspaceWindowManager & window_manager() const
absl::StatusOr< std::string > RunProjectBuildCommand()
absl::Status CheckRomWritePolicy(const std::optional< std::string > &target_filename=std::nullopt)
Save the current ROM file.
absl::Status RestoreRomBackup(const std::string &backup_path)
bool SessionHasPendingRomWork(size_t session_index) const
bool HasPendingPotItemSaveConfirmation() const
Rom * GetCurrentRom() const override
void CancelPendingRomSave(bool hide_popups=false)
int PendingDungeonRoomCountForSession(size_t session_index) const
bool HasDuplicateSession(const std::string &filepath)
WorkspaceManager * workspace_manager()
std::unique_ptr< LayoutManager > layout_manager_
std::unique_ptr< DashboardPanel > dashboard_panel_
absl::Status RetireNativeSaveTransfer(const std::string &state, const std::string &editing_source_path="")
void ResetAssetState(RomSession *session)
void ProcessStartupActions(const AppConfig &config)
void LoadWorkspacePreset(const std::string &name)
std::string GenerateUniqueEditorTitle(EditorType type, size_t session_index) const
void RenameSession(size_t index, const std::string &new_name)
core::VersionManager * version_manager_
std::vector< editor::RomFileManager::BackupEntry > GetRomBackups() const
std::string CompactPendingUnsavedWorkLabel(size_t session_index) const
const UserSettings & user_settings() const
std::vector< std::string > ListLayoutSnapshots() const
SharedClipboard shared_clipboard_
bool EditorInitRequiresGameData(EditorType type) const
void SyncEditorContextForCategory(const std::string &category)
const RightDrawerManager * right_drawer_manager() const
UICoordinator * ui_coordinator()
void ShowProjectManagement()
Injects dependencies into all editors within an EditorSet.
Editor * ResolveEditorForCategory(const std::string &category)
void FinishRawRomOpen(bool remembered_load_options, bool ask_for_load_options, bool is_first_time_rom_path)
void Initialize(gfx::IRenderer *renderer, const std::string &filename="")
std::optional< size_t > runtime_feature_flags_session_id_
absl::Status FinalizeNewProject(const std::string &project_name, const std::string &project_path=std::string())
std::string DescribeAllPendingUnsavedWork() const
project::RomWritePolicy GetProjectRomWritePolicy() const
void MarkEditorLoaded(RomSession *session, EditorType type)
absl::Status StartPendingRomSave(const std::optional< std::string > &save_as_filename)
absl::Status CreateNewProjectFromRom(const std::string &template_name, const std::string &rom_path, const std::string &project_name, const std::string &project_path=std::string())
friend class EditorManagerLayoutTestPeer
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
absl::Status RecordCompletedNativeSave(const project::YazeProject &project, const std::string &saved_rom, bool save_as, bool rom_written=true)
RightDrawerManager * right_drawer_manager()
void ConfirmPendingUnsavedSessionActionDiscardAndContinue()
absl::Status InitializeEditorForType(EditorType type, EditorSet *editor_set, Rom *rom)
LayoutCoordinator layout_coordinator_
absl::Status LoadAssets(uint64_t loading_handle=0)
std::string GetCurrentRomHash() const
FeatureHintManager feature_hint_manager_
bool HasPendingUnsavedSessionAction() const
void RestoreActiveEditorLayoutAfterAssets(RomSession *session)
auto GetCurrentEditorSet() const -> EditorSet *
std::string DescribePendingUnsavedWork(size_t session_index) const
void SetFontGlobalScale(float scale)
absl::Status LoadProjectWithRom(bool allow_dialogs=true)
EditorContextSnapshot GetEditorContextSnapshot(const std::string &category)
ProjectManagementPanel * project_management_panel()
void FinishPendingRomSaveAttempt(const absl::Status &status)
std::unique_ptr< MenuOrchestrator > menu_orchestrator_
void RequestSwitchToSession(size_t index) override
void HandleUIActionRequest(UIActionRequestEvent::Action action)
void ResolvePotItemSaveConfirmation(PotItemSaveDecision decision)
absl::Status CommitRawProjectFileSave(const std::string &filepath, const std::string &contents)
auto GetCurrentEditor() const -> Editor *override
absl::Status OpenRomOrProject(const std::string &filename, LoadOptionsPrompt prompt=LoadOptionsPrompt::kAsk)
void HandleSessionRomLoaded(size_t index, Rom *rom)
WorkspaceWindowManager & window_manager()
ProjectFileEditor project_file_editor_
void SetSidebarVisible(bool visible)
void HandleHostVisibilityChanged(bool visible)
void ApplyLayoutPreset(const std::string &preset_name)
void RestoreTemporaryLayoutSnapshot(bool clear_after_restore=false)
void ApplyStartupVisibility(const AppConfig &config)
ShortcutManager * shortcut_manager()
void ExecutePendingUnsavedSessionAction(const PendingUnsavedSessionAction &action)
WorkspaceWindowManager window_manager_
absl::Status SwapProjectRom(const std::string &rom_path, const std::optional< std::string > &expected_sha256=std::nullopt)
size_t PendingPaletteColorCountForSession(size_t session_index) const
absl::Status OpenLyraTerrainFromPath(const std::string &path)
std::string GetProjectExpectedRomHash() const
const WindowHost * window_host() const
void RestoreEditorLayoutAfterAssets(RomSession *session, EditorType type)
void PersistInputConfig(const emu::input::InputConfig &config)
absl::Status SaveRomInternal(const std::optional< std::string > &save_as_filename)
void SetStartupLoadHints(const AppConfig &config)
void RebaseCleanProjectFileDraft(const std::string &filepath)
std::optional< size_t > pending_project_open_previous_session_id_
absl::Status LoadAssetsLazy(uint64_t loading_handle=0)
bool PendingRomSaveMatchesActiveSession() const
absl::Status DrawRomSelector()=delete
void SetAssetLoadMode(AssetLoadMode mode)
void DismissEditorSelection() override
absl::Status DiscardPendingRomBackupRestore()
const std::vector< core::WriteConflict > & pending_write_conflicts() const
std::atomic< uint64_t > ui_sync_frame_id_
std::optional< size_t > active_project_context_session_id_
std::string GetPendingUnsavedSessionActionContinueLabel() const
std::string GetPendingUnsavedSessionActionPrompt() const
const project::YazeProject * GetCurrentProject() const
bool ApplyLayoutProfile(const std::string &profile_id)
Editor * GetEditorByType(EditorType type, EditorSet *editor_set) const
StartupVisibility sidebar_mode_override_
RomLoadOptionsDialog rom_load_options_dialog_
absl::Status LoadRom()
Load a ROM file into a new or existing session.
std::vector< std::string > startup_panel_hints_
std::vector< std::function< void()> > deferred_actions_
bool ActivateExistingSessionForOpen(const std::string &filename)
void OpenEditorAndPanelsFromFlags(const std::string &editor_name, const std::string &panels_str)
project::RomRole GetProjectRomRole() const
StartupVisibility dashboard_mode_override_
void BindProjectContextToSession(RomSession *session, const project::YazeProject &project)
std::optional< size_t > ResolveSessionIndexById(size_t session_id) const
static bool IsPanelBasedEditor(EditorType type)
absl::Status Update()
Main update loop for the editor application.
SessionCoordinator * session_coordinator()
absl::Status OpenRomOrProjectInternal(const std::string &filename, bool allow_dialogs=true, LoadOptionsPrompt prompt=LoadOptionsPrompt::kAsk)
absl::StatusOr< std::string > ResolveProjectRunTarget() const
absl::Status ImportProject(const std::string &project_path)
FeatureHintManager * feature_hint_manager()
AgentUiController * GetAgentUiController()
core::VersionManager * GetVersionManager()
WorkspaceWindowManager * GetWindowManager()
void RequestCloseSession(size_t index) override
size_t GetCurrentSessionId() const
Stable workspace identity; unlike the UI index, it does not compact.
std::string ExecuteEditorControl(const std::string &request)
bool ProjectFileDraftTargetsCurrentProject() const
absl::Status SaveProjectWorkBeforeRomSave(bool allow_dialogs)
AssetLoadMode asset_load_mode() const
ProjectWorkflowStatus MakeRunStatus(const std::string &summary, const std::string &detail, ProjectWorkflowState state) const
project::YazeProject * GetCurrentProject()
void QueueDeferredAction(std::function< void()> action)
absl::Status ValidateProjectRomSelection(const std::string &rom_path)
SelectionPropertiesPanel selection_properties_panel_
bool DeleteLayoutSnapshot(const std::string &name)
absl::Status PrepareActiveProjectEditorDraftsForSave(bool publish_lyra=true)
const SessionCoordinator * session_coordinator() const
ProjectFileEditor * project_file_editor()
void ConfigureSession(RomSession *session) override
std::unique_ptr< ActivityBar > activity_bar_
ShortcutManager shortcut_manager_
auto emulator() -> emu::Emulator &
const PanelHost * panel_host() const
emu::input::InputConfig BuildInputConfigFromSettings() const
bool RestoreLayoutSnapshot(const std::string &name, bool remove_after_restore=false)
bool HasPendingDungeonChangesForSession(size_t session_index) const
std::optional< PendingUnsavedSessionAction > pending_unsaved_session_action_
void MarkEditorInitialized(RomSession *session, EditorType type)
bool SessionHasPendingUnsavedWork(size_t session_index) const
absl::Status RevertRomToSavedInternal()
std::unique_ptr< BackgroundCommandTask > active_project_build_
bool IsCurrentProjectContextOwnedBySession(size_t session_id) const
bool IsPlanningOnlyProjectSave(const RomSession &session)
core::FeatureFlags::Flags * GetCurrentFeatureFlags()
WorkspaceManager workspace_manager_
yaze::zelda3::Overworld * overworld() const
void ConfigureEditorDependencies(EditorSet *editor_set, Rom *rom, size_t session_id)
int pending_pot_item_unloaded_rooms() const
absl::StatusOr< const project::YazeProject * > PrepareActiveProjectContextForSave()
std::unique_ptr< ProjectManagementPanel > project_management_panel_
std::unique_ptr< workflow::HackWorkflowBackend > hack_workflow_backend_
absl::StatusOr< std::string > ResolveProjectBuildCommand()
void RestoreProjectContextAfterFailedOpen(std::optional< size_t > previous_session_id)
void RemoveSession(size_t index)
absl::Status CheckOracleRomSafetyPreSave(Rom *rom)
UiSyncState GetUiSyncStateSnapshot() const
ProjectWorkflowStatus MakeBuildStatus(const std::string &summary, const std::string &detail, ProjectWorkflowState state, const std::string &output_tail="", bool can_cancel=false) const
void CloseRomLoadOptions(const char *reason)
absl::Status DiscardProvisionalSessionCreatedSince(size_t previous_session_count)
absl::Status EnsureEditorAssetsLoaded(EditorType type)
std::unique_ptr< PopupManager > popup_manager_
bool RestoreProjectContextForSession(RomSession *session)
void CaptureCurrentRomIdentity(bool preserve_editing_source=false)
std::atomic< int > pending_editor_deferred_actions_
std::unique_ptr< UICoordinator > ui_coordinator_
EditorActivator editor_activator_
absl::Status SetCurrentRom(Rom *rom)
std::string GetPendingUnsavedSessionActionSaveLabel() const
std::optional< PendingProjectRomSelection > pending_project_rom_selection_
std::unique_ptr< WindowHost > window_host_
void HandleSessionCreated(size_t index, RomSession *session)
absl::Status SaveActiveProjectEditingWork(bool allow_dialogs=true)
bool EditorRequiresGameData(EditorType type) const
absl::Status ReplaceActiveSessionRom(Rom &&rom, const std::string &filepath)
Manages editor types, categories, and lifecycle.
Contains a complete set of editors for a single ROM instance.
Interface for editor classes.
Definition editor.h:252
EditorType type() const
Definition editor.h:355
Show-once feature tips backed by ToastManager + UserSettings.
Interface for editor selection and navigation.
Interface for session configuration.
Facade class that coordinates all layout-related operations.
float GetBottomLayoutOffset() const
Get the bottom margin needed for status bar.
float GetRightLayoutOffset() const
Get the right margin needed for drawers.
float GetLeftLayoutOffset() const
Get the left margin needed for sidebar (Activity Bar + Side Panel)
Fluent interface for building ImGui menus with icons.
Editor for .yaze project files with syntax highlighting and validation.
Panel for managing project settings, ROM versions, and snapshots.
Handles all project file operations with ROM-first workflow.
ImGui drawer for displaying and managing agent proposals.
Manages right-side sliding drawers for agent chat, proposals, settings.
Handles all ROM file I/O operations.
Manages ROM and project persistence state.
bool IsRomHashMismatch() const
Check whether the ROM hash mismatches the project's expected hash.
const std::string & current_rom_hash() const
Get the cached ROM hash string.
const std::vector< core::WriteConflict > & pending_write_conflicts() const
Full-editing properties panel for selected entities.
High-level orchestrator for multi-session UI.
A session-aware status bar displayed at the bottom of the application.
Definition status_bar.h:57
Handles all UI drawing operations and state management.
Manages user preferences and settings persistence.
Low-level window operations with minimal dependencies.
Thin host API over WorkspaceWindowManager for declarative window workflows.
Definition panel_host.h:46
Manages workspace layouts, sessions, and presets.
void SaveWorkspacePreset(const std::string &name)
void LoadWorkspacePreset(const std::string &name)
absl::Status SaveWorkspaceLayout(const std::string &name="")
absl::Status LoadWorkspaceLayout(const std::string &name="")
Central registry for all editor cards with session awareness and dependency injection.
A class for emulating and debugging SNES games.
Definition emulator.h:41
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
#define LOG_WARN(category, format,...)
Definition log.h:138
void SetCurrentEditor(Editor *editor)
Set the currently active editor.
Editors are the view controllers for the application.
std::optional< EditorType > ParseEditorTypeFromString(absl::string_view name)
StartupVisibility
Tri-state toggle used for startup UI visibility controls.
AssetLoadMode
Asset loading mode for editor resources.
Configuration options for the application startup.
Definition application.h:26
std::optional< std::string > save_as_filename
Represents a single session, containing a ROM and its associated editors.
core::FeatureFlags::Flags feature_flags
Input configuration (platform-agnostic key codes)
std::string expected_hash
Definition project.h:228
RomWritePolicy write_policy
Definition project.h:229
Modern project structure with comprehensive settings consolidation.
Definition project.h:290