From ce2f13242d55adc44e73d3229cecafdfd3890796 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Sun, 29 Sep 2024 02:36:05 -0700 Subject: [PATCH] chore: restore backend & game server log panels --- Assets/Rivet/Editor/Task.cs | 17 +-- Assets/Rivet/Editor/TaskManager.cs | 104 ++++++++++++------ Assets/Rivet/Editor/UI/Dock/Dock.cs | 64 +++++------ .../Editor/UI/Dock/Tabs/DevelopController.cs | 9 +- .../Rivet/Editor/UI/Dock/Tabs/Settings.uxml | 2 +- .../Editor/UI/Dock/Tabs/SettingsController.cs | 37 +------ 6 files changed, 117 insertions(+), 116 deletions(-) diff --git a/Assets/Rivet/Editor/Task.cs b/Assets/Rivet/Editor/Task.cs index 3451c7c..cd0b6bc 100644 --- a/Assets/Rivet/Editor/Task.cs +++ b/Assets/Rivet/Editor/Task.cs @@ -39,26 +39,23 @@ public RivetTask(string name, JObject input) var inputJson = _input.ToString(Newtonsoft.Json.Formatting.None); - RivetLogger.Log($"[{_name}] Request: {inputJson}"); + RivetLogger.Log($"[{name}] Request: {inputJson}"); Task.Run(() => Run(name, inputJson)); } private void Run(string name, string inputJson) { _taskId = RivetToolchain.RunTask(name, inputJson, OnOutputEvent); - RivetLogger.Log($"task id {_taskId}"); } private void OnOutputEvent(ulong taskId, IntPtr eventJsonPtr) { string eventJson = RivetToolchain.PtrToString(eventJsonPtr); - RivetLogger.Log($"received event {eventJson}"); EditorApplication.delayCall += () => HandleOnOutputEvent(eventJson); } private void HandleOnOutputEvent(string eventJson) { - RivetLogger.Log($"output event {_taskId}"); var eventObj = JObject.Parse(eventJson); if (eventObj.ContainsKey("log")) { @@ -69,14 +66,20 @@ private void HandleOnOutputEvent(string eventJson) _logResult = eventObj["result"] as JObject; OnFinish(); } - else if (eventObj.ContainsKey("set_backend_port")) + else if (eventObj.ContainsKey("port_update")) { - var port = eventObj["set_backend_port"]["port"].Value(); + var backendPort = eventObj["port_update"]["backend_port"].Value(); + var editorPort = eventObj["port_update"]["editor_port"].Value(); // TODO: // Assuming you have a similar configuration saving mechanism // RivetPluginBridge.Instance.LocalBackendPort = port; // RivetPluginBridge.Instance.SaveConfiguration(); - RivetLogger.Log($"Set backend port {port}"); + RivetLogger.Log($"Set backend port {backendPort} {editorPort}"); + } + else if (eventObj.ContainsKey("backend_config_update")) + { + var updateEvent = eventObj["backend_config_update"].Value(); + // TODO: } else { diff --git a/Assets/Rivet/Editor/TaskManager.cs b/Assets/Rivet/Editor/TaskManager.cs index 38a3399..2ce58b5 100644 --- a/Assets/Rivet/Editor/TaskManager.cs +++ b/Assets/Rivet/Editor/TaskManager.cs @@ -37,59 +37,58 @@ public LogEntry(string message, LogType type) } } - public delegate Task GetTaskConfigDelegate(); + public delegate Task GetStartConfigDelegate(); + public delegate Task GetStopConfigDelegate(); public delegate TaskPanelWindow? GetTaskPanelDelegate(); public delegate void StateChangeHandler(bool running); // Config - private GetTaskConfigDelegate _getTaskConfig; + private GetStartConfigDelegate _getStartConfig; + private GetStopConfigDelegate _getStopConfig; private GetTaskPanelDelegate _getTaskPanel; private bool _autoRestart = false; - private bool _taskStopping = false; // Events public event StateChangeHandler StateChange; // State private readonly object _taskLock = new(); - private RivetTask _task; + private RivetTask? _task; + private RivetTask? _stopTask; public List LogEntries = new(); - public TaskManager(string initMessage, GetTaskConfigDelegate getTaskConfig, GetTaskPanelDelegate getTaskPanel, bool autoRestart = false) + public TaskManager(string initMessage, GetStartConfigDelegate getStartConfig, GetStopConfigDelegate getStopConfig, GetTaskPanelDelegate getTaskPanel, bool autoRestart = false) { - _getTaskConfig = getTaskConfig; + _getStartConfig = getStartConfig; + _getStopConfig = getStopConfig; _getTaskPanel = getTaskPanel; _autoRestart = autoRestart; LogEntries.Add(new LogEntry(initMessage, LogType.META)); } - public async Task StartTask(bool restart = true) + public async Task StartTask() { lock (_taskLock) { - // Do nothing if already stopping another task - if (_taskStopping) - return; - // Do nothing if task already running - if (!restart && _task != null) + if (_task != null || _stopTask != null) return; } // Kill old task StopTask(); - // Start task - var config = await _getTaskConfig(); + // Start new task + var config = await _getStartConfig(); if (config == null) { RivetLogger.Log("No task config provided."); + return; } lock (_taskLock) { _task = new RivetTask(config.Value.Name, config.Value.Input); - _taskStopping = false; _task.TaskLog += OnTaskLog; OnStateChange(); } @@ -98,8 +97,19 @@ public async Task StartTask(bool restart = true) // Run task var output = await _task.RunAsync(); + + await OnTaskOutput(output, _task); + } + + private async Task OnTaskOutput(Result output, RivetTask sourceTask) + { lock (_taskLock) { + if (_task != sourceTask) + { + return; + } + _task = null; OnStateChange(); } @@ -115,32 +125,62 @@ public async Task StartTask(bool restart = true) break; } - // TODO: Re-enable task restarting - // // Restart if task was not stopped - // bool shouldRestart; - // lock (_taskLock) shouldRestart = _autoRestart && _task == null && !_taskStopping; - // if (shouldRestart) - // { - // AddLogLine("Restarting in 2 seconds", LogType.META); - // await Task.Delay(2000); - // await StartTask(); - // } + // Restart if task was not stopped + if (_autoRestart) + { + AddLogLine("Restarting in 2 seconds", LogType.META); + await Task.Delay(2000); + await StartTask(); + } + } - public void StopTask() + public async Task StopTask() { + bool shouldStop; lock (_taskLock) { - if (_task != null) - { - _taskStopping = true; - _task.Kill(); - _task = null; + shouldStop = _task != null && _stopTask == null; + } + + if (shouldStop) + { + // Abort running task + var localTask = _task; + _task = null; + localTask.Kill(); - AddLogLine("Stop", LogType.META); + AddLogLine("Stopping", LogType.META); + // Run stop task + // + // Save in global scope so it doesn't get dropped before getting called + var config = await _getStopConfig(); + if (config == null) + { + RivetLogger.Log("No task config provided."); + return; + } + lock (_taskLock) + { + _stopTask = new RivetTask(config.Value.Name, config.Value.Input); OnStateChange(); } + + await _stopTask.RunAsync(); + + OnStopFinish(); + } + } + + private void OnStopFinish() + { + AddLogLine("Stopped", LogType.META); + + lock (_taskLock) + { + _stopTask = null; + OnStateChange(); } } diff --git a/Assets/Rivet/Editor/UI/Dock/Dock.cs b/Assets/Rivet/Editor/UI/Dock/Dock.cs index ec1e787..0f00ecf 100644 --- a/Assets/Rivet/Editor/UI/Dock/Dock.cs +++ b/Assets/Rivet/Editor/UI/Dock/Dock.cs @@ -30,8 +30,10 @@ public class Dock : EditorWindow [SerializeField] private VisualTreeAsset m_VisualTreeAsset; - private VisualElement _root { - get { + private VisualElement _root + { + get + { return rootVisualElement; } } @@ -204,13 +206,13 @@ public void OnEnable() // Task managers LocalGameServerManager = new( initMessage: "Open \"Develop\" and press \"Start\" to start game server.", - getTaskConfig: async () => + getStartConfig: async () => { if (LocalGameServerExecutablePath != null) { return new TaskConfig { - Name = "exec_command", + Name = "game_server.start", Input = new JObject { ["cwd"] = Builder.ProjectRoot(), @@ -224,55 +226,54 @@ public void OnEnable() return null; } }, + getStopConfig: async () => + { + return new TaskConfig + { + Name = "game_server.stop", + Input = new JObject { } + }; + }, getTaskPanel: () => GameServerWindow.GetWindowIfExists() ); BackendManager = new( initMessage: "Auto-started by Rivet plugin.", - getTaskConfig: async () => + getStartConfig: async () => { - // Choose port to run on. This is to avoid potential conflicts with - // multiple projects running at the same time. - var chooseRes = await new RivetTask("backend_choose_local_port", new JObject()).RunAsync(); - int port; - switch (chooseRes) - { - case ResultOk ok: - port = (int)ok.Data["port"]; - LocalBackendPort = port; - break; - case ResultErr err: - RivetLogger.Error($"Failed to choose port: {err}"); - return null; - default: - return null; - } - - return new TaskConfig { - Name = "backend_dev", + Name = "backend.start", Input = new JObject { - ["port"] = port, ["cwd"] = Builder.ProjectRoot(), } }; }, + getStopConfig: async () => + { + return new TaskConfig + { + Name = "backend.stop", + Input = new JObject { } + }; + }, getTaskPanel: () => BackendWindow.GetWindowIfExists(), autoRestart: true ); // Shut down on reload - AssemblyReloadEvents.beforeAssemblyReload += () => { + AssemblyReloadEvents.beforeAssemblyReload += () => + { RivetLogger.Log("Before Assembly Reload"); ShutdownPlugin(); }; - // // Start backend - // _ = BackendManager.StartTask(); - + // Bootstrap + _ = GetBootstrapData(); + // Start backend + // _ = BackendManager.StartTask(); } public void OnDisable() @@ -292,11 +293,6 @@ private void ShutdownPlugin() BackendManager.StopTask(); } - public void OnShow() { - // Fetch data - _ = GetBootstrapData(); - } - void SetTab(MainTab tab) { _tab = tab; diff --git a/Assets/Rivet/Editor/UI/Dock/Tabs/DevelopController.cs b/Assets/Rivet/Editor/UI/Dock/Tabs/DevelopController.cs index 45f96d2..9fe5740 100644 --- a/Assets/Rivet/Editor/UI/Dock/Tabs/DevelopController.cs +++ b/Assets/Rivet/Editor/UI/Dock/Tabs/DevelopController.cs @@ -149,14 +149,7 @@ private void OnLocalGameServerStart() _dock.LocalGameServerExecutablePath = serverPath; - // _ = _dock.LocalGameServerManager.StartTask(); - - // _ = new RivetTask("show_term", new JObject - // { - // ["command"] = _dock.LocalGameServerExecutablePath, - // // ["args"] = new JArray { "-batchmode", "-nographics", "-logFile", logPath, "-server" }, - // ["args"] = new JArray { "-batchmode", "-nographics", "-server" }, - // }).RunAsync(); + _ = _dock.LocalGameServerManager.StartTask(); } private void OnPlayerStart() diff --git a/Assets/Rivet/Editor/UI/Dock/Tabs/Settings.uxml b/Assets/Rivet/Editor/UI/Dock/Tabs/Settings.uxml index a075a79..8bb4d4e 100644 --- a/Assets/Rivet/Editor/UI/Dock/Tabs/Settings.uxml +++ b/Assets/Rivet/Editor/UI/Dock/Tabs/Settings.uxml @@ -30,7 +30,7 @@ - + diff --git a/Assets/Rivet/Editor/UI/Dock/Tabs/SettingsController.cs b/Assets/Rivet/Editor/UI/Dock/Tabs/SettingsController.cs index 63c6ee2..a4f5ff9 100644 --- a/Assets/Rivet/Editor/UI/Dock/Tabs/SettingsController.cs +++ b/Assets/Rivet/Editor/UI/Dock/Tabs/SettingsController.cs @@ -59,10 +59,9 @@ void InitUI() _root.Q("AccountBody").Q("SignOutButton").RegisterCallback(ev => { _ = OnUnlinkGame(); }); - // _backendStart.RegisterCallback(ev => { _ = _dock.BackendManager.StartTask(); }); - // _backendStop.RegisterCallback(ev => _dock.BackendManager.StopTask()); - // _backendRestart.RegisterCallback(ev => { _ = _dock.BackendManager.StartTask(); }); - _backendStart.RegisterCallback(ev => { _ = OnStartBackend(); }); // TODO: Remove + _backendStart.RegisterCallback(ev => { _ = _dock.BackendManager.StartTask(); }); + _backendStop.RegisterCallback(ev => _dock.BackendManager.StopTask()); + _backendRestart.RegisterCallback(ev => { _ = _dock.BackendManager.StartTask(); }); _backendShowLogs.RegisterCallback(ev => BackendWindow.ShowBackend()); // Update callbacks @@ -70,36 +69,6 @@ void InitUI() _editProjectButton.RegisterCallback(ev => { _ = OnEditSettings(SettingsType.Project); }); } - private async Task OnStartBackend() - { - // Choose port to run on. This is to avoid potential conflicts with - // multiple projects running at the same time. - var chooseRes = await new RivetTask("backend_choose_local_port", new JObject()).RunAsync(); - int port; - switch (chooseRes) - { - case ResultOk ok: - port = (int)ok.Data["port"]; - Dock.Singleton.LocalBackendPort = port; - break; - case ResultErr err: - RivetLogger.Error($"Failed to choose port: {err}"); - return; - default: - return; - } - - // var input = new JObject { - // ["port"] = port, - // ["cwd"] = Builder.ProjectRoot() - // }; - // await new RivetTask("show_term", new JObject - // { - // ["command"] = RivetTask.GetRivetCLIPath(), - // ["args"] = new JArray { "task", "run", "--run-config", "{}", "--name", "backend_dev", "--input", input.ToString(Formatting.None) }, - // }).RunAsync(); - } - private async Task OnUnlinkGame() { await new RivetTask("unlink", new JObject()).RunAsync();