using System; using System.Collections.Generic; using Nebula.Launcher.Models; using Nebula.Launcher.ProcessHelper; using Nebula.Launcher.ViewModels; using Nebula.Shared; using Nebula.Shared.Services; namespace Nebula.Launcher.Services; [ServiceRegister] public sealed class InstanceRunningContainer(PopupMessageService popupMessageService, DebugService debugService) { private readonly InstanceKeyPool _keyPool = new(); private readonly Dictionary _processCache = new(); private readonly Dictionary _contentLoggerCache = new(); private readonly Dictionary _keyCache = new(); public Action? IsRunningChanged; public InstanceKey RegisterInstance(IProcessStartInfoProvider provider) { var id = _keyPool.Take(); var currentContentLogConsumer = new ContentLogConsumer(); var logBridge = new DebugLoggerBridge(debugService.GetLogger("PROCESS_"+id.Id)); var logContainer = new ProcessLogConsumerCollection(); logContainer.RegisterLogger(currentContentLogConsumer); logContainer.RegisterLogger(logBridge); var handler = new ProcessRunHandler(provider, logContainer); handler.OnProcessExited += OnProcessExited; _processCache[id] = handler; _contentLoggerCache[id] = currentContentLogConsumer; _keyCache[handler] = id; return id; } public void Popup(InstanceKey instanceKey) { if(!_contentLoggerCache.TryGetValue(instanceKey, out var handler)) return; handler.Popup(popupMessageService); } public void Run(InstanceKey instanceKey) { if(!_processCache.TryGetValue(instanceKey, out var process)) return; process.Start(); IsRunningChanged?.Invoke(instanceKey, true); } public void Stop(InstanceKey instanceKey) { if(!_processCache.TryGetValue(instanceKey, out var process)) return; process.Stop(); } public bool IsRunning(InstanceKey instanceKey) { return _processCache.ContainsKey(instanceKey); } private void RemoveProcess(ProcessRunHandler handler) { if(handler.Disposed) return; var key = _keyCache[handler]; IsRunningChanged?.Invoke(key, false); _processCache.Remove(key); _keyCache.Remove(handler); _contentLoggerCache.Remove(key); } private void OnProcessExited(ProcessRunHandler obj) { obj.OnProcessExited -= OnProcessExited; RemoveProcess(obj); } }