|
|
|
@@ -0,0 +1,61 @@
|
|
|
|
|
#nullable enable
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using UnityEditor.Compilation;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using ShrinkContext;
|
|
|
|
|
using ShrinkEventBus;
|
|
|
|
|
|
|
|
|
|
namespace ShrinkSDK.Inspection.Editor
|
|
|
|
|
{
|
|
|
|
|
public static class ShrinkInspectionExport
|
|
|
|
|
{
|
|
|
|
|
private const string DirectoryName = "Artifacts/Inspection";
|
|
|
|
|
/// <summary>Host extensions add explicitly owned Network/Command/Context instances. Remove handlers when the host shuts down.</summary>
|
|
|
|
|
public static event Action<ShrinkInspectionSnapshot>? CaptureHostState;
|
|
|
|
|
|
|
|
|
|
[MenuItem("Tools/ShrinkSDK/Inspection/Export compilation inputs")]
|
|
|
|
|
public static void ExportCompilation()
|
|
|
|
|
{
|
|
|
|
|
RequireStableEditor();
|
|
|
|
|
var root = Path.GetFullPath(".");
|
|
|
|
|
var assemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);
|
|
|
|
|
var loaded = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => a.GetName().Name).ToHashSet();
|
|
|
|
|
var identityNames = assemblies.Select(a => a.name).Where(loaded.Contains).OrderBy(n => n, StringComparer.Ordinal).ToArray();
|
|
|
|
|
var inputs = assemblies.Select(a => new { Name = a.name, Sources = a.sourceFiles.Select(Path.GetFullPath).ToArray(),
|
|
|
|
|
References = a.allReferences.Select(Path.GetFullPath).Where(File.Exists).ToArray(), Defines = a.defines, Output = Path.GetFullPath(a.outputPath) }).ToArray();
|
|
|
|
|
var ticks = inputs.SelectMany(a => a.Sources.Concat(a.References)).Distinct(StringComparer.OrdinalIgnoreCase)
|
|
|
|
|
.ToDictionary(path => path, path => File.GetLastWriteTimeUtc(path).Ticks);
|
|
|
|
|
Directory.CreateDirectory(DirectoryName);
|
|
|
|
|
File.WriteAllText(DirectoryName + "/compilation.json", JsonConvert.SerializeObject(new { Root = root,
|
|
|
|
|
BuildId = ShrinkInspectionSnapshot.BuildIdentity(identityNames), IdentityAssemblies = identityNames, Assemblies = inputs, SourceTicks = ticks }, Formatting.Indented));
|
|
|
|
|
Debug.Log("Shrink inspection compilation exported: " + Path.GetFullPath(DirectoryName + "/compilation.json"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[MenuItem("Tools/ShrinkSDK/Inspection/Export runtime snapshot")]
|
|
|
|
|
public static void ExportRuntime()
|
|
|
|
|
{
|
|
|
|
|
RequireStableEditor();
|
|
|
|
|
var path = DirectoryName + "/compilation.json";
|
|
|
|
|
if (!File.Exists(path)) throw new InvalidOperationException("Export compilation inputs first.");
|
|
|
|
|
var manifest = JsonConvert.DeserializeObject<IdentityManifest>(File.ReadAllText(path))!;
|
|
|
|
|
var snapshot = new ShrinkInspectionSnapshot(ShrinkInspectionSnapshot.BuildIdentity(manifest.IdentityAssemblies));
|
|
|
|
|
snapshot.AddContext("default-context", ShrinkContextDefaults.Default);
|
|
|
|
|
var ordinal = 0;
|
|
|
|
|
foreach (var bus in EventBus.CaptureNamedBuses()) snapshot.AddEventBus("named-bus-" + ordinal++, bus);
|
|
|
|
|
snapshot.Coverage.Add("Default Context and named EventBus instances only; host-owned instances require CaptureHostState registration.");
|
|
|
|
|
CaptureHostState?.Invoke(snapshot);
|
|
|
|
|
File.WriteAllText(DirectoryName + "/runtime.json", snapshot.ToJson());
|
|
|
|
|
Debug.Log("Shrink inspection runtime exported: " + Path.GetFullPath(DirectoryName + "/runtime.json"));
|
|
|
|
|
}
|
|
|
|
|
private static void RequireStableEditor()
|
|
|
|
|
{
|
|
|
|
|
if (EditorApplication.isCompiling || EditorApplication.isUpdating) throw new InvalidOperationException("Wait for Editor compilation/import to finish.");
|
|
|
|
|
}
|
|
|
|
|
private sealed class IdentityManifest { public string[] IdentityAssemblies = Array.Empty<string>(); }
|
|
|
|
|
}
|
|
|
|
|
}
|