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 <string>
11#include <vector>
12
13#include "absl/status/status.h"
19#include "app/editor/editor.h"
49#include "app/emu/emulator.h"
50#include "app/startup_flags.h"
51#include "core/project.h"
53#include "imgui/imgui.h"
54#include "rom/rom.h"
55#include "util/log.h"
56#include "yaze_config.h"
58
59// Forward declarations for gRPC-dependent types
60namespace yaze {
61class CanvasAutomationServiceImpl;
62}
63
64namespace yaze::editor {
65class AgentEditor;
66}
67
68namespace yaze {
69
70// Forward declaration for AppConfig
71struct AppConfig;
72
73namespace editor {
74
90 public:
91 struct UiSyncState {
92 uint64_t frame_id = 0;
96 };
97
103
104 // Constructor and destructor must be defined in .cc file for std::unique_ptr
105 // with forward-declared types
108
109 void Initialize(gfx::IRenderer* renderer, const std::string& filename = "");
110
111 // Processes startup flags to open a specific editor and panels.
112 void OpenEditorAndPanelsFromFlags(const std::string& editor_name,
113 const std::string& panels_str);
114
115 // Apply startup actions based on AppConfig
116 void ProcessStartupActions(const AppConfig& config);
117 void ApplyStartupVisibility(const AppConfig& config);
118
121
122 absl::Status Update();
123 void DrawMainMenuBar();
124
125 // Host visibility/focus lifecycle hook (e.g., OS space switching).
126 void HandleHostVisibilityChanged(bool visible);
127
128 auto emulator() -> emu::Emulator& { return emulator_; }
129 auto quit() const { return quit_; }
130 auto version() const { return version_; }
131
141 const PanelManager& panel_manager() const { return panel_manager_; }
142 PanelHost* panel_host() { return panel_host_.get(); }
143 const PanelHost* panel_host() const { return panel_host_.get(); }
144
145 // Deprecated compatibility wrappers
147 const PanelManager& card_registry() const { return panel_manager_; }
148
149 // Layout offset calculation for dockspace adjustment
150 // Delegates to LayoutCoordinator for cleaner separation of concerns
160
161 absl::Status SetCurrentRom(Rom* rom);
162 Rom* GetCurrentRom() const override {
163 return session_coordinator_ ? session_coordinator_->GetCurrentRom()
164 : nullptr;
165 }
166 auto GetCurrentGameData() const -> zelda3::GameData* {
167 return session_coordinator_ ? session_coordinator_->GetCurrentGameData()
168 : nullptr;
169 }
171 return session_coordinator_ ? session_coordinator_->GetCurrentEditorSet()
172 : nullptr;
173 }
174 auto GetCurrentEditor() const -> Editor* { return current_editor_; }
175 std::string GetCurrentRomHash() const {
177 }
187 bool IsRomHashMismatch() const {
189 }
190 std::vector<editor::RomFileManager::BackupEntry> GetRomBackups() const;
191 absl::Status RestoreRomBackup(const std::string& backup_path);
192 absl::Status PruneRomBackups();
198
199 // Write conflict warning (ASM-owned address protection)
200 const std::vector<core::WriteConflict>& pending_write_conflicts() const {
202 }
207 void SetCurrentEditor(Editor* editor) override {
208 current_editor_ = editor;
209 // Update ContentRegistry context for panel access
211 // Update help panel's editor context for context-aware help
212 if (right_panel_manager_ && editor) {
213 right_panel_manager_->SetActiveEditor(editor->type());
214 }
215 }
216 size_t GetCurrentSessionId() const {
217 return session_coordinator_ ? session_coordinator_->GetActiveSessionIndex()
218 : 0;
219 }
222
223 // Session management helpers
224 size_t GetCurrentSessionIndex() const;
225
226 // Get current session's feature flags (falls back to global if no session)
228 size_t current_index = GetCurrentSessionIndex();
230 current_index < session_coordinator_->GetTotalSessionCount()) {
231 auto* session = static_cast<RomSession*>(
232 session_coordinator_->GetSession(current_index));
233 if (session) {
234 return &session->feature_flags;
235 }
236 }
237 return &core::FeatureFlags::get(); // Fallback to global
238 }
239
240 void SetFontGlobalScale(float scale) {
242 ImGui::GetIO().FontGlobalScale = scale;
243 auto status = user_settings_.Save();
244 if (!status.ok()) {
245 LOG_WARN("EditorManager", "Failed to save user settings: %s",
246 status.ToString().c_str());
247 }
248 }
249
250 // Workspace management (delegates to WorkspaceManager)
252 void SaveWorkspacePreset(const std::string& name) {
254 }
255 void LoadWorkspacePreset(const std::string& name) {
257 }
258
259 // Jump-to functionality for cross-editor navigation
260 void SwitchToEditor(EditorType editor_type, bool force_visible = false,
261 bool from_dialog = false) override;
262 void DismissEditorSelection() override;
263
264 // Panel-based editor registry
265 static bool IsPanelBasedEditor(EditorType type);
266 bool IsSidebarVisible() const {
267 return ui_coordinator_ ? ui_coordinator_->IsPanelSidebarVisible() : false;
268 }
269 void SetSidebarVisible(bool visible) {
270 if (ui_coordinator_) {
271 ui_coordinator_->SetPanelSidebarVisible(visible);
272 }
273 }
274
275 // Lazy asset loading helpers
276 absl::Status EnsureEditorAssetsLoaded(EditorType type);
277 absl::Status EnsureGameDataLoaded();
278
279 // Session management
280 void CreateNewSession();
282 void CloseCurrentSession();
283 void RemoveSession(size_t index);
284 void SwitchToSession(size_t index);
285 size_t GetActiveSessionCount() const;
286
287 // Workspace layout management
288 // Window management - inline delegation (reduces EditorManager bloat)
293 if (ui_coordinator_)
294 ui_coordinator_->ShowAllWindows();
295 }
297 if (ui_coordinator_)
298 ui_coordinator_->HideAllWindows();
299 }
300
301 // Layout presets (inline delegation)
305
306 // Panel layout presets (command palette accessible)
307 void ApplyLayoutPreset(const std::string& preset_name);
308 bool ApplyLayoutProfile(const std::string& profile_id);
310 void RestoreTemporaryLayoutSnapshot(bool clear_after_restore = false);
313
314 // Helper methods
315 std::string GenerateUniqueEditorTitle(EditorType type,
316 size_t session_index) const;
317 bool HasDuplicateSession(const std::string& filepath);
318 void RenameSession(size_t index, const std::string& new_name);
319 void Quit() { quit_ = true; }
320
321 // Deferred action queue - actions executed safely on next frame
322 // Use this to avoid modifying ImGui state during menu/popup rendering
323 void QueueDeferredAction(std::function<void()> action) {
324 deferred_actions_.push_back(std::move(action));
325 pending_editor_deferred_actions_.fetch_add(1, std::memory_order_relaxed);
326 }
327
328 UiSyncState GetUiSyncStateSnapshot() const;
329
330 // Public for SessionCoordinator to configure new sessions
331 void ConfigureSession(RomSession* session) override;
332
333#ifdef YAZE_WITH_GRPC
334 void SetCanvasAutomationService(CanvasAutomationServiceImpl* service) {
335 canvas_automation_service_ = service;
336 }
337#endif
338
339 // UI visibility controls (public for MenuOrchestrator)
340 // UI visibility controls - inline for performance (single-line wrappers
341 // delegating to UICoordinator)
343 if (ui_coordinator_)
344 ui_coordinator_->SetImGuiDemoVisible(true);
345 }
347 if (ui_coordinator_)
348 ui_coordinator_->SetImGuiMetricsVisible(true);
349 }
350
351#ifdef YAZE_ENABLE_TESTING
352 void ShowTestDashboard() { show_test_dashboard_ = true; }
353#endif
354
355#ifdef YAZE_BUILD_AGENT_UI
356 void ShowAIAgent();
357 void ShowChatHistory();
358 AgentEditor* GetAgentEditor() { return agent_ui_.GetAgentEditor(); }
359 AgentUiController* GetAgentUiController() { return &agent_ui_; }
360#else
361 AgentEditor* GetAgentEditor() { return nullptr; }
363#endif
364#ifdef YAZE_BUILD_AGENT_UI
365 void ShowProposalDrawer() { proposal_drawer_.Show(); }
366#endif
367
368 // ROM and Project operations (public for MenuOrchestrator)
369 absl::Status LoadRom();
370 absl::Status SaveRom();
371 absl::Status SaveRomAs(const std::string& filename);
372 absl::Status OpenRomOrProject(const std::string& filename);
373 absl::Status CreateNewProject(
374 const std::string& template_name = "Basic ROM Hack");
375 absl::Status OpenProject();
376 absl::Status SaveProject();
377 absl::Status SaveProjectAs();
378
389 absl::Status ImportProject(const std::string& project_path);
390 absl::Status RepairCurrentProject();
391
392 // Project management
393 absl::Status LoadProjectWithRom();
396 return &current_project_;
397 }
399
400 // Show project management panel in right sidebar
402
403 // Show project file editor
405
406 private:
407 absl::Status DrawRomSelector() = delete; // Moved to UICoordinator
408 // DrawContextSensitivePanelControl removed - card control moved to sidebar
409
410 // Optional loading_handle for WASM progress tracking (0 = create new)
411 absl::Status LoadAssets(uint64_t loading_handle = 0);
412 absl::Status LoadAssetsForMode(uint64_t loading_handle = 0);
413 absl::Status LoadAssetsLazy(uint64_t loading_handle = 0);
414 absl::Status InitializeEditorForType(EditorType type, EditorSet* editor_set,
415 Rom* rom);
416 void ResetAssetState(RomSession* session);
417 void MarkEditorInitialized(RomSession* session, EditorType type);
418 void MarkEditorLoaded(RomSession* session, EditorType type);
419 Editor* GetEditorByType(EditorType type, EditorSet* editor_set) const;
420 Editor* ResolveEditorForCategory(const std::string& category);
421 void SyncEditorContextForCategory(const std::string& category);
422 bool EditorRequiresGameData(EditorType type) const;
423 bool EditorInitRequiresGameData(EditorType type) const;
424
425 // Testing system
429 // Returns a preferred startup category, skipping "Emulator" to prevent
430 // the emulator panel from auto-opening on project load.
431 std::string GetPreferredStartupCategory(
432 const std::string& saved_category,
433 const std::vector<std::string>& available_categories) const;
434
435 // Session event handlers (EventBus subscribers)
436 void HandleSessionSwitched(size_t new_index, RomSession* session);
437 void HandleSessionCreated(size_t index, RomSession* session);
438 void HandleSessionClosed(size_t index);
439 // Initialization helpers (extracted from constructor for readability)
440 void SubscribeToEvents();
442 void RegisterEditors();
444 void InitializeServices();
450 void ProcessInput();
451 void UpdateEditorState();
452 void DrawInterface();
454 void UpdateSystemUIs();
455 void RunEmulator();
456
457 void HandleSessionRomLoaded(size_t index, Rom* rom);
459
460 // UI action event handler (EventBus subscriber for UIActionRequestEvent)
462
463 bool quit_ = false;
464
465 // Note: All show_* flags are being moved to UICoordinator
466 // Access via ui_coordinator_->IsXxxVisible() or SetXxxVisible()
467
468 // Workspace dialog flags (managed by EditorManager, not UI)
472
473 // Note: Most UI visibility flags have been moved to UICoordinator
474 // Access via ui_coordinator_->IsXxxVisible() or SetXxxVisible()
475
476 // Agent proposal drawer
479
480 // Agent UI (chat + editor), no-op when agent UI is disabled
482
483 // Project file editor
485
486 // Note: Editor selection dialog and welcome screen are now managed by
487 // UICoordinator Kept here for backward compatibility during transition
488 std::unique_ptr<DashboardPanel> dashboard_panel_;
496
497 // Properties panel for selection editing
499
500 // Project management panel for version control and ROM management
501 std::unique_ptr<ProjectManagementPanel> project_management_panel_;
502
503 std::string version_ = "";
504 absl::Status status_;
506
507 public:
508 private:
510 // Tracks which session is currently active so delegators (menus, popups,
511 // shortcuts) stay in sync without relying on per-editor context.
512
514
516 std::unique_ptr<core::VersionManager> version_manager_;
518 std::unique_ptr<PopupManager> popup_manager_;
523
524 // New delegated components (dependency injection architecture)
525 PanelManager panel_manager_; // Panel management with session awareness
526 std::unique_ptr<PanelHost> panel_host_;
528 std::unique_ptr<MenuOrchestrator> menu_orchestrator_;
531 std::unique_ptr<UICoordinator> ui_coordinator_;
534 std::unique_ptr<SessionCoordinator> session_coordinator_;
535 std::unique_ptr<LayoutManager>
536 layout_manager_; // DockBuilder layout management
537 LayoutCoordinator layout_coordinator_; // Facade for layout operations
538 std::unique_ptr<RightPanelManager>
539 right_panel_manager_; // Right-side panel system
540 StatusBar status_bar_; // Bottom status bar
541 std::unique_ptr<ActivityBar> activity_bar_;
543
548 absl::Status CheckRomWritePolicy();
549 absl::Status CheckOracleRomSafetyPreSave(Rom* rom);
550
551 float autosave_timer_ = 0.0f;
552 bool settings_dirty_ = false;
555
556 // ROM lifecycle state (hash, write policy, confirmation dialogs, backups)
557 // Mutable because some const accessors delegate to it.
559
560 // Deferred action queue - executed at the start of each frame
561 std::vector<std::function<void()>> deferred_actions_;
563 std::atomic<uint64_t> ui_sync_frame_id_{0};
564
565 // Core Event Bus and Context
567 std::unique_ptr<GlobalEditorContext> editor_context_;
568
569#ifdef YAZE_WITH_GRPC
570 CanvasAutomationServiceImpl* canvas_automation_service_ = nullptr;
571#endif
572
573 // RAII helper for clean session context switching
575 public:
576 SessionScope(EditorManager* manager, size_t session_id);
578
579 private:
584 };
585
586 void ConfigureEditorDependencies(EditorSet* editor_set, Rom* rom,
587 size_t session_id);
589};
590
591} // namespace editor
592} // namespace yaze
593
594#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:28
static Flags & get()
Definition features.h:118
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_id)
The EditorManager controls the main editor window and manages the various editor classes.
std::unique_ptr< SessionCoordinator > session_coordinator_
std::unique_ptr< PanelHost > panel_host_
RomLifecycleManager rom_lifecycle_
void SaveWorkspacePreset(const std::string &name)
StartupVisibility welcome_mode_override_
PanelManager * GetPanelManager()
void SwitchToEditor(EditorType editor_type, bool force_visible=false, bool from_dialog=false) override
std::unique_ptr< GlobalEditorContext > editor_context_
auto GetCurrentGameData() const -> zelda3::GameData *
const PanelManager & card_registry() const
absl::Status SaveRomAs(const std::string &filename)
project::YazeProject current_project_
void SetCurrentEditor(Editor *editor) override
absl::Status LoadAssetsForMode(uint64_t loading_handle=0)
std::string GetPreferredStartupCategory(const std::string &saved_category, const std::vector< std::string > &available_categories) const
void SwitchToSession(size_t index)
absl::Status RestoreRomBackup(const std::string &backup_path)
bool HasPendingPotItemSaveConfirmation() const
Rom * GetCurrentRom() const override
bool HasDuplicateSession(const std::string &filepath)
WorkspaceManager * workspace_manager()
std::unique_ptr< LayoutManager > layout_manager_
std::unique_ptr< DashboardPanel > dashboard_panel_
void HandleSessionClosed(size_t index)
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)
std::vector< editor::RomFileManager::BackupEntry > GetRomBackups() const
absl::Status CheckRomWritePolicy()
Save the current ROM file.
SharedClipboard shared_clipboard_
bool EditorInitRequiresGameData(EditorType type) const
void SyncEditorContextForCategory(const std::string &category)
UICoordinator * ui_coordinator()
void ShowProjectManagement()
Injects dependencies into all editors within an EditorSet.
Editor * ResolveEditorForCategory(const std::string &category)
void Initialize(gfx::IRenderer *renderer, const std::string &filename="")
project::RomWritePolicy GetProjectRomWritePolicy() const
void MarkEditorLoaded(RomSession *session, EditorType type)
absl::Status CreateNewProject(const std::string &template_name="Basic ROM Hack")
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
auto GetCurrentEditorSet() const -> EditorSet *
const PanelManager & panel_manager() const
void SetFontGlobalScale(float scale)
std::unique_ptr< MenuOrchestrator > menu_orchestrator_
void HandleUIActionRequest(UIActionRequestEvent::Action action)
void ResolvePotItemSaveConfirmation(PotItemSaveDecision decision)
void HandleSessionRomLoaded(size_t index, Rom *rom)
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)
auto GetCurrentEditor() const -> Editor *
std::string GetProjectExpectedRomHash() const
void PersistInputConfig(const emu::input::InputConfig &config)
std::unique_ptr< RightPanelManager > right_panel_manager_
absl::Status LoadAssetsLazy(uint64_t loading_handle=0)
absl::Status DrawRomSelector()=delete
void SetAssetLoadMode(AssetLoadMode mode)
void DismissEditorSelection() override
const std::vector< core::WriteConflict > & pending_write_conflicts() const
std::atomic< uint64_t > ui_sync_frame_id_
const project::YazeProject * GetCurrentProject() const
bool ApplyLayoutProfile(const std::string &profile_id)
std::unique_ptr< core::VersionManager > version_manager_
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::function< void()> > deferred_actions_
void OpenEditorAndPanelsFromFlags(const std::string &editor_name, const std::string &panels_str)
project::RomRole GetProjectRomRole() const
StartupVisibility dashboard_mode_override_
static bool IsPanelBasedEditor(EditorType type)
absl::Status Update()
Main update loop for the editor application.
absl::Status ImportProject(const std::string &project_path)
AgentUiController * GetAgentUiController()
core::VersionManager * GetVersionManager()
AssetLoadMode asset_load_mode() const
project::YazeProject * GetCurrentProject()
void QueueDeferredAction(std::function< void()> action)
SelectionPropertiesPanel selection_properties_panel_
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
void MarkEditorInitialized(RomSession *session, EditorType type)
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
std::unique_ptr< ProjectManagementPanel > project_management_panel_
absl::Status OpenRomOrProject(const std::string &filename)
void RemoveSession(size_t index)
absl::Status CheckOracleRomSafetyPreSave(Rom *rom)
UiSyncState GetUiSyncStateSnapshot() const
void HandleSessionSwitched(size_t new_index, RomSession *session)
absl::Status EnsureEditorAssetsLoaded(EditorType type)
std::unique_ptr< PopupManager > popup_manager_
std::atomic< int > pending_editor_deferred_actions_
std::unique_ptr< UICoordinator > ui_coordinator_
EditorActivator editor_activator_
absl::Status SetCurrentRom(Rom *rom)
void HandleSessionCreated(size_t index, RomSession *session)
bool EditorRequiresGameData(EditorType type) const
RightPanelManager * right_panel_manager()
Manages editor types, categories, and lifecycle.
Contains a complete set of editors for a single ROM instance.
Interface for editor classes.
Definition editor.h:236
EditorType type() const
Definition editor.h:283
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 panels.
float GetLeftLayoutOffset() const
Get the left margin needed for sidebar (Activity Bar + Side Panel)
Fluent interface for building ImGui menus with icons.
Thin host API over PanelManager for declarative panel workflows.
Definition panel_host.h:43
Central registry for all editor cards with session awareness and dependency injection.
Editor for .yaze project files with syntax highlighting and validation.
Handles all project file operations with ROM-first workflow.
ImGui drawer for displaying and managing agent proposals.
Manages right-side sliding panels 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
ROM load options and ZSCustomOverworld upgrade dialog.
Full-editing properties panel for selected entities.
A session-aware status bar displayed at the bottom of the application.
Definition status_bar.h:39
Handles all UI drawing operations and state management.
Manages user preferences and settings persistence.
Modern welcome screen with project grid and quick actions.
Low-level window operations with minimal dependencies.
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="")
A class for emulating and debugging SNES games.
Definition emulator.h:40
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
Represents the full Overworld data, light and dark world.
Definition overworld.h:261
#define LOG_WARN(category, format,...)
Definition log.h:107
void SetCurrentEditor(Editor *editor)
Set the currently active editor.
Editors are the view controllers for the application.
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
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:107
RomWritePolicy write_policy
Definition project.h:108
Modern project structure with comprehensive settings consolidation.
Definition project.h:120