forked from amkovkov/GranuSightSoftware2
feat: MainView
This commit is contained in:
+128
-2
@@ -1,5 +1,17 @@
|
||||
using System.CommandLine;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.OpenGL.Egl;
|
||||
|
||||
using GSS2.Core.Logging;
|
||||
using GSS2.Core;
|
||||
using GSS2.Core.Analysis.AmineContent.Database.Calibration;
|
||||
using GSS2.Core.Analysis.AmineContent.Database.Results;
|
||||
|
||||
namespace GSS2.Commands;
|
||||
|
||||
public static class UI
|
||||
@@ -31,7 +43,6 @@ public static class UI
|
||||
RenderingMode = new("--mode", ["--rendering-mode", "-m"])
|
||||
{
|
||||
Description = "Режим рендеринга",
|
||||
|
||||
DefaultValueFactory = (_) => RenderingModes.X11
|
||||
};
|
||||
HideConsole = new("--hide-console", ["--no-console", "-c"])
|
||||
@@ -53,7 +64,6 @@ public static class UI
|
||||
Command.Add(RenderingMode);
|
||||
Command.Add(HideConsole);
|
||||
Command.SetAction(CommandAction);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -69,6 +79,122 @@ public static class UI
|
||||
|
||||
private static void CommandAction(ParseResult result)
|
||||
{
|
||||
/// Получаем значения аргументов командной строки
|
||||
var fullscreen = result.GetValue(Fullscreen);
|
||||
var renderingMode = result.GetValue(RenderingMode);
|
||||
var hideConsole = result.GetValue(HideConsole);
|
||||
|
||||
// Если выбран режим рендеринга DRM, то приложение будет рисоваться вместе с консолью,
|
||||
// поэтому если не перехватить консоль, то вывод в неё будет рисоваться вместе с интерфейсом
|
||||
if (hideConsole)
|
||||
SilenceConsole();
|
||||
|
||||
// Собираем хост
|
||||
var host = BuildHost();
|
||||
|
||||
// Запускаем хост асинхронно без блокировки потока
|
||||
_ = host.RunAsync();
|
||||
|
||||
// Собираем графическое приложение
|
||||
var ui = BuildApplication(host, fullscreen);
|
||||
switch (renderingMode)
|
||||
{
|
||||
case RenderingModes.X11:
|
||||
// Если мы запускаемся под X11,
|
||||
// то очевидно у нас есть полноценный рабочий стол,
|
||||
// поэтому запускаем графический интерфейс в классическом режиме с главным окном
|
||||
ui.StartWithClassicDesktopLifetime(Program.Args);
|
||||
break;
|
||||
case RenderingModes.DRM:
|
||||
// Если мы запускаемся в DRM (Direct Rendering Mode),
|
||||
// то у нас нет рабочего стола и окон,
|
||||
// потому что отрисовка (вроде как) идёт напрямую в кадровый буфер,
|
||||
// поэтому запускаем графический интерфейс в DRM.
|
||||
// Если работает X11, или любая другая графическая система,
|
||||
// то запустить приложение в DRM не получится,
|
||||
// потому что DRI (Direct Rendering Interface) занят этой графической системой
|
||||
// TODO: Подумать над тем, чтобы брать DRI и scale для DRM рендеринга из переменных среды
|
||||
// TODO: Подумать над тем, чтобы при запуске в DRM убивать приложения, которые занимают DRI
|
||||
ui.StartLinuxDrm(Program.Args, "/dev/dri/card1", 1.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SilenceConsole()
|
||||
{
|
||||
var start = new ThreadStart(() =>
|
||||
{
|
||||
Console.CursorVisible = false;
|
||||
while (true)
|
||||
Console.ReadKey(true);
|
||||
});
|
||||
var thread = new Thread(start)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
private static IHost BuildHost()
|
||||
{
|
||||
// Создаём хост
|
||||
var builder = Host.CreateApplicationBuilder();
|
||||
|
||||
// Добавляем конфигурацию из appsettings.json
|
||||
builder.Configuration.AddAppSettingsJson();
|
||||
|
||||
// Конфигурируем логгер
|
||||
builder.Logging.ConfigureLogging();
|
||||
builder.Services.AddSingleton<LibCameraLogSink>();
|
||||
|
||||
// Добавляем сервисы баз данных
|
||||
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);
|
||||
builder.Services.AddComputeResourcesService();
|
||||
builder.Services.AddImageStorageService(new DirectoryInfo("images"));
|
||||
|
||||
// Добавляем элементы интерфейса как сервисы
|
||||
builder.Services.AddViewsAndModels();
|
||||
|
||||
// Собираем хост
|
||||
var host = builder.Build();
|
||||
|
||||
// Поскольку LibCameraLogSink, который перенаправляет логи из libcamera в хост,
|
||||
// не будет создан ни одним из других сервисов, его необходимо создать превентивно
|
||||
host.Services.GetRequiredService<LibCameraLogSink>();
|
||||
|
||||
// Применяем миграции баз данных если их схема данных изменялась
|
||||
using (var scope = host.Services.CreateScope())
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<AmineContentCalibrationContext>();
|
||||
context.Database.Migrate();
|
||||
}
|
||||
using (var scope = host.Services.CreateScope())
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<AmineContentResultsContext>();
|
||||
context.Database.Migrate();
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
private static AppBuilder BuildApplication(IHost host, bool fullscreen) =>
|
||||
AppBuilder.Configure(() => new Application(host.Services, fullscreen))
|
||||
.UsePlatformDetect()
|
||||
.UseSkia()
|
||||
.LogToTrace()
|
||||
.With(new X11PlatformOptions
|
||||
{
|
||||
RenderingMode = [X11RenderingMode.Egl]
|
||||
})
|
||||
.With(new EglDisplayOptions
|
||||
{
|
||||
SupportsContextSharing = true
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user