diff --git a/CHANGELOG.md b/CHANGELOG.md index 7905014..b5639e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Improvements - Discard old data when updating a StaticSpriteBatch - Multi-target net452, making MLEM compatible with MonoGame for consoles - Allow retrieving the cost of a calculated path when using AStar +- Added trimming and AOT annotations and made MLEM trimmable - **Drastically improved StaticSpriteBatch batching performance** - **Made GenericFont and TokenizedString support UTF-32 characters like emoji** @@ -48,6 +49,7 @@ Improvements - Close other dropdowns when opening a dropdown - Generified UiMarkdownParser by adding abstract UiParser - Multi-target net452, making MLEM compatible with MonoGame for consoles +- Added trimming and AOT annotations and made MLEM.Ui trimmable Fixes - Fixed parents of elements that prevent spill not being notified properly @@ -69,6 +71,7 @@ Improvements - Allow data texture atlas pivots and offsets to be negative - Made RuntimeTexturePacker restore texture region name and pivot when packing - Multi-target net452, making MLEM compatible with MonoGame for consoles +- Added trimming and AOT annotations and made MLEM.Data trimmable Fixes - Fixed data texture atlases not allowing most characters in their region names @@ -79,11 +82,13 @@ Removals ## MLEM.Extended Improvements - Multi-target net452, making MLEM compatible with MonoGame for consoles +- Added trimming and AOT annotations and made MLEM.Extended trimmable - **Made GenericBitmapFont and GenericStashFont support UTF-32 characters like emoji** ## MLEM.Startup Improvements - Multi-target net452, making MLEM compatible with MonoGame for consoles +- Added trimming and AOT annotations and made MLEM.Startup trimmable ## 6.0.0 diff --git a/MLEM.Data/Content/RawContentManager.cs b/MLEM.Data/Content/RawContentManager.cs index 785811a..a4c2723 100644 --- a/MLEM.Data/Content/RawContentManager.cs +++ b/MLEM.Data/Content/RawContentManager.cs @@ -5,33 +5,52 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + namespace MLEM.Data.Content { /// /// Represents a version of that doesn't load content binary xnb files, but rather as their regular formats. /// public class RawContentManager : ContentManager, IGameComponent { - private static List readers; - /// /// The graphics device that this content manager uses /// public readonly GraphicsDevice GraphicsDevice; private readonly List disposableAssets = new List(); + private readonly List readers; + #if FNA private Dictionary LoadedAssets { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); #endif /// /// Creates a new content manager with an optionally specified root directory. + /// Each required for asset loading is gathered and instantiated automatically from the loaded assemblies. /// /// The service provider of your game /// The root directory. Defaults to "Content" + #if NET6_0_OR_GREATER + [RequiresUnreferencedCode("Automatically gathered RawContentReader types might be removed, use other constructor to add readers manually")] + #endif public RawContentManager(IServiceProvider serviceProvider, string rootDirectory = "Content") : + this(serviceProvider, RawContentManager.CollectContentReaders(), rootDirectory) {} + + /// + /// Creates a new content manager with an optionally specified root directory. + /// Each required for asset loading has to be passed using . + /// + /// The service provider of your game + /// The raw content readers to use, which can be modified externally afterwards to add additional readers if desired. + /// The root directory. Defaults to "Content" + public RawContentManager(IServiceProvider serviceProvider, List readers, string rootDirectory) : base(serviceProvider, rootDirectory) { if (serviceProvider.GetService(typeof(IGraphicsDeviceService)) is IGraphicsDeviceService s) this.GraphicsDevice = s.GraphicsDevice; + this.readers = readers; } /// @@ -63,9 +82,7 @@ namespace MLEM.Data.Content { private T Read(string assetName, T existing) { var triedFiles = new List(); - if (RawContentManager.readers == null) - RawContentManager.readers = RawContentManager.CollectContentReaders(); - foreach (var reader in RawContentManager.readers) { + foreach (var reader in this.readers) { if (!reader.CanRead(typeof(T))) continue; foreach (var ext in reader.GetFileExtensions()) { @@ -104,6 +121,9 @@ namespace MLEM.Data.Content { /// public void Initialize() {} + #if NET6_0_OR_GREATER + [RequiresUnreferencedCode("Automatically gathered RawContentReader types might be removed, use other constructor to add readers manually")] + #endif private static List CollectContentReaders() { var ret = new List(); var assemblyExceptions = new List(); diff --git a/MLEM.Data/Content/XmlReader.cs b/MLEM.Data/Content/XmlReader.cs index dc82584..3892e18 100644 --- a/MLEM.Data/Content/XmlReader.cs +++ b/MLEM.Data/Content/XmlReader.cs @@ -12,6 +12,10 @@ namespace MLEM.Data.Content { } /// + #if NET6_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026", + Justification = "RawContentManager does not support XmlReader in a trimmed or AOT context, so this method is not expected to be called.")] + #endif public override object Read(RawContentManager manager, string assetPath, Stream stream, Type t, object existing) { return new XmlSerializer(t).Deserialize(stream); } diff --git a/MLEM.Data/CopyExtensions.cs b/MLEM.Data/CopyExtensions.cs index 8e098ca..8dcdf8e 100644 --- a/MLEM.Data/CopyExtensions.cs +++ b/MLEM.Data/CopyExtensions.cs @@ -3,11 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + namespace MLEM.Data { /// /// A set of extensions for dealing with copying objects. /// [Obsolete("CopyExtensions has major flaws and insufficient speed compared to other libraries specifically designed for copying objects.")] + #if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Aot", "IL3050"), UnconditionalSuppressMessage("Aot", "IL2070"), UnconditionalSuppressMessage("Aot", "IL2090")] + #endif public static class CopyExtensions { private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; @@ -15,7 +22,7 @@ namespace MLEM.Data { /// /// Creates a shallow copy of the object and returns it. - /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a shallow copy of /// The binding flags for field searching @@ -31,7 +38,7 @@ namespace MLEM.Data { /// /// Creates a deep copy of the object and returns it. - /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a deep copy of /// The binding flags for field searching @@ -63,7 +70,7 @@ namespace MLEM.Data { /// /// Copies the given object into the given object in a deep manner. - /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a deep copy of /// The object to copy into diff --git a/MLEM.Data/DynamicEnum.cs b/MLEM.Data/DynamicEnum.cs index 4ef258d..f2469a3 100644 --- a/MLEM.Data/DynamicEnum.cs +++ b/MLEM.Data/DynamicEnum.cs @@ -26,6 +26,9 @@ namespace MLEM.Data { /// /// [Obsolete("DynamicEnum has been moved into the DynamicEnums library: https://www.nuget.org/packages/DynamicEnums"), JsonConverter(typeof(DynamicEnumConverter))] + #if NET6_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Aot", "IL2067")] + #endif public abstract class DynamicEnum { private static readonly Dictionary Storages = new Dictionary(); diff --git a/MLEM.Data/Json/JsonConverters.cs b/MLEM.Data/Json/JsonConverters.cs index d70118e..35805f1 100644 --- a/MLEM.Data/Json/JsonConverters.cs +++ b/MLEM.Data/Json/JsonConverters.cs @@ -11,9 +11,16 @@ namespace MLEM.Data.Json { /// /// An array of all of the s that are part of MLEM.Data /// - public static readonly JsonConverter[] Converters = typeof(JsonConverters).Assembly.GetExportedTypes() - .Where(t => t.IsSubclassOf(typeof(JsonConverter)) && !t.IsGenericType) - .Select(Activator.CreateInstance).Cast().ToArray(); + public static readonly JsonConverter[] Converters = { + new Direction2Converter(), + #pragma warning disable CS0618 + new DynamicEnumConverter(), + #pragma warning restore CS0618 + new PointConverter(), + new RectangleConverter(), + new RectangleFConverter(), + new Vector2Converter() + }; /// /// Adds all of the objects that are part of MLEM.Data to the given diff --git a/MLEM.Data/Json/JsonTypeSafeGenericDataHolder.cs b/MLEM.Data/Json/JsonTypeSafeGenericDataHolder.cs index 87877f2..7d44685 100644 --- a/MLEM.Data/Json/JsonTypeSafeGenericDataHolder.cs +++ b/MLEM.Data/Json/JsonTypeSafeGenericDataHolder.cs @@ -9,6 +9,9 @@ namespace MLEM.Data.Json { /// This class uses for each object stored to ensure that objects with a custom get deserialized as an instance of their original type if is not set to . /// [DataContract] + #if NET7_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for instantiation of JsonTypeSafeWrapper instances might not be available at runtime.")] + #endif public class JsonTypeSafeGenericDataHolder : IGenericDataHolder { private static readonly string[] EmptyStrings = new string[0]; diff --git a/MLEM.Data/Json/JsonTypeSafeWrapper.cs b/MLEM.Data/Json/JsonTypeSafeWrapper.cs index ad3f05c..5c46dbd 100644 --- a/MLEM.Data/Json/JsonTypeSafeWrapper.cs +++ b/MLEM.Data/Json/JsonTypeSafeWrapper.cs @@ -34,6 +34,9 @@ namespace MLEM.Data.Json { /// /// The value to wrap /// A with a type matching the type of + #if NET7_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] + #endif public static JsonTypeSafeWrapper Of(object value) { var type = typeof(JsonTypeSafeWrapper<>).MakeGenericType(value.GetType()); return (JsonTypeSafeWrapper) Activator.CreateInstance(type, value); diff --git a/MLEM.Data/Json/StaticJsonConverter.cs b/MLEM.Data/Json/StaticJsonConverter.cs index 980fbfb..c433ed7 100644 --- a/MLEM.Data/Json/StaticJsonConverter.cs +++ b/MLEM.Data/Json/StaticJsonConverter.cs @@ -4,9 +4,13 @@ using System.Linq; using System.Reflection; using Newtonsoft.Json; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + namespace MLEM.Data.Json { /// - /// A that doesn't actually serialize the object, but instead serializes the name given to it by the underlying . + /// A that doesn't actually serialize the object, but instead serializes the name given to it by the underlying . /// Optionally, the name of a can be passed to this converter when used in the by passing the arguments for the constructor as . /// /// The type of the object to convert @@ -29,7 +33,11 @@ namespace MLEM.Data.Json { /// /// The type that the dictionary is declared in /// The name of the dictionary itself - public StaticJsonConverter(Type type, string memberName) : this(StaticJsonConverter.GetEntries(type, memberName)) {} + public StaticJsonConverter( + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] + #endif + Type type, string memberName) : this(StaticJsonConverter.GetEntries(type, memberName)) {} /// Writes the JSON representation of the object. /// The to write to. @@ -56,7 +64,11 @@ namespace MLEM.Data.Json { return ret; } - private static Dictionary GetEntries(Type type, string memberName) { + private static Dictionary GetEntries( + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] + #endif + Type type, string memberName) { const BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; var value = type.GetProperty(memberName, flags)?.GetValue(null) ?? type.GetField(memberName, flags)?.GetValue(null); if (value == null) diff --git a/MLEM.Data/MLEM.Data.FNA.csproj b/MLEM.Data/MLEM.Data.FNA.csproj index 4c9ffa5..578c6a3 100644 --- a/MLEM.Data/MLEM.Data.FNA.csproj +++ b/MLEM.Data/MLEM.Data.FNA.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true MLEM.Data $(DefineConstants);FNA NU1701 diff --git a/MLEM.Data/MLEM.Data.csproj b/MLEM.Data/MLEM.Data.csproj index 12fe703..efb263a 100644 --- a/MLEM.Data/MLEM.Data.csproj +++ b/MLEM.Data/MLEM.Data.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true NU1701 diff --git a/MLEM.Data/NetBufferSerializer.cs b/MLEM.Data/NetBufferSerializer.cs index 2bb1d53..44ff973 100644 --- a/MLEM.Data/NetBufferSerializer.cs +++ b/MLEM.Data/NetBufferSerializer.cs @@ -11,6 +11,9 @@ namespace MLEM.Data { /// Before serializing and deserializing an object, each of the object's fields has to have a handler. New handlers can be added using or . /// [Obsolete("Lidgren.Network support is deprecated. Consider using LiteNetLib or a custom implementation instead.")] + #if NET6_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Aot", "IL2070")] + #endif public class NetBufferSerializer { private readonly Dictionary> writeFunctions = new Dictionary>(); diff --git a/MLEM.Extended/MLEM.Extended.FNA.csproj b/MLEM.Extended/MLEM.Extended.FNA.csproj index b671c22..96cd437 100644 --- a/MLEM.Extended/MLEM.Extended.FNA.csproj +++ b/MLEM.Extended/MLEM.Extended.FNA.csproj @@ -3,6 +3,7 @@ netstandard2.0;net6.0 true true + true MLEM.Extended $(DefineConstants);FNA NU1702 diff --git a/MLEM.Extended/MLEM.Extended.csproj b/MLEM.Extended/MLEM.Extended.csproj index ff63ed3..27b1392 100644 --- a/MLEM.Extended/MLEM.Extended.csproj +++ b/MLEM.Extended/MLEM.Extended.csproj @@ -3,6 +3,7 @@ netstandard2.0;net6.0 true true + true diff --git a/MLEM.Startup/MLEM.Startup.FNA.csproj b/MLEM.Startup/MLEM.Startup.FNA.csproj index b5f3a64..13360f8 100644 --- a/MLEM.Startup/MLEM.Startup.FNA.csproj +++ b/MLEM.Startup/MLEM.Startup.FNA.csproj @@ -4,6 +4,7 @@ net452;netstandard2.0;net6.0 true true + true MLEM.Startup $(DefineConstants);FNA diff --git a/MLEM.Startup/MLEM.Startup.csproj b/MLEM.Startup/MLEM.Startup.csproj index f7f863d..ad175d2 100644 --- a/MLEM.Startup/MLEM.Startup.csproj +++ b/MLEM.Startup/MLEM.Startup.csproj @@ -4,6 +4,7 @@ net452;netstandard2.0;net6.0 true true + true diff --git a/MLEM.Templates/MLEM.Templates.csproj b/MLEM.Templates/MLEM.Templates.csproj index f321339..84edf68 100644 --- a/MLEM.Templates/MLEM.Templates.csproj +++ b/MLEM.Templates/MLEM.Templates.csproj @@ -6,6 +6,7 @@ false content true + true NU5128 diff --git a/MLEM.Ui/MLEM.Ui.FNA.csproj b/MLEM.Ui/MLEM.Ui.FNA.csproj index 3482793..5076489 100644 --- a/MLEM.Ui/MLEM.Ui.FNA.csproj +++ b/MLEM.Ui/MLEM.Ui.FNA.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true MLEM.Ui $(DefineConstants);FNA diff --git a/MLEM.Ui/MLEM.Ui.csproj b/MLEM.Ui/MLEM.Ui.csproj index 301173c..8363452 100644 --- a/MLEM.Ui/MLEM.Ui.csproj +++ b/MLEM.Ui/MLEM.Ui.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true diff --git a/MLEM.Ui/Parsers/UiParser.cs b/MLEM.Ui/Parsers/UiParser.cs index b14fea6..b50525e 100644 --- a/MLEM.Ui/Parsers/UiParser.cs +++ b/MLEM.Ui/Parsers/UiParser.cs @@ -24,7 +24,12 @@ namespace MLEM.Ui.Parsers { /// /// An array containing all of the enum values. /// - public static readonly ElementType[] ElementTypes = (ElementType[]) Enum.GetValues(typeof(ElementType)); + public static readonly ElementType[] ElementTypes = + #if NET6_0_OR_GREATER + Enum.GetValues(); + #else + (ElementType[]) Enum.GetValues(typeof(ElementType)); + #endif /// /// The base path for images, which is prepended to the image link. diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs index 0fba60f..6b3b38d 100644 --- a/MLEM/Input/InputHandler.cs +++ b/MLEM/Input/InputHandler.cs @@ -17,11 +17,21 @@ namespace MLEM.Input { /// /// All values of the enum. /// - public static readonly Buttons[] AllButtons = (Buttons[]) Enum.GetValues(typeof(Buttons)); + public static readonly Buttons[] AllButtons = + #if NET6_0_OR_GREATER + Enum.GetValues(); + #else + (Buttons[]) Enum.GetValues(typeof(Buttons)); + #endif /// /// All values of the enum. /// - public static readonly Keys[] AllKeys = (Keys[]) Enum.GetValues(typeof(Keys)); + public static readonly Keys[] AllKeys = + #if NET6_0_OR_GREATER + Enum.GetValues(); + #else + (Keys[]) Enum.GetValues(typeof(Keys)); + #endif #if FNA private const int MaximumGamePadCount = 4; diff --git a/MLEM/Input/KeysExtensions.cs b/MLEM/Input/KeysExtensions.cs index 9a5714d..a397da0 100644 --- a/MLEM/Input/KeysExtensions.cs +++ b/MLEM/Input/KeysExtensions.cs @@ -12,7 +12,7 @@ namespace MLEM.Input { /// /// All enum values of /// - public static readonly ModifierKey[] ModifierKeys = (ModifierKey[]) Enum.GetValues(typeof(ModifierKey)); + public static readonly ModifierKey[] ModifierKeys = {ModifierKey.None, ModifierKey.Shift, ModifierKey.Control, ModifierKey.Alt}; private static readonly Dictionary KeysLookup = new Dictionary { {ModifierKey.Shift, new[] {Keys.LeftShift, Keys.RightShift}}, {ModifierKey.Control, new[] {Keys.LeftControl, Keys.RightControl}}, diff --git a/MLEM/Input/MouseExtensions.cs b/MLEM/Input/MouseExtensions.cs index 7276331..98595b8 100644 --- a/MLEM/Input/MouseExtensions.cs +++ b/MLEM/Input/MouseExtensions.cs @@ -10,7 +10,7 @@ namespace MLEM.Input { /// /// All enum values of /// - public static readonly MouseButton[] MouseButtons = (MouseButton[]) Enum.GetValues(typeof(MouseButton)); + public static readonly MouseButton[] MouseButtons = {MouseButton.Left, MouseButton.Middle, MouseButton.Right, MouseButton.Extra1, MouseButton.Extra2}; /// /// Returns the of the given mouse button. diff --git a/MLEM/MLEM.FNA.csproj b/MLEM/MLEM.FNA.csproj index 9a83102..42cf5cb 100644 --- a/MLEM/MLEM.FNA.csproj +++ b/MLEM/MLEM.FNA.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true MLEM $(DefineConstants);FNA diff --git a/MLEM/MLEM.csproj b/MLEM/MLEM.csproj index ac0df57..5d995d4 100644 --- a/MLEM/MLEM.csproj +++ b/MLEM/MLEM.csproj @@ -3,6 +3,7 @@ net452;netstandard2.0;net6.0 true true + true diff --git a/MLEM/Misc/Direction2.cs b/MLEM/Misc/Direction2.cs index 6d139f7..5d277bc 100644 --- a/MLEM/Misc/Direction2.cs +++ b/MLEM/Misc/Direction2.cs @@ -71,7 +71,10 @@ namespace MLEM.Misc { /// /// All enum values /// - public static readonly Direction2[] All = (Direction2[]) Enum.GetValues(typeof(Direction2)); + public static readonly Direction2[] All = { + Direction2.None, Direction2.Up, Direction2.Right, Direction2.Down, Direction2.Left, + Direction2.UpRight, Direction2.DownRight, Direction2.UpLeft, Direction2.DownLeft + }; /// /// The through directions ///