From 63665b7fb535a172745e6d289caf1742c39934dc Mon Sep 17 00:00:00 2001 From: Benjamin Date: Sun, 2 Nov 2025 10:57:12 -0600 Subject: [PATCH] Trimming Support - Made various changes that allow trimming to be more reliable --- .../ModLoadOrder/Dependency/CPKGen/Endian.cs | 17 ++++++++++-- .../ShinRyuModManager-CE.csproj | 2 ++ .../UserInterface/App.axaml.cs | 2 ++ .../UserInterface/ViewLocator.cs | 26 +++++++++---------- .../UserInterface/Views/MainWindow.axaml.cs | 4 +-- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/ShinRyuModManager-CE/ModLoadOrder/Dependency/CPKGen/Endian.cs b/ShinRyuModManager-CE/ModLoadOrder/Dependency/CPKGen/Endian.cs index 2d35991..480676d 100644 --- a/ShinRyuModManager-CE/ModLoadOrder/Dependency/CPKGen/Endian.cs +++ b/ShinRyuModManager-CE/ModLoadOrder/Dependency/CPKGen/Endian.cs @@ -114,8 +114,21 @@ public EndianWriter(Stream input, bool isLittleEndian) public bool IsLittleEndian { get; set; } = isLittleEndian; public void Write(T value) { - dynamic input = value; - byte[] someBytes = BitConverter.GetBytes(input); + // A bit gross, but AOT and Trimming compatible + var someBytes = value switch { + bool b => BitConverter.GetBytes(b), + char c => BitConverter.GetBytes(c), + double d => BitConverter.GetBytes(d), + Half h => BitConverter.GetBytes(h), + short s => BitConverter.GetBytes(s), + int i => BitConverter.GetBytes(i), + long l => BitConverter.GetBytes(l), + float f => BitConverter.GetBytes(f), + ushort us => BitConverter.GetBytes(us), + uint ui => BitConverter.GetBytes(ui), + ulong ul => BitConverter.GetBytes(ul), + _ => throw new NotSupportedException($"Type {typeof(T)} is not supported.") + }; if (!IsLittleEndian) someBytes = someBytes.Reverse().ToArray(); diff --git a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj index 17ae65e..f6fc05b 100644 --- a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj +++ b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj @@ -12,6 +12,7 @@ false UserInterface\Assets\Icons\SRMM_icon.ico true + true 1.1.11 @@ -25,6 +26,7 @@ $(BuildSuffix) + true diff --git a/ShinRyuModManager-CE/UserInterface/App.axaml.cs b/ShinRyuModManager-CE/UserInterface/App.axaml.cs index 21188fc..87fde7e 100644 --- a/ShinRyuModManager-CE/UserInterface/App.axaml.cs +++ b/ShinRyuModManager-CE/UserInterface/App.axaml.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Globalization; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; @@ -42,6 +43,7 @@ private static void DesktopOnExit(object sender, ControlledApplicationLifetimeEx Log.CloseAndFlush(); } + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Only removing validation plugins; no reflection or property access used.")] private static void DisableAvaloniaDataAnnotationValidation() { // Get an array of plugins to remove var dataValidationPluginsToRemove = diff --git a/ShinRyuModManager-CE/UserInterface/ViewLocator.cs b/ShinRyuModManager-CE/UserInterface/ViewLocator.cs index 4fd431d..0c53e18 100644 --- a/ShinRyuModManager-CE/UserInterface/ViewLocator.cs +++ b/ShinRyuModManager-CE/UserInterface/ViewLocator.cs @@ -1,24 +1,24 @@ using Avalonia.Controls; using Avalonia.Controls.Templates; +using ShinRyuModManager.UserInterface.UserControls; using ShinRyuModManager.UserInterface.ViewModels; +using ShinRyuModManager.UserInterface.Views; namespace ShinRyuModManager.UserInterface; public class ViewLocator : IDataTemplate { - public Control Build(object param) { - var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal); - var type = Type.GetType(name); - - if (type != null) { - return (Control)Activator.CreateInstance(type)!; - } - - return new TextBox { - Text = $"Not Found: {name}" + public Control Build(object data) { + return data switch { + MainWindowViewModel vm => new MainWindow { DataContext = vm }, + AboutWindowViewModel vm => new AboutWindow { DataContext = vm }, + ChangeLogWindowViewModel vm => new ChangeLogWindow { DataContext = vm }, + LibraryDisplayControlViewModel vm => new LibraryDisplayControl { DataContext = vm }, + LibraryManagerViewModel vm => new LibraryManagerWindow { DataContext = vm }, + MessageBoxWindowViewModel vm => new MessageBoxWindow { DataContext = vm }, + ProgressWindowViewModel vm => new ProgressWindow { DataContext = vm }, + _ => new TextBlock { Text = $"View not found for {data.GetType().Name}" } }; } - public bool Match(object data) { - return data is ViewModelBase; - } + public bool Match(object data) => data is ViewModelBase; } diff --git a/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs b/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs index 0fff1a1..8b24b5e 100644 --- a/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs +++ b/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs @@ -497,12 +497,12 @@ private void RefreshModList() { viewModel.LoadModList(); } - private void CreateOrActivateWindow() where T : Window { + private void CreateOrActivateWindow() where T : Window, new() { if (_childWindow is { IsVisible: true }) { // Window visible _childWindow.Activate(); } else { - _childWindow = Activator.CreateInstance(); + _childWindow = new T(); _childWindow.Closed += (_, _) => _childWindow = null; _childWindow.Show(this); }