Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed resolving json converters (included issue #75) #90

Merged
merged 10 commits into from
Mar 1, 2024
46 changes: 46 additions & 0 deletions Assets/Resources/Newtonsoft.Json-for-Unity.Converters.asset
Original file line number Diff line number Diff line change
Expand Up @@ -19,142 +19,188 @@ MonoBehaviour:
unityConverters:
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Addressables.AssetReferenceConverter
converterAssembly: Newtonsoft.Json.UnityConverters.Addressables
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshQueryFilterConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshTriangulationConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Camera.CullingGroupEventConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsIntConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.PlaneConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectIntConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectOffsetConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Graphics.ResolutionConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Hashing.Hash128Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Color32Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.ColorConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Matrix4x4Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.QuaternionConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.SphericalHarmonicsL2Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector2Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector2IntConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector3Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector3IntConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector4Converter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.NativeArray.NativeArrayConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.JointDriveConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.JointLimitsConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.SoftJointLimitConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics2D.ColliderDistance2DConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics2D.ContactFilter2DConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Random.RandomStateConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Scripting.LayerMaskConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Scripting.RangeIntConverter
converterAssembly: Newtonsoft.Json.UnityConverters
settings: []
useAllJsonNetConverters: 0
jsonNetConverters:
- enabled: 1
converterName: Newtonsoft.Json.Converters.StringEnumConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 1
converterName: Newtonsoft.Json.Converters.VersionConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.BinaryConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.BsonObjectIdConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DataSetConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DataTableConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DiscriminatedUnionConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.EntityKeyMemberConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.ExpandoObjectConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.IsoDateTimeConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.JavaScriptDateTimeConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.KeyValuePairConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.RegexConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.UnixDateTimeConverter
converterAssembly: Newtonsoft.Json
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.XmlNodeConverter
converterAssembly: Newtonsoft.Json
settings: []
autoSyncConverters: 1
4 changes: 2 additions & 2 deletions Build/version.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"Major": 1,
"Minor": 6,
"Patch": 2,
"Patch": 3,
"Suffix": "",
"AutoDeployLiveRun": true
"AutoDeployLiveRun": false
}
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Unity Converters for Newtonsoft.Json changelog

## 1.6.3 (WIP)

- Fixed converter lookups collisions when multiple assemblies converters
with the same name, as it was not resolving assemblies in an exact way
nor deterministic order:

- Added assembly name field to `ConverterConfig` for each converter.

- Changed TypeCache to sort assemblies based on `FullName`
and some heuristics.

- Changed TypeCache to lookup type in correct assembly,
based on the assembly's name.

Thanks [@Erifirin](https://github.com/Erifirin) for the pull request ([#90](https://github.com/jilleJr/Newtonsoft.Json-for-Unity.Converters/pull/90))

## 1.6.2 (2024-01-08)

- Fixed typo in the new Unity.Mathematics QuaternionConverter's namespace:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ public struct ConverterConfig : IEquatable<ConverterConfig>

public string converterName;

public string converterAssembly;

public List<KeyedConfig> settings;

public override string ToString()
{
return $"{{enabled={enabled}, converterName={converterName}, settings=[{settings?.Count ?? 0}]}}";
return $"{{enabled={enabled}, converterName={converterName}, assembly={converterAssembly}, settings=[{settings?.Count ?? 0}]}}";
}

public override bool Equals(object obj)
Expand All @@ -28,16 +30,18 @@ public bool Equals(ConverterConfig other)
{
return enabled == other.enabled &&
converterName == other.converterName &&
converterAssembly == other.converterAssembly &&
EqualityComparer<List<KeyedConfig>>.Default.Equals(settings, other.settings);
}

#pragma warning disable S2328 // "GetHashCode" should not reference mutable fields
public override int GetHashCode()
#pragma warning restore S2328 // "GetHashCode" should not reference mutable fields
{
int hashCode = 1016066258;
int hashCode = 913629501;
hashCode = hashCode * -1521134295 + enabled.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(converterName);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(converterAssembly);
hashCode = hashCode * -1521134295 + EqualityComparer<List<KeyedConfig>>.Default.GetHashCode(settings);
return hashCode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,27 @@ public override void OnInspectorGUI()

private void AddAndSetupConverters(SerializedProperty arrayProperty, IList<Type> converterTypes, bool newAreEnabledByDefault)
{
var elements = EnumerateArrayElements(arrayProperty);
var elements = EnumerateArrayElements(arrayProperty).ToArray();
var elementTypes = elements
.Select(e => TypeCache.FindType(e.FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue))
.Select(e => TypeCache.FindType(
name: e.FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue,
assemblyName: e.FindPropertyRelative(nameof(ConverterConfig.converterAssembly)).stringValue
))
.ToArray();

// Refresh missing fields on existing types
for (int i = 0; i < elements.Length; i++)
{
SerializedProperty elem = elements[i];
Type type = elementTypes[i];

var assemblyNameProp = elem.FindPropertyRelative(nameof(ConverterConfig.converterAssembly));
if (string.IsNullOrEmpty(assemblyNameProp.stringValue))
{
assemblyNameProp.stringValue = type.Assembly.GetName().Name;
}
}

Type[] missingConverters = converterTypes
.Where(type => !elementTypes.Contains(type))
.ToArray();
Expand All @@ -166,7 +182,7 @@ private void AddAndSetupConverters(SerializedProperty arrayProperty, IList<Type>
{
continue;
}
var typeName = arrayProperty.GetArrayElementAtIndex(i).FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue;
string typeName = arrayProperty.GetArrayElementAtIndex(i).FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue;
Debug.Log($"Removed type from JsonConverter list: \"{typeName}\"", target);
arrayProperty.DeleteArrayElementAtIndex(i);
}
Expand All @@ -179,9 +195,11 @@ private void AddAndSetupConverters(SerializedProperty arrayProperty, IList<Type>
SerializedProperty elemProp = arrayProperty.GetArrayElementAtIndex(nextIndex);
SerializedProperty enabledProp = elemProp.FindPropertyRelative(nameof(ConverterConfig.enabled));
SerializedProperty converterNameProp = elemProp.FindPropertyRelative(nameof(ConverterConfig.converterName));
SerializedProperty assemblyNameProp = elemProp.FindPropertyRelative(nameof(ConverterConfig.converterAssembly));

enabledProp.boolValue = newAreEnabledByDefault;
converterNameProp.stringValue = converterType.FullName;
assemblyNameProp.stringValue = converterType.Assembly.GetName().Name;
}
}

Expand Down Expand Up @@ -236,7 +254,10 @@ private void FoldoutConvertersList(SerializedProperty property, AnimBool fadedAn
var allConfigsWithType = EnumerateArrayElements(property)
.Select(o => (
serializedProperty: o,
type: TypeCache.FindType(o.FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue)
type: TypeCache.FindType(
name: o.FindPropertyRelative(nameof(ConverterConfig.converterName)).stringValue,
assemblyName: o.FindPropertyRelative(nameof(ConverterConfig.converterAssembly)).stringValue
)
))
.Where(o => o.type != null)
.OrderBy(o => o.type.FullName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,15 @@ internal static ConverterGrouping FindGroupedConverters(UnityConvertersConfig co
}

return new ConverterGrouping {
outsideConverters = config.outsideConverters.Select(x => GetTypeOrLog(x.converterName)).WhereNotNullRef().ToList(),
unityConverters = config.unityConverters.Select(x => GetTypeOrLog(x.converterName)).WhereNotNullRef().ToList(),
jsonNetConverters = config.jsonNetConverters.Select(x => GetTypeOrLog(x.converterName)).WhereNotNullRef().ToList(),
outsideConverters = config.outsideConverters.Select(x => GetTypeOrLog(x.converterName, x.converterAssembly)).WhereNotNullRef().ToList(),
unityConverters = config.unityConverters.Select(x => GetTypeOrLog(x.converterName, x.converterAssembly)).WhereNotNullRef().ToList(),
jsonNetConverters = config.jsonNetConverters.Select(x => GetTypeOrLog(x.converterName, x.converterAssembly)).WhereNotNullRef().ToList(),
};
}

private static Type GetTypeOrLog(string name)
private static Type GetTypeOrLog(string name, string assemblyName)
{
var type = TypeCache.FindType(name);
var type = TypeCache.FindType(name, assemblyName);
if (type == null)
{
Debug.LogWarning($"Failed to lookup JsonConverter type. Ignoring it. Type name: \"{name}\""+
Expand Down Expand Up @@ -215,7 +215,7 @@ private static IEnumerable<Type> ApplyConfigFilter(IEnumerable<Type> types, bool

var typesOfEnabledThroughConfig = configs
.Where(o => o.enabled)
.Select(o => Utility.TypeCache.FindType(o.converterName))
.Select(o => Utility.TypeCache.FindType(o.converterName, o.converterAssembly))
.Where(o => o != null);

var hashMap = new HashSet<Type>(typesOfEnabledThroughConfig);
Expand Down
Loading