using Avalonia; using Avalonia.OpenGL.Egl; using System.CommandLine; namespace GSS2.Test; public partial class Program { private enum RenderingMode { X11, DRM } private static List? _args = null; private static readonly RootCommand _rootCommand = new("Run UI application"); private static readonly Option _fullscreen = new("--fullscreen") { Description = "Run in fullscreen mode" }; private static readonly Option _renderingMode = new("--rendering-mode") { Description = "Rendering mode to use", DefaultValueFactory = (_) => RenderingMode.X11 }; private static readonly Option _hideConsole = new("--hide-console") { Description = "Suppress console output", DefaultValueFactory = (result) => result.GetRequiredValue(_renderingMode) == RenderingMode.DRM }; private static readonly Command _cameraTuningCommand = new("camera-tuning") { Description = "Tune camera parameters" }; private static readonly Option _cameraTuningOutputFile = new("--output") { Description = "Output image file", Required = false }; private static readonly Option _cameraTuningGainR = new("--gain-r") { Description = "Color gain (red channel) to start from", DefaultValueFactory = (_) => 1 }; private static readonly Option _cameraTuningGainG = new("--gain-g") { Description = "Color gain (green channel) to start from", DefaultValueFactory = (_) => 1 }; private static readonly Option _cameraTuningGainB = new("--gain-b") { Description = "Color gain (blue channel) to start from", DefaultValueFactory = (_) => 1 }; private static readonly Option _cameraTuningThreshold = new("--threshold") { Description = "Threshold to stop on", DefaultValueFactory = (_) => 0.1 }; private static readonly Option _cameraTuningSteps = new("--steps") { Description = "Maximum steps count", DefaultValueFactory = (_) => 10 }; private static readonly Command _captureCommand = new("capture") { Description = "Capture image from camera" }; private static readonly Option _captureOutputFile = new("--output") { Description = "Output image file", DefaultValueFactory = (_) => new FileInfo("image.png") }; private static readonly Option _captureIntensityWhite = new("--intensity-white") { Description = "Illuminator intensity for white (from 0 to 1)", DefaultValueFactory = (_) => 1 }; private static readonly Option _captureIntensityUv365nm = new("--intensity-uv365nm") { Description = "Illuminator intensity for UV 365 nm (from 0 to 1)", DefaultValueFactory = (_) => 0 }; private static readonly Option _captureIntensityUv254nm = new("--intensity-uv254nm") { Description = "Illuminator intensity for UV 254 nm (from 0 to 1)", DefaultValueFactory = (_) => 0 }; private static readonly Command _imageStorageClear = new("image-storage-clear") { Description = "Clear image storage from unused images" }; public static event ConsoleCancelEventHandler? ShutdownRequested; [STAThread] public static int Main(string[] args) { _args = args.ToList(); #if DEBUG WaitDebuggerIfNeeded(); #endif _rootCommand.SetAction(Ui); _rootCommand.Add(_fullscreen); _rootCommand.Add(_renderingMode); _rootCommand.Add(_hideConsole); _rootCommand.Add(_cameraTuningCommand); _cameraTuningCommand.SetAction(CameraTuning); _cameraTuningCommand.Add(_cameraTuningOutputFile); _cameraTuningCommand.Add(_cameraTuningGainR); _cameraTuningCommand.Add(_cameraTuningGainG); _cameraTuningCommand.Add(_cameraTuningGainB); _cameraTuningCommand.Add(_cameraTuningThreshold); _cameraTuningCommand.Add(_cameraTuningSteps); _rootCommand.Add(_captureCommand); _captureCommand.SetAction(Capture); _captureCommand.Add(_captureOutputFile); _captureCommand.Add(_captureIntensityWhite); _captureCommand.Add(_captureIntensityUv365nm); _captureCommand.Add(_captureIntensityUv254nm); _rootCommand.Add(_imageStorageClear); _imageStorageClear.SetAction(ImageStorageClear); Console.CancelKeyPress += new ConsoleCancelEventHandler(OnProgramShutdown); Console.WriteLine("Press Ctrl+C to shut down."); var parseResult = _rootCommand.Parse(_args); if (parseResult.Errors.Count() != 0) { foreach (var parseError in parseResult.Errors) Console.Error.WriteLine(parseError.Message); return 1; } return parseResult.Invoke(); } private static void OnProgramShutdown(object? sender, ConsoleCancelEventArgs ea) { ShutdownRequested?.Invoke(sender, ea); ea.Cancel = true; } private static void WaitDebuggerIfNeeded() { if (System.Diagnostics.Debugger.IsAttached) return; if (_args is null || !_args.Contains("--debug")) return; _args.Remove("--debug"); bool keepWaiting = true; void CancelHandle(object? sender, ConsoleCancelEventArgs e) { e.Cancel = true; keepWaiting = false; Console.WriteLine("\nWait cancelled by user."); Environment.Exit(0); } Console.CancelKeyPress += CancelHandle; Console.WriteLine("Waiting debugger attach (Press Ctrl+C to cancel)"); Console.WriteLine($"Process Id: {Environment.ProcessId}"); Console.WriteLine($"Process Name: {Environment.ProcessPath}"); Console.WriteLine($"Thread Id: {Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine($"Thread Name: {Thread.CurrentThread.Name}"); while (!System.Diagnostics.Debugger.IsAttached && keepWaiting) Thread.Sleep(100); if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); Console.CancelKeyPress -= CancelHandle; } }