mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
parent
2e4ce635d0
commit
c5753f3aed
60
Source/AssetRipper.Assets.Tests/AssetEqualityTests.cs
Normal file
60
Source/AssetRipper.Assets.Tests/AssetEqualityTests.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using AssetRipper.Assets.Cloning;
|
||||
using AssetRipper.Assets.Collections;
|
||||
using AssetRipper.Primitives;
|
||||
using AssetRipper.SourceGenerated;
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_1;
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_4;
|
||||
using AssetRipper.SourceGenerated.Extensions;
|
||||
|
||||
namespace AssetRipper.Assets.Tests;
|
||||
|
||||
internal class AssetEqualityTests
|
||||
{
|
||||
[Test]
|
||||
public void DefaultGameObjectEqualityTest()
|
||||
{
|
||||
IGameObject gameObject1 = AssetCreator.Create<IGameObject>(ClassIDType.GameObject, new UnityVersion(2017));
|
||||
IGameObject gameObject2 = AssetCreator.Create<IGameObject>(ClassIDType.GameObject, new UnityVersion(2017));
|
||||
AssetEqualityComparer comparer = new();
|
||||
Assert.That(comparer.Equals(gameObject1, gameObject2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GameObjectWithTransformEqualityTest()
|
||||
{
|
||||
IGameObject gameObject1 = CreateGameObject();
|
||||
IGameObject gameObject2 = CreateGameObject();
|
||||
AssetEqualityComparer comparer = new();
|
||||
Assert.That(comparer.Equals(gameObject1, gameObject2));
|
||||
|
||||
static IGameObject CreateGameObject()
|
||||
{
|
||||
ProcessedAssetCollection collection = AssetCreator.CreateCollection(new UnityVersion(2017));
|
||||
IGameObject gameObject = collection.CreateAsset<IGameObject>(ClassIDType.GameObject);
|
||||
ITransform transform = collection.CreateAsset<ITransform>(ClassIDType.Transform);
|
||||
gameObject.AddComponent(ClassIDType.Transform, transform);
|
||||
transform.GameObject_C4P = gameObject;
|
||||
return gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GameObjectWithTransformInequalityTest()
|
||||
{
|
||||
IGameObject gameObject1 = CreateGameObject(0, 0, 0);
|
||||
IGameObject gameObject2 = CreateGameObject(1, 1, 1);
|
||||
AssetEqualityComparer comparer = new();
|
||||
Assert.That(comparer.Equals(gameObject1, gameObject2), Is.False);
|
||||
|
||||
static IGameObject CreateGameObject(float x, float y, float z)
|
||||
{
|
||||
ProcessedAssetCollection collection = AssetCreator.CreateCollection(new UnityVersion(2017));
|
||||
IGameObject gameObject = collection.CreateAsset<IGameObject>(ClassIDType.GameObject);
|
||||
ITransform transform = collection.CreateAsset<ITransform>(ClassIDType.Transform);
|
||||
transform.LocalPosition_C4.SetValues(x, y, z);
|
||||
gameObject.AddComponent(ClassIDType.Transform, transform);
|
||||
transform.GameObject_C4P = gameObject;
|
||||
return gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AssetRipper.SourceGenerated" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
|
||||
@ -23,6 +22,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetRipper.Assets\AssetRipper.Assets.csproj" />
|
||||
<ProjectReference Include="..\AssetRipper.SourceGenerated.Extensions\AssetRipper.SourceGenerated.Extensions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
using AssetRipper.Assets.Metadata;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AssetRipper.Assets.Cloning
|
||||
{
|
||||
public sealed class AssetEqualityComparer : IEqualityComparer<IUnityObjectBase>
|
||||
{
|
||||
private static readonly Dictionary<UnorderedPair, bool> compareCache = new();
|
||||
private static readonly Dictionary<UnorderedPair, List<UnorderedPair>> dependentEqualityPairs = new();
|
||||
private readonly Dictionary<UnorderedPair, bool> compareCache = new();
|
||||
private readonly Dictionary<UnorderedPair, List<UnorderedPair>> dependentEqualityPairs = new();
|
||||
public IUnityObjectBase CallingObject { get; private set; } = default!;
|
||||
public IUnityObjectBase OtherObject { get; private set; } = default!;
|
||||
|
||||
@ -60,6 +61,7 @@ namespace AssetRipper.Assets.Cloning
|
||||
|
||||
DoComparison(x, y);
|
||||
EvaluateDependentEqualityComparisons();
|
||||
Debug.Assert(dependentEqualityPairs.Count == 0, "Dependent equality pairs should have been resolved");
|
||||
|
||||
return compareCache[(x, y)];
|
||||
}
|
||||
@ -85,10 +87,17 @@ namespace AssetRipper.Assets.Cloning
|
||||
UnorderedPair valuePair = list[i];
|
||||
if (compareCache.TryGetValue(valuePair, out bool value))
|
||||
{
|
||||
compareCache[keyPair] = value;
|
||||
dependentEqualityPairs.Remove(keyPair);
|
||||
hasChanged = true;
|
||||
break;
|
||||
if (value)
|
||||
{
|
||||
list.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
compareCache[keyPair] = false;
|
||||
dependentEqualityPairs.Remove(keyPair);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!dependentEqualityPairs.ContainsKey(valuePair))
|
||||
{
|
||||
@ -107,6 +116,15 @@ namespace AssetRipper.Assets.Cloning
|
||||
}
|
||||
}
|
||||
} while (hasChanged);
|
||||
|
||||
if (dependentEqualityPairs.Count > 0)
|
||||
{
|
||||
foreach ((UnorderedPair keyPair, _) in dependentEqualityPairs)
|
||||
{
|
||||
compareCache[keyPair] = true;
|
||||
}
|
||||
dependentEqualityPairs.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void DoComparison(IUnityObjectBase x, IUnityObjectBase y)
|
||||
|
||||
@ -2,22 +2,31 @@
|
||||
using AssetRipper.Assets.Bundles;
|
||||
using AssetRipper.Assets.Collections;
|
||||
using AssetRipper.Assets.Metadata;
|
||||
using AssetRipper.Primitives;
|
||||
using AssetRipper.SourceGenerated;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AssetRipper.Tests;
|
||||
namespace AssetRipper.SourceGenerated.Extensions;
|
||||
|
||||
internal static class AssetCreator
|
||||
/// <summary>
|
||||
/// A helper class for creating assets, generally for unit testing.
|
||||
/// </summary>
|
||||
public static class AssetCreator
|
||||
{
|
||||
public static T CreateAsset<T>(this ProcessedAssetCollection collection, ClassIDType classID) where T : IUnityObjectBase
|
||||
{
|
||||
return collection.CreateAsset((int)classID, (assetInfo) =>
|
||||
{
|
||||
return (T)AssetFactory.Create(assetInfo);
|
||||
});
|
||||
}
|
||||
|
||||
public static T Create<T>(ClassIDType classID, UnityVersion version, Func<AssetInfo, T> factory) where T : IUnityObjectBase
|
||||
{
|
||||
return MakeCollection(version).CreateAsset<T>((int)classID, factory);
|
||||
return CreateCollection(version).CreateAsset((int)classID, factory);
|
||||
}
|
||||
|
||||
public static T Create<T>(ClassIDType classID, UnityVersion version) where T : IUnityObjectBase
|
||||
{
|
||||
return MakeCollection(version).CreateAsset((int)classID, (assetInfo) =>
|
||||
return CreateCollection(version).CreateAsset((int)classID, (assetInfo) =>
|
||||
{
|
||||
return (T)AssetFactory.Create(assetInfo);
|
||||
});
|
||||
@ -31,7 +40,7 @@ internal static class AssetCreator
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of asset to create.</typeparam>
|
||||
/// <returns>A new asset.</returns>
|
||||
public static T CreateUnsafe<T>() where T : UnityObjectBase
|
||||
public static T CreateUnsafe<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>() where T : UnityObjectBase
|
||||
{
|
||||
return Create(default, default, (assetInfo) =>
|
||||
{
|
||||
@ -48,15 +57,17 @@ internal static class AssetCreator
|
||||
/// </remarks>
|
||||
/// <param name="type">The type of asset to create.</param>
|
||||
/// <returns>A new asset.</returns>
|
||||
public static UnityObjectBase CreateUnsafe(Type type)
|
||||
[RequiresDynamicCode("")]
|
||||
public static UnityObjectBase CreateUnsafe([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type)
|
||||
{
|
||||
#pragma warning disable IL2111 // Method with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
|
||||
return (UnityObjectBase?)typeof(AssetCreator).GetMethod(nameof(CreateUnsafe), 1, BindingFlags.Public | BindingFlags.Static, null, [], null)
|
||||
!.MakeGenericMethod(type)
|
||||
.Invoke(null, null)
|
||||
?? throw new NullReferenceException();
|
||||
.Invoke(null, null) ?? throw new NullReferenceException();
|
||||
#pragma warning restore IL2111 // Method with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
|
||||
}
|
||||
|
||||
private static ProcessedAssetCollection MakeCollection(UnityVersion version)
|
||||
public static ProcessedAssetCollection CreateCollection(UnityVersion version)
|
||||
{
|
||||
GameBundle gameBundle = new();
|
||||
ProcessedAssetCollection collection = gameBundle.AddNewProcessedCollection(nameof(AssetCreator), version);
|
||||
@ -1,5 +1,6 @@
|
||||
using AssetRipper.Assets;
|
||||
using AssetRipper.Export.PrimaryContent;
|
||||
using AssetRipper.SourceGenerated.Extensions;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace AssetRipper.Tests.Traversal;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using AssetRipper.Assets.Metadata;
|
||||
using AssetRipper.Export.UnityProjects;
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_114;
|
||||
using AssetRipper.SourceGenerated.Extensions;
|
||||
using AssetRipper.SourceGenerated.Subclasses.StaticBatchInfo;
|
||||
using AssetRipper.Yaml;
|
||||
using System.Globalization;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_1;
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_114;
|
||||
using AssetRipper.SourceGenerated.Classes.ClassID_142;
|
||||
using AssetRipper.SourceGenerated.Extensions;
|
||||
|
||||
namespace AssetRipper.Tests.Traversal;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user