using Hi.Disp;
using Hi.Geom;
using Microsoft.AspNetCore.SignalR;
using Hi.Webapi.Hubs;
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; }
IHubContext HubContext { get; }
private bool disposedValue;
public RenderingService(ILogger logger, IHubContext hubContext)
{
Logger = logger;
HubContext = hubContext;
}
///
/// Get Or Create an DispEngine.
///
public DispEngine GetOrCreateEngine(string connectionId)
{
return EngineDictionary.GetOrAdd(connectionId, id =>
{
Logger.LogInformation($"Create new DispEngine,ConnectionId: {id}");
var engine = new DispEngine();
engine.BackgroundColor = new Vec3d(0.1, 0.1, 0.5);
engine.BackgroundOpacity = 0.1;
return engine;
});
}
///
/// Send image to specific client.
///
public async Task SendImageToClient(string connectionId, byte[] compressedData, int originalLength, int width, int height)
{
try
{
await HubContext.Clients.Client(connectionId).SendAsync("ImageUpdate",
compressedData, originalLength, width, height);
}
catch (Exception ex)
{
Logger.LogError(ex, $"Failed to send image to client: {connectionId}");
}
}
///
/// Remove DispEngine
///
public bool RemoveEngine(string connectionId)
{
if (EngineDictionary.TryRemove(connectionId, out var engine))
{
Logger.LogInformation($"Remove DispEngine,ConnectionId: {connectionId}");
try
{
engine.IsVisible = false;
engine.Dispose();
}
catch (Exception ex)
{
Logger.LogError(ex, $"清理 DispEngine 時發生錯誤,ConnectionId: {connectionId}");
}
return true;
}
return false;
}
///
/// Get Active Engine Count.
///
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 DispEngine Error,ConnectionId: {kvp.Key}");
}
}
EngineDictionary.Clear();
}
disposedValue = true;
}
}
///
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}