Make3.Renderer/Domain/RenderManager.cs
2025-06-28 03:00:25 +03:00

105 lines
3.2 KiB
C#

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<IFrameRender> _taskChannel;
private readonly ConcurrentDictionary<Guid, Render> _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<IFrameRender>(options);
}
// public Task<Guid> 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<Guid> StartRender(Project project)
public async Task<Guid> 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<IFrameRender>();
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<Guid> GetActiveRenders()
{
return new List<Guid>();
}
}