using System.Collections.Concurrent; using System.Threading.Channels; using Domain.Interfaces; //using Make3.CommonTypes.BinaryMask; using Make3.CommonTypes.Interfaces.Matrices; namespace Domain; public class RenderManager : IRenderManager { private readonly Channel _taskChannel; private readonly ConcurrentDictionary _renders = []; //private readonly BinaryMaskFactory _binaryMaskFactory; private IMatrixAbstractFactory _binaryMaskFactory; public RenderManager(IMatrixAbstractFactory binaryMaskFactory, int channelCapacity = 5) { _binaryMaskFactory = binaryMaskFactory; var options = new BoundedChannelOptions(channelCapacity) { FullMode = BoundedChannelFullMode.Wait // Ожидание при переполнении канала }; _taskChannel = Channel.CreateBounded(options); } // public Task StartRender(Project project) // { // var render = new Render(project); // if (_renders.TryAdd(render.Id, render)) // { // _ =render.Run(_taskChannel); // } // _ = ProcessQueue(); // return Task.FromResult(render.Id); // } // public Task StartRender(Project project) public async Task StartRender(Project.Project project) { var render = new Render(project, _binaryMaskFactory); if (_renders.TryAdd(render.Id, render)) { await render.Run(_taskChannel); } _ = ProcessQueue(); return render.Id; } private async Task ProcessQueue(CancellationToken cancellationToken = default) { while (await _taskChannel.Reader.WaitToReadAsync(cancellationToken)) { while (_taskChannel.Reader.TryRead(out var task)) { try { await task.Execute(cancellationToken); } catch (OperationCanceledException) { // Console.WriteLine($"Task {task.RenderId} was cancelled."); } } } } public async Task StopRender(Guid renderId) { if (_renders.TryRemove(renderId, out var render)) { await render.Stop(); UpdateProjectHistoryToHistory(render.ProjectId, render.Id); } } private async Task ClearTasksForRender(Guid renderId) { var remainingTasks = new List(); while (await _taskChannel.Reader.WaitToReadAsync()) { if (_taskChannel.Reader.TryRead(out var task)) { // if (task.RenderId != renderId) // { // remainingTasks.Add(task); // } } } foreach (var task in remainingTasks) { await _taskChannel.Writer.WriteAsync(task); } } private void UpdateProjectHistoryToHistory(Guid projectId, Guid renderId) { Console.WriteLine($"UpdateProjectHistoryToHistory: {projectId}, {renderId}"); } public IEnumerable GetActiveRenders() { return new List(); } }