From 2ce8d3e96613921b3787b2dc3cba5065146e02c1 Mon Sep 17 00:00:00 2001 From: Alek-ban Date: Fri, 16 Jan 2026 14:17:19 +0300 Subject: [PATCH] feat: AvaloniaUi GSS2.Test --- GSS2.Core/DependencyInjectionHelper.cs | 4 +- GSS2.Core/GSS2.Core.csproj | 2 +- GSS2.Test/App.axaml | 8 +++ GSS2.Test/App.axaml.cs | 83 ++++++++++++++++++++++++++ GSS2.Test/GSS2.Test.csproj | 13 ++++ GSS2.Test/MainWindow.axaml | 9 +++ GSS2.Test/MainWindow.axaml.cs | 60 +++++++++++++++++++ GSS2.Test/Program.cs | 47 ++++----------- GSS2.Test/Worker.cs | 4 +- GSS2.Test/app.manifest | 18 ++++++ GSS2.Test/appsettings.json | 2 +- 11 files changed, 210 insertions(+), 40 deletions(-) create mode 100644 GSS2.Test/App.axaml create mode 100644 GSS2.Test/App.axaml.cs create mode 100644 GSS2.Test/MainWindow.axaml create mode 100644 GSS2.Test/MainWindow.axaml.cs create mode 100644 GSS2.Test/app.manifest diff --git a/GSS2.Core/DependencyInjectionHelper.cs b/GSS2.Core/DependencyInjectionHelper.cs index 0557714..f1765ff 100644 --- a/GSS2.Core/DependencyInjectionHelper.cs +++ b/GSS2.Core/DependencyInjectionHelper.cs @@ -58,7 +58,7 @@ public static class DependencyInjectionHelper return new IlluminatorService(logger, serviceConfiguration); } ); - public static IServiceCollection AddCameraService(this IServiceCollection services, string section) => services + public static IServiceCollection AddCameraService(this IServiceCollection services, string section, bool autoInitialize = false) => services .AddSingleton( serviceProvider => { @@ -71,7 +71,7 @@ public static class DependencyInjectionHelper var logger = serviceProvider.GetService>(); if (logger is null) throw new Exception("Cannot get logger"); - return new CameraService(logger, serviceConfiguration); + return new CameraService(logger, serviceConfiguration, autoInitialize); } ); diff --git a/GSS2.Core/GSS2.Core.csproj b/GSS2.Core/GSS2.Core.csproj index 02da2a2..f11cb3f 100644 --- a/GSS2.Core/GSS2.Core.csproj +++ b/GSS2.Core/GSS2.Core.csproj @@ -21,7 +21,7 @@ - + diff --git a/GSS2.Test/App.axaml b/GSS2.Test/App.axaml new file mode 100644 index 0000000..a972279 --- /dev/null +++ b/GSS2.Test/App.axaml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/GSS2.Test/App.axaml.cs b/GSS2.Test/App.axaml.cs new file mode 100644 index 0000000..27ecadd --- /dev/null +++ b/GSS2.Test/App.axaml.cs @@ -0,0 +1,83 @@ +using System.Drawing; + +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +using GSS2.Core; +using GSS2.Core.Analysis.AmineContent.Database; +using GSS2.Core.Hardware; + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Console; + +namespace GSS2.Test; + +public partial class App : Application +{ + private readonly IHost _host = BuildHostApp(); + + public override void Initialize() + { + _host.Start(); + AvaloniaXamlLoader.Load(this); + } + + private static IHost BuildHostApp() + { + var builder = Host.CreateApplicationBuilder(); + + builder.Logging.ClearProviders(); + builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter)); + builder.Logging.AddConsoleFormatter(); + builder.Logging.AddProvider(new FileLoggerProvider("app.log")); + builder.Services.AddSingleton(); + + builder.Services.AddAmineContentCalibrationContext(builder.Configuration); + builder.Services.AddAmineContentResultsContext(builder.Configuration); + + builder.Services.AddLightsService("Hardware:Lights"); + builder.Services.AddTemperatureHumidityService("Hardware:TemperatureHumidity"); + builder.Services.AddIlluminatorService("Hardware:Illuminator"); + builder.Services.AddCameraService("Hardware:Camera", true); + + var host = builder.Build(); + host.Services.GetRequiredService(); + + using (var scope = host.Services.CreateScope()) + { + var context = scope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); + } + using (var scope = host.Services.CreateScope()) + { + var context = scope.ServiceProvider.GetRequiredService(); + context.Database.Migrate(); + } + + return host; + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + var lightsService = _host.Services.GetRequiredService(); + _ = lightsService.Run(CancellationToken.None); + _ = lightsService.SnowfallAsync(0.3, 1, Color.Aqua); + + var cameraService = _host.Services.GetRequiredService(); + var illuminatorService = _host.Services.GetRequiredService(); + + desktop.MainWindow = new MainWindow(cameraService, illuminatorService, lightsService); + desktop.MainWindow.Closed += async (_, _) => + { + await lightsService.DisconnectAsync(); + await _host.StopAsync(); + _host.Dispose(); + }; + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/GSS2.Test/GSS2.Test.csproj b/GSS2.Test/GSS2.Test.csproj index ae3debe..b91816d 100644 --- a/GSS2.Test/GSS2.Test.csproj +++ b/GSS2.Test/GSS2.Test.csproj @@ -1,14 +1,27 @@ + WinExe net10.0 enable enable dotnet-GSS2.Test-191ece0a-855d-46ec-9ecb-44378fc3db83 + app.manifest + true + + + + + + + + None + All + diff --git a/GSS2.Test/MainWindow.axaml b/GSS2.Test/MainWindow.axaml new file mode 100644 index 0000000..64b4513 --- /dev/null +++ b/GSS2.Test/MainWindow.axaml @@ -0,0 +1,9 @@ + + + diff --git a/GSS2.Test/MainWindow.axaml.cs b/GSS2.Test/MainWindow.axaml.cs new file mode 100644 index 0000000..914970f --- /dev/null +++ b/GSS2.Test/MainWindow.axaml.cs @@ -0,0 +1,60 @@ +using Avalonia.Controls; +using Avalonia.Media.Imaging; + +using GSS2.Core.Hardware; + +namespace GSS2.Test; + +public partial class MainWindow : Window +{ + private readonly CameraService _cameraService; + private readonly IlluminatorService _illuminatorService; + private readonly LightsService _lightsService; + + public MainWindow(CameraService cameraService, IlluminatorService illuminatorService, LightsService lightsService) + { + _cameraService = cameraService; + _illuminatorService = illuminatorService; + _lightsService = lightsService; + + InitializeComponent(); + + PointerPressed += async (_, _) => + { + _lightsService.CpuLoad(0.5, 1, System.Drawing.Color.Aqua); + + try + { + _illuminatorService.SetIntensity(0.01, 0, 0); + _illuminatorService.TurnOn(); + using var img = await _cameraService.CaptureImage(CancellationToken.None, 5); + + if (img is not null) + { + var bytes = img.ToBytes(".png"); + using var stream = new MemoryStream(bytes); + image.Source = new Bitmap(stream); + } + + _lightsService.Flash(0.5, 2, System.Drawing.Color.Green); + } + catch + { + _lightsService.Flash(0.5, 2, System.Drawing.Color.Red); + } + finally + { + _illuminatorService.TurnOff(); + } + + var snowfallTimer = new System.Timers.Timer(3000); + snowfallTimer.Elapsed += (_, _) => + { + lightsService.Snowfall(0.3, 1, System.Drawing.Color.Aqua); + snowfallTimer.Dispose(); + }; + snowfallTimer.Start(); + + }; + } +} \ No newline at end of file diff --git a/GSS2.Test/Program.cs b/GSS2.Test/Program.cs index ed0215e..59a916c 100644 --- a/GSS2.Test/Program.cs +++ b/GSS2.Test/Program.cs @@ -1,46 +1,25 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Console; using GSS2.Core; using GSS2.Core.Analysis.AmineContent.Database; -using Microsoft.Extensions.Logging.Console; + +using Avalonia; namespace GSS2.Test; public class Program { + [STAThread] public static void Main(string[] args) { - var builder = Host.CreateApplicationBuilder(args); - - builder.Logging.ClearProviders(); - builder.Logging.AddConsole(options => options.FormatterName = nameof(ConsoleFormatter)); - builder.Logging.AddConsoleFormatter(); - builder.Logging.AddProvider(new FileLoggerProvider("app.log")); - builder.Services.AddSingleton(); - - builder.Services.AddAmineContentCalibrationContext(builder.Configuration); - builder.Services.AddAmineContentResultsContext(builder.Configuration); - - builder.Services.AddLightsService("Hardware:Lights"); - builder.Services.AddTemperatureHumidityService("Hardware:TemperatureHumidity"); - builder.Services.AddIlluminatorService("Hardware:Illuminator"); - builder.Services.AddCameraService("Hardware:Camera"); - - builder.Services.AddHostedService(); - - var host = builder.Build(); - host.Services.GetRequiredService(); - - using (var scope = host.Services.CreateScope()) - { - var context = scope.ServiceProvider.GetRequiredService(); - context.Database.Migrate(); - } - using (var scope = host.Services.CreateScope()) - { - var context = scope.ServiceProvider.GetRequiredService(); - context.Database.Migrate(); - } - - host.Run(); + BuildAvaloniaApp() + .UseStandardRuntimePlatformSubsystem() + .StartWithClassicDesktopLifetime(args); } + + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); } diff --git a/GSS2.Test/Worker.cs b/GSS2.Test/Worker.cs index 136d17a..f2ab8db 100644 --- a/GSS2.Test/Worker.cs +++ b/GSS2.Test/Worker.cs @@ -29,12 +29,12 @@ public class Worker( _ = _lightsService.Run(cancellationToken); _ = _lightsService.SnowfallAsync(0.3, 1, Color.Aqua, cancellationToken); - _illuminatorService.SetIntensity(0.5, 0, 0); + _illuminatorService.SetIntensity(0.01, 0, 0); _illuminatorService.TurnOn(); await Task.Delay(1000); - var img = await _cameraService.CaptureImage(cancellationToken); + var img = await _cameraService.CaptureImage(cancellationToken, 50); img?.SaveImage("IMAGE.png"); await Task.Delay(1000); diff --git a/GSS2.Test/app.manifest b/GSS2.Test/app.manifest new file mode 100644 index 0000000..eca2788 --- /dev/null +++ b/GSS2.Test/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/GSS2.Test/appsettings.json b/GSS2.Test/appsettings.json index 26fa27e..d85a5d0 100644 --- a/GSS2.Test/appsettings.json +++ b/GSS2.Test/appsettings.json @@ -40,7 +40,7 @@ "ViewFinderWidth": 1920, "ViewFinderHeight": 1080, "ViewFinderFps": 30, - "ImageCaptureFrameBufferCount": 2, + "ImageCaptureFrameBufferCount": 5, "ImageCaptureWidth": 4056, "ImageCaptureHeight": 3040 },