XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
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>(); 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();
    }
}