using Hi.Disp; using Hi.Geom; using Hi.Native; using System.Collections.Concurrent; namespace Hi.Webapi.Services { /// /// Singleton Service for managing . /// public class RenderingService : IDisposable { /// /// Engine Dictionary. /// Key is sessionID. /// public ConcurrentDictionary EngineDictionary { get; } = new(); ILogger Logger { get; } private bool disposedValue; public RenderingService(ILogger logger) { Logger = logger; } /// /// 創建或獲取一個 DispEngine 實例 /// public DispEngine GetOrCreateEngine(string sessionId) { return EngineDictionary.GetOrAdd(sessionId, id => { Logger.LogInformation($"創建新的 DispEngine,SessionId: {id}"); var engine = new DispEngine(); engine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5); engine.BackgroundOpacity = 0.1; return engine; }); } /// /// 移除指定的 DispEngine /// public bool RemoveEngine(string sessionId) { if (EngineDictionary.TryRemove(sessionId, out var engine)) { Logger.LogInformation($"移除 DispEngine,SessionId: {sessionId}"); try { // 停止渲染 engine.IsVisible = false; // 釋放資源 engine.Dispose(); } catch (Exception ex) { Logger.LogError(ex, $"清理 DispEngine 時發生錯誤,SessionId: {sessionId}"); } return true; } return false; } /// /// 獲取當前活動的引擎數量 /// public int GetActiveEngineCount() => EngineDictionary.Count; /// protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { foreach (var kvp in EngineDictionary) { try { kvp.Value.IsVisible = false; kvp.Value.Dispose(); } catch (Exception ex) { Logger.LogError(ex, $"Dispose 時清理引擎錯誤,SessionId: {kvp.Key}"); } } EngineDictionary.Clear(); } disposedValue = true; } } /// public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } }