MrBot.Net/MRBot/Services/WindowManagerService.cs
2023-12-08 15:20:12 -06:00

85 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using LavishScriptAPI;
using LavishVMAPI;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MRBot.UI;
namespace MRBot.Services;
internal sealed class WindowManagerService : BackgroundService
{
private readonly IHostApplicationLifetime _applicationLifetime;
private readonly ILogger<WindowManagerService> _logger;
private readonly List<IWindow> _activeWindows = new();
private readonly List<IWindow> _inactiveWindows;
public WindowManagerService(IEnumerable<IWindow> windows, IHostApplicationLifetime applicationLifetime, ILogger<WindowManagerService> logger)
{
_applicationLifetime = applicationLifetime;
_logger = logger;
_inactiveWindows = windows.ToList();
}
private void RemoveWindow(object sender, LSEventArgs args)
{
var window = sender as IWindow;
if(window == null) return;
_activeWindows.Remove(window);
_inactiveWindows.Add(window);
window.Hide();
window?.Dispose();
if (_activeWindows.Count == 0)
{
_applicationLifetime.StopApplication();
}
}
private void OpenWindow(string windowName)
{
var window = _inactiveWindows.FirstOrDefault(w => w.Name == windowName);
if (window == null) return;
_inactiveWindows.Remove(window);
_activeWindows.Add(window);
window.Show();
window.OnWindowClose += RemoveWindow;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting window manager");
return base.StartAsync(cancellationToken);
}
private void ServiceLoopAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Thread.Sleep(500);
Frame.Wait(false);
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
OpenWindow(WindowNames.MainWindow);
await Task.Factory.StartNew(() =>
{
ServiceLoopAsync(stoppingToken);
}, stoppingToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
public override void Dispose()
{
foreach (var window in _activeWindows)
{
window.OnWindowClose -= RemoveWindow;
window.Dispose();
}
base.Dispose();
}
}