using System.Diagnostics; using System.Text.Json; using Microsoft.UI.Windowing; using Windows.Foundation; using Windows.Graphics; using XFEEDToolBox.Controls; using XFEEDToolBox.Core.Galaxy; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Core.Navigation; using XFEEDToolBox.Views; namespace XFEEDToolBox; public partial class App { // Own-control diagnostics, without OS mouse/keyboard automation or game actions. private static async Task RunMapPerformanceProbeAsync(string reportPath) { Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(reportPath))!); var cases = new List(); object? homeInteraction = null; object? panorama=null;object? suggestions=null;string? failure = null; var shell = MainWindow.Content; try { ((OverlappedPresenter)MainWindow.AppWindow.Presenter).Restore(false); MainWindow.AppWindow.Resize(new SizeInt32(1510, 980)); MainWindow.Activate(); AppShellPage.Current!.Navigate(typeof(MainPage)); await Task.Delay(350); var home = (GalaxyMapView)((MainPage)AppShellPage.Current.CurrentPage!).FindName("HomeGalaxyMap"); home.RenderNowForProbe(); var initial = home.CameraState; var frame = home.FrameCount; if(!home.MapGraphicsBackend.StartsWith("Direct3D"))throw new InvalidOperationException(home.GraphicsError); for (var i = 0; i < 1000; i++) home.ApplyDragDelta(.02, .01, false); var state = home.CameraState; await Task.Delay(150); var coalesced = home.FrameCount - frame; var atRest = home.FrameCount; await Task.Delay(100); var idle = home.FrameCount == atRest; home.ResetCamera(); home.RenderNowForProbe(); homeInteraction = new { home.IsInteractive, rotationChanges = state.Yaw > initial.Yaw && state.Pitch > initial.Pitch, inputUpdates = 1000, renderedFrames = coalesced, coalesced = coalesced is > 0 and <= 2, idleDoesNotRedraw = idle }; var realSystems = ViewModel.GalaxySystems.ToArray(); var root = new Grid(); MainWindow.Content = root; foreach (var (name, systems, synthetic,longRoute) in new[] { ("local-real-coordinates", realSystems, false,false), ("dense-1800", BenchmarkSystems(1800), true,false), ("catalog-25000", BenchmarkSystems(25000), true,false),("4k-25000-route",BenchmarkSystems(25000),true,true) }) { var map = new GalaxyMapView { Width = 850, Height = 500, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Systems = systems, Centre = synthetic ? new(0, 0, 0) : ViewModel.GalaxyCentre ?? new(0, 0, 0), CurrentSystem = systems.FirstOrDefault()?.Name ?? "" }; if(longRoute) { var raster=MainWindow.Content.XamlRoot?.RasterizationScale??1;map.Width=3840/raster;map.Height=2160/raster; map.Route=systems.Select((s,i)=>new NavWaypoint(i+1,s.Name,s.Position,s.StarClass)).ToArray(); map.FuelOverlay=new NavigationFuelOverlay(Enumerable.Range(1,25000).Where(i=>i>12500).Select(i=>(long)i).ToArray(),[1,12500],12500); } root.Children.Add(map); await Task.Delay(200); map.RenderNowForProbe(); map.UpdateLayout(); if(!map.MapGraphicsBackend.StartsWith("Direct3D"))throw new InvalidOperationException(map.GraphicsError); for (var i = 0; i < 8; i++) { map.ApplyDragDelta(.1, .05, false); map.RenderNowForProbe(); } var vectors = map.VectorNodesCreated; var text = map.TextNodesCreated; var sceneBuilds = map.SceneRebuilds; var samples = new double[120]; var allocations = GC.GetAllocatedBytesForCurrentThread(); for (var i = 0; i < samples.Length; i++) { var clock = Stopwatch.GetTimestamp(); map.ApplyDragDelta(.35, .12, false); map.RenderNowForProbe(); map.UpdateLayout(); samples[i] = (Stopwatch.GetTimestamp() - clock) * 1000.0 / Stopwatch.Frequency; } var allocated = GC.GetAllocatedBytesForCurrentThread() - allocations; var noResort = map.SceneRebuilds == sceneBuilds; Array.Sort(samples); var skyBeforePan=map.SkyboxRebuilds; var target = new Coordinates(13, 7, -11); var beforePan = map.ProjectForProbe(target); map.ApplyDragDelta(23, -17, true); map.RenderNowForProbe(); var afterPan = map.ProjectForProbe(target); var panCorrect = Math.Abs(afterPan.X - beforePan.X - 23) < .001 && Math.Abs(afterPan.Y - beforePan.Y + 17) < .001; var skyPanStable=map.SkyboxRebuilds==skyBeforePan; var priorScale = map.CameraState.Scale; map.Zoom(1.5); map.RenderNowForProbe(); var zoomCorrect = Math.Abs(map.CameraState.Scale / priorScale - 1.5) < .001; var skyZoomStable=map.SkyboxRebuilds==skyBeforePan; map.ResetCamera(); map.RenderNowForProbe(); var selectable = systems.FirstOrDefault(s => { var p = map.ProjectForProbe(s.Position); return p.X > 10 && p.X < 840 && p.Y > 10 && p.Y < 490; }); var selectionWorks = selectable is null; if (selectable is not null) { map.SelectAt(map.ProjectForProbe(selectable.Position)); selectionWorks = map.Selection is not null; } cases.Add(new { name, systems = systems.Length, syntheticBenchmarkOnly = synthetic, visible = map.VisibleStars, renderer=map.MapGraphicsBackend,renderError=map.GraphicsError,drawCalls=map.GraphicsDrawCalls, frames = samples.Length, meanCpuMilliseconds = samples.Average(), p95CpuMilliseconds = samples[(int)(samples.Length * .95)], worstCpuMilliseconds = samples[^1], allocatedBytesPerFrame = allocated / samples.Length, vectorNodesStable = map.VectorNodesCreated == vectors, textNodesStable = map.TextNodesCreated == text, noSceneResortWhileDragging = noResort, panCorrect, zoomCorrect, selectionWorks, skyboxAtInfinityDuringPan=skyPanStable,skyboxAtInfinityDuringZoom=skyZoomStable, visibleGlows=map.GlowingStars,allVisibleStarsGlow=map.GlowingStars==map.VisibleStars, gridLines=map.GridLinesVisible,gridGeometryBounded=map.GridLinesVisible<=InfiniteGalaxyGrid.MaximumLines }); var image=map.CapturePixelsForProbe(); await SaveModelFrameAsync(new ShipModelView.RenderedFrame(image.Width,image.Height,image.Pixels,0),Path.Combine(Path.GetDirectoryName(Path.GetFullPath(reportPath))!,name+"-gpu.png")); map.RenderNowForProbe(); map.SuspendPage(); var stopped = map.FrameCount; map.ApplyDragDelta(10, 5, false); await Task.Delay(80); if (map.FrameCount != stopped) throw new InvalidOperationException("隐藏星图仍在绘制。"); root.Children.Remove(map); } MainWindow.Content = shell; AppShellPage.Current.Navigate(typeof(GalaxyMapPage)); await Task.Delay(200); var page = (NavigationPage)AppShellPage.Current.CurrentPage!; var expanded = (GalaxyMapView)page.FindName("Map"); var completion=await page.ProbeSuggestionsAsync("HR 32");suggestions=new{completion.Count,completion.Open,completion.AllNative}; if(completion.Count<2||!completion.Open||!completion.AllNative)throw new InvalidOperationException("星系补全未在原生控件中展示游戏目录结果。"); expanded.RenderNowForProbe(); await CapturePageAsync(page, Path.Combine(Path.GetDirectoryName(Path.GetFullPath(reportPath))!, "galaxy-layout.png")); expanded.ShowGalaxyOverview();expanded.RenderNowForProbe();var overview=expanded.CapturePixelsForProbe(); await SaveModelFrameAsync(new ShipModelView.RenderedFrame(overview.Width,overview.Height,overview.Pixels,0),Path.Combine(Path.GetDirectoryName(Path.GetFullPath(reportPath))!,"galaxy-overview-gpu.png")); panorama=new{expanded.MapGraphicsBackend,expanded.SkyboxSource,overview.Width,overview.Height,drawCalls=expanded.GraphicsDrawCalls}; if(!File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"XFEstudio","XFEEDToolBox","galaxy","skybox-verified.dds"))) throw new InvalidOperationException("原始天空资源尚未排除场景反射。"); } catch (Exception e) { failure = e.ToString(); } await File.WriteAllTextAsync(reportPath, JsonSerializer.Serialize(new { homeInteraction, cases,panorama,suggestions, failure, uiError = ViewModel.ErrorMessage, inputMethod = "Same own-control drag/zoom/select handlers; no OS input automation", gameActionsInvoked = false }, new JsonSerializerOptions { WriteIndented = true })); MainWindow.Close(); } private static GalacticSystem[] BenchmarkSystems(int count) { var random = new Random(73421); return Enumerable.Range(0, count).Select(i => new GalacticSystem("Benchmark-" + i, new Coordinates((random.NextDouble() - .5) * 110, (random.NextDouble() - .5) * 55, (random.NextDouble() - .5) * 110),StarClass:"OBAFGKMLTY"[i%10].ToString(), Source: "性能探针合成坐标,不保存为星图数据")).ToArray(); } }