1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-06 01:47:06 +02:00

Made JsonTypeSafeWrapper.Of generic to potentially avoid reflective instantiation

This commit is contained in:
Ell 2022-11-28 00:43:50 +01:00
parent d72b094a7a
commit 1a1b2025cd
4 changed files with 20 additions and 10 deletions

View file

@ -88,6 +88,7 @@ Improvements
- Added trimming and AOT annotations and made MLEM.Data trimmable - Added trimming and AOT annotations and made MLEM.Data trimmable
- Store a RuntimeTexturePacker packed texture region's source region - Store a RuntimeTexturePacker packed texture region's source region
- Use JSON.NET attributes in favor of DataContract and DataMember - Use JSON.NET attributes in favor of DataContract and DataMember
- Made JsonTypeSafeWrapper.Of generic to potentially avoid reflective instantiation
Fixes Fixes
- Fixed data texture atlases not allowing most characters in their region names - Fixed data texture atlases not allowing most characters in their region names

View file

@ -33,8 +33,7 @@ namespace MLEM.Data.Json {
} else { } else {
if (this.data == null) if (this.data == null)
this.data = new Dictionary<string, JsonTypeSafeWrapper>(); this.data = new Dictionary<string, JsonTypeSafeWrapper>();
// if types already match exactly, we don't need to use Of (which requires dynamic code) this.data[key] = JsonTypeSafeWrapper.Of(data);
this.data[key] = data.GetType() == typeof(T) ? new JsonTypeSafeWrapper<T>(data) : JsonTypeSafeWrapper.Of(data);
} }
} }

View file

@ -29,17 +29,21 @@ namespace MLEM.Data.Json {
/// <summary> /// <summary>
/// Creates a new <see cref="JsonTypeSafeWrapper{T}"/> from the given value. /// Creates a new <see cref="JsonTypeSafeWrapper{T}"/> from the given value.
/// The type parameter of the returned wrapper will be equal to the <see cref="Type"/> of the <paramref name="value"/> passed. /// The type parameter of the returned wrapper will be equal to the <see cref="Type"/> of the <paramref name="value"/> passed, even if it is a subtype of <typeparamref name="T"/>.
/// If a <see cref="JsonTypeSafeWrapper{T}"/> for a specific type, known at comepile type, should be created, you can use <see cref="JsonTypeSafeWrapper{T}(T)"/>. /// If a <see cref="JsonTypeSafeWrapper{T}"/> for a specific type, known at compile type, should be created, you can use <see cref="JsonTypeSafeWrapper{T}(T)"/>.
/// </summary> /// </summary>
/// <param name="value">The value to wrap</param> /// <param name="value">The value to wrap</param>
/// <returns>A <see cref="JsonTypeSafeWrapper{T}"/> with a type matching the type of <paramref name="value"/></returns> /// <returns>A <see cref="JsonTypeSafeWrapper{T}"/> with a type matching the type of <paramref name="value"/></returns>
#if NET7_0_OR_GREATER #if NET7_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime if the value's type is a subtype of T.")]
#endif #endif
public static JsonTypeSafeWrapper Of(object value) { public static JsonTypeSafeWrapper Of<T>(T value) {
var type = typeof(JsonTypeSafeWrapper<>).MakeGenericType(value.GetType()); if (value.GetType() == typeof(T)) {
return (JsonTypeSafeWrapper) Activator.CreateInstance(type, value); return new JsonTypeSafeWrapper<T>(value);
} else {
var type = typeof(JsonTypeSafeWrapper<>).MakeGenericType(value.GetType());
return (JsonTypeSafeWrapper) Activator.CreateInstance(type, value);
}
} }
} }
@ -55,7 +59,7 @@ namespace MLEM.Data.Json {
/// <summary> /// <summary>
/// Creates a new json type-safe wrapper instance that wraps the given <paramref name="value"/>. /// Creates a new json type-safe wrapper instance that wraps the given <paramref name="value"/>.
/// If the type of the value is unknown at compile time, <see cref="JsonTypeSafeWrapper.Of"/> can be used instead. /// If the type of the value is unknown at compile time, <see cref="JsonTypeSafeWrapper.Of{T}"/> can be used instead.
/// </summary> /// </summary>
/// <param name="value">The value to wrap</param> /// <param name="value">The value to wrap</param>
public JsonTypeSafeWrapper(T value) { public JsonTypeSafeWrapper(T value) {

View file

@ -40,9 +40,15 @@ public class DataTests {
var safeData = new JsonTypeSafeGenericDataHolder(); var safeData = new JsonTypeSafeGenericDataHolder();
// data holder should wrap the time span to ensure that it stays a time span // data holder should wrap the time span to ensure that it stays a time span
safeData.SetData("Time", TimeSpan.FromMinutes(5)); safeData.SetData("Time", TimeSpan.FromMinutes(5));
// also check path that creates an instance through reflection
safeData.SetData<object>("Time2", TimeSpan.FromMinutes(15));
var safeRead = DataTests.SerializeAndDeserialize(safeData); var safeRead = DataTests.SerializeAndDeserialize(safeData);
Assert.IsInstanceOf<TimeSpan>(safeRead.GetData<object>("Time")); Assert.IsInstanceOf<TimeSpan>(safeRead.GetData<object>("Time"));
Assert.DoesNotThrow(() => safeRead.GetData<TimeSpan>("Time")); Assert.AreEqual(TimeSpan.FromMinutes(5), safeRead.GetData<TimeSpan>("Time"));
Assert.IsInstanceOf<TimeSpan>(safeRead.GetData<object>("Time2"));
Assert.AreEqual(TimeSpan.FromMinutes(15), safeRead.GetData<TimeSpan>("Time2"));
} }
private static T SerializeAndDeserialize<T>(T t) { private static T SerializeAndDeserialize<T>(T t) {