1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-26 06:28:35 +01:00

Compare commits

..

4 commits

5 changed files with 13 additions and 23 deletions

View file

@ -39,6 +39,7 @@ Fixes
- Fixed Combination.IsModifierDown querying one of its modifiers instead of all of them - Fixed Combination.IsModifierDown querying one of its modifiers instead of all of them
Removals Removals
- Removed DataContract attribute from GenericDataHolder
- Marked EnumHelper as obsolete due to its reimplementation in [DynamicEnums](https://www.nuget.org/packages/DynamicEnums) - Marked EnumHelper as obsolete due to its reimplementation in [DynamicEnums](https://www.nuget.org/packages/DynamicEnums)
### MLEM.Ui ### MLEM.Ui
@ -79,6 +80,8 @@ Improvements
- Multi-target net452, making MLEM compatible with MonoGame for consoles - Multi-target net452, making MLEM compatible with MonoGame for consoles
- 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
- Allow adding JsonTypeSafeWrapper instances to JsonTypeSafeGenericDataHolder directly
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

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization;
using MLEM.Misc; using MLEM.Misc;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -7,8 +6,8 @@ namespace MLEM.Data.Json {
/// <summary> /// <summary>
/// An <see cref="IGenericDataHolder"/> represents an object that can hold generic key-value based data. /// An <see cref="IGenericDataHolder"/> represents an object that can hold generic key-value based data.
/// This class uses <see cref="JsonTypeSafeWrapper"/> for each object stored to ensure that objects with a custom <see cref="JsonConverter"/> get deserialized as an instance of their original type if <see cref="JsonSerializer.TypeNameHandling"/> is not set to <see cref="TypeNameHandling.None"/>. /// This class uses <see cref="JsonTypeSafeWrapper"/> for each object stored to ensure that objects with a custom <see cref="JsonConverter"/> get deserialized as an instance of their original type if <see cref="JsonSerializer.TypeNameHandling"/> is not set to <see cref="TypeNameHandling.None"/>.
/// Note that, using <see cref="SetData"/>, adding <see cref="JsonTypeSafeWrapper{T}"/> instances directly is also possible.
/// </summary> /// </summary>
[DataContract]
#if NET7_0_OR_GREATER #if NET7_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for instantiation of JsonTypeSafeWrapper instances might not be available at runtime.")] [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for instantiation of JsonTypeSafeWrapper instances might not be available at runtime.")]
#endif #endif
@ -16,7 +15,7 @@ namespace MLEM.Data.Json {
private static readonly string[] EmptyStrings = new string[0]; private static readonly string[] EmptyStrings = new string[0];
[DataMember(EmitDefaultValue = false)] [JsonProperty]
private Dictionary<string, JsonTypeSafeWrapper> data; private Dictionary<string, JsonTypeSafeWrapper> data;
/// <inheritdoc /> /// <inheritdoc />
@ -27,7 +26,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>();
this.data[key] = JsonTypeSafeWrapper.Of(data); this.data[key] = data as JsonTypeSafeWrapper ?? JsonTypeSafeWrapper.Of(data);
} }
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MLEM.Data.Json { namespace MLEM.Data.Json {
@ -15,6 +14,7 @@ namespace MLEM.Data.Json {
/// <summary> /// <summary>
/// Returns this json type-safe wrapper's value as an <see cref="object"/>. /// Returns this json type-safe wrapper's value as an <see cref="object"/>.
/// </summary> /// </summary>
[JsonIgnore]
public abstract object Value { get; } public abstract object Value { get; }
/// <summary> /// <summary>
@ -45,12 +45,12 @@ namespace MLEM.Data.Json {
} }
/// <inheritdoc /> /// <inheritdoc />
[DataContract]
public class JsonTypeSafeWrapper<T> : JsonTypeSafeWrapper { public class JsonTypeSafeWrapper<T> : JsonTypeSafeWrapper {
/// <inheritdoc /> /// <inheritdoc />
public override object Value => this.value; public override object Value => this.value;
[DataMember]
[JsonProperty]
private readonly T value; private readonly T value;
/// <summary> /// <summary>

View file

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization;
namespace MLEM.Misc { namespace MLEM.Misc {
/// <summary> /// <summary>
@ -7,12 +6,9 @@ namespace MLEM.Misc {
/// A lot of MLEM components extend this class to allow for users to add additional data to them easily. /// A lot of MLEM components extend this class to allow for users to add additional data to them easily.
/// This <see cref="IGenericDataHolder"/> implemention uses an underlying <see cref="Dictionary{String,Object}"/> that only keeps track of non-default values. /// This <see cref="IGenericDataHolder"/> implemention uses an underlying <see cref="Dictionary{String,Object}"/> that only keeps track of non-default values.
/// </summary> /// </summary>
[DataContract]
public class GenericDataHolder : IGenericDataHolder { public class GenericDataHolder : IGenericDataHolder {
private static readonly string[] EmptyStrings = new string[0]; private static readonly string[] EmptyStrings = new string[0];
[DataMember(EmitDefaultValue = false)]
private Dictionary<string, object> data; private Dictionary<string, object> data;
/// <inheritdoc /> /// <inheritdoc />

View file

@ -37,24 +37,16 @@ public class DataTests {
[Test] [Test]
public void TestJsonTypeSafety() { public void TestJsonTypeSafety() {
var serializer = new JsonSerializer {TypeNameHandling = TypeNameHandling.Auto};
// normal generic data holder should crush the time span down to a string due to its custom serializer
var data = new GenericDataHolder();
data.SetData("Time", TimeSpan.FromMinutes(5));
var read = DataTests.SerializeAndDeserialize(serializer, data);
Assert.IsNotInstanceOf<TimeSpan>(read.GetData<object>("Time"));
Assert.Throws<InvalidCastException>(() => read.GetData<TimeSpan>("Time"));
// json type safe generic data holder should wrap the time span to ensure that it stays a time span
var safeData = new JsonTypeSafeGenericDataHolder(); var safeData = new JsonTypeSafeGenericDataHolder();
// 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));
var safeRead = DataTests.SerializeAndDeserialize(serializer, 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.DoesNotThrow(() => safeRead.GetData<TimeSpan>("Time"));
} }
private static T SerializeAndDeserialize<T>(JsonSerializer serializer, T t) { private static T SerializeAndDeserialize<T>(T t) {
var serializer = new JsonSerializer {TypeNameHandling = TypeNameHandling.Auto};
var writer = new StringWriter(); var writer = new StringWriter();
serializer.Serialize(writer, t); serializer.Serialize(writer, t);
return serializer.Deserialize<T>(new JsonTextReader(new StringReader(writer.ToString()))); return serializer.Deserialize<T>(new JsonTextReader(new StringReader(writer.ToString())));