using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace io.github.hatayama.uLoopMCP { /// /// Model layer for McpEditorWindow in MVP architecture /// Handles state management and business logic using immutable state objects /// Related classes: /// - McpEditorWindowState: State objects managed by this model /// - McpEditorWindow: Presenter that uses this model /// - McpEditorWindowView: View layer for UI rendering /// - McpEditorSettings: Persistent settings storage /// public class McpEditorModel { public UIState UI { get; private set; } public RuntimeState Runtime { get; private set; } public McpEditorModel() { UI = new UIState(); Runtime = new RuntimeState(); } /// /// Update UI state with new values /// /// Function to update UI state public void UpdateUIState(Func updater) { UI = updater(UI); } /// /// Update runtime state with new values /// /// Function to update runtime state public void UpdateRuntimeState(Func updater) { Runtime = updater(Runtime); } /// /// Load state from persistent settings /// public void LoadFromSettings() { McpEditorSettingsData settings = McpEditorSettings.GetSettings(); UpdateUIState(ui => new UIState( customPort: settings.customPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: settings.showSecuritySettings, showToolSettings: settings.showToolSettings, addRepositoryRoot: settings.addRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: (ConnectionMode)settings.connectionMode, showConfiguration: ui.ShowConfiguration)); } /// /// Save current UI state to persistent settings /// public void SaveToSettings() { McpEditorSettings.SetCustomPort(UI.CustomPort); McpEditorSettings.SetConnectionMode(UI.ConnectionMode); } /// /// Load state from persistent settings (formerly from SessionState) /// public void LoadFromSessionState() { McpEditorType selectedEditor = McpEditorSettings.GetSelectedEditorType(); UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: selectedEditor, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); } /// /// Save current state to persistent settings (formerly to SessionState) /// public void SaveToSessionState() { McpEditorSettings.SetSelectedEditorType(UI.SelectedEditorType); } /// /// Initialize post-compile mode /// public void EnablePostCompileMode() { UpdateRuntimeState(runtime => new RuntimeState( isPostCompileMode: true, needsRepaint: true, lastServerRunning: runtime.LastServerRunning, lastServerPort: runtime.LastServerPort, lastConnectedClientsCount: runtime.LastConnectedClientsCount, lastClientsInfoHash: runtime.LastClientsInfoHash)); } /// /// Exit post-compile mode /// public void DisablePostCompileMode() { UpdateRuntimeState(runtime => new RuntimeState( isPostCompileMode: false, needsRepaint: runtime.NeedsRepaint, lastServerRunning: runtime.LastServerRunning, lastServerPort: runtime.LastServerPort, lastConnectedClientsCount: runtime.LastConnectedClientsCount, lastClientsInfoHash: runtime.LastClientsInfoHash)); } /// /// Mark that UI repaint is needed /// public void RequestRepaint() { UpdateRuntimeState(runtime => new RuntimeState( isPostCompileMode: runtime.IsPostCompileMode, needsRepaint: true, lastServerRunning: runtime.LastServerRunning, lastServerPort: runtime.LastServerPort, lastConnectedClientsCount: runtime.LastConnectedClientsCount, lastClientsInfoHash: runtime.LastClientsInfoHash)); } /// /// Clear repaint request /// public void ClearRepaintRequest() { UpdateRuntimeState(runtime => new RuntimeState( isPostCompileMode: runtime.IsPostCompileMode, needsRepaint: false, lastServerRunning: runtime.LastServerRunning, lastServerPort: runtime.LastServerPort, lastConnectedClientsCount: runtime.LastConnectedClientsCount, lastClientsInfoHash: runtime.LastClientsInfoHash)); } /// /// Update server state tracking for change detection /// public void UpdateServerStateTracking(bool isRunning, int port, int clientCount, string clientsHash) { UpdateRuntimeState(runtime => new RuntimeState( isPostCompileMode: runtime.IsPostCompileMode, needsRepaint: runtime.NeedsRepaint, lastServerRunning: isRunning, lastServerPort: port, lastConnectedClientsCount: clientCount, lastClientsInfoHash: clientsHash)); } // UIState-specific update methods with persistence /// /// Update CustomPort setting with persistence /// public void UpdateCustomPort(int port) { UpdateUIState(ui => new UIState( customPort: port, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetCustomPort(port); } /// /// Update ShowConnectedTools setting /// public void UpdateShowConnectedTools(bool show) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: show, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); } /// /// Update SelectedEditorType setting with persistence /// public void UpdateSelectedEditorType(McpEditorType type) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: type, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetSelectedEditorType(type); } /// /// Update MainScrollPosition setting /// public void UpdateMainScrollPosition(Vector2 position) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: position, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); } /// /// Update ShowSecuritySettings setting with persistence /// public void UpdateShowSecuritySettings(bool show) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: show, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetShowSecuritySettings(show); } public void UpdateShowToolSettings(bool show) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: show, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetShowToolSettings(show); } public void UpdateToolEnabled(string toolName, bool enabled) { ToolSettings.SetToolEnabled(toolName, enabled); } /// /// Update AllowThirdPartyTools setting with persistence /// public void UpdateAllowThirdPartyTools(bool allow) { ULoopSettings.SetAllowThirdPartyTools(allow); } /// /// Update AddRepositoryRoot setting with persistence /// public void UpdateAddRepositoryRoot(bool addRepositoryRoot) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: addRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetAddRepositoryRoot(addRepositoryRoot); UnityMcpPathResolver.InvalidateGitRootCache(); } /// /// Update SupportsRepositoryRootToggle flag /// public void UpdateSupportsRepositoryRootToggle(bool supportsToggle) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: supportsToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); } /// /// Update ShowRepositoryRootToggle flag /// public void UpdateShowRepositoryRootToggle(bool showToggle) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: showToggle, connectionMode: ui.ConnectionMode, showConfiguration: ui.ShowConfiguration)); } public void UpdateConnectionMode(ConnectionMode mode) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: mode, showConfiguration: ui.ShowConfiguration)); McpEditorSettings.SetConnectionMode(mode); } public void UpdateShowConfiguration(bool show) { UpdateUIState(ui => new UIState( customPort: ui.CustomPort, showConnectedTools: ui.ShowConnectedTools, selectedEditorType: ui.SelectedEditorType, mainScrollPosition: ui.MainScrollPosition, showSecuritySettings: ui.ShowSecuritySettings, showToolSettings: ui.ShowToolSettings, addRepositoryRoot: ui.AddRepositoryRoot, supportsRepositoryRootToggle: ui.SupportsRepositoryRootToggle, showRepositoryRootToggle: ui.ShowRepositoryRootToggle, connectionMode: ui.ConnectionMode, showConfiguration: show)); } } }