Implement IDeepCloneable interface and refactor methods

Introduced IDeepCloneable interface in AssetRipper.Assets namespace.
Implemented DeepClone method in SerializableStructure and UnloadedStructure.
Updated nested StatelessAsset class to implement IDeepCloneable.
Refactored UnloadedStructure methods using LoadStructureOrStatelessAsset.
Revised FetchDependencies to use an empty array instead of Enumerable.Empty.
Added methods to UnloadedStructure for better equality comparison and asset handling.
This commit is contained in:
ds5678 2025-02-10 10:54:36 -08:00
parent d94213c1d3
commit e0cf8a09a9
3 changed files with 49 additions and 7 deletions

View File

@ -0,0 +1,14 @@
using AssetRipper.Assets.Cloning;
using AssetRipper.Assets.Metadata;
namespace AssetRipper.Assets;
public interface IDeepCloneable
{
/// <summary>
/// Deep clones this object.
/// </summary>
/// <param name="converter">The converter to use for cloning <see cref="PPtr"/>s.</param>
/// <returns>The cloned object.</returns>
IUnityAssetBase DeepClone(PPtrConverter converter);
}

View File

@ -11,7 +11,7 @@ using AssetRipper.SourceGenerated.Classes.ClassID_114;
namespace AssetRipper.Import.Structure.Assembly.Serializable namespace AssetRipper.Import.Structure.Assembly.Serializable
{ {
public sealed class SerializableStructure : UnityAssetBase public sealed class SerializableStructure : UnityAssetBase, IDeepCloneable
{ {
public override int SerializedVersion => Type.Version; public override int SerializedVersion => Type.Version;
public override bool FlowMappedInYaml => Type.FlowMappedInYaml; public override bool FlowMappedInYaml => Type.FlowMappedInYaml;
@ -255,6 +255,8 @@ namespace AssetRipper.Import.Structure.Assembly.Serializable
return clone; return clone;
} }
IUnityAssetBase IDeepCloneable.DeepClone(PPtrConverter converter) => DeepClone(converter);
public override void Reset() public override void Reset()
{ {
foreach (SerializableValue field in Fields) foreach (SerializableValue field in Fields)

View File

@ -15,14 +15,25 @@ namespace AssetRipper.Import.Structure.Assembly.Serializable;
/// This is a placeholder asset that lazily reads the actual structure sometime after all the assets have been loaded. /// This is a placeholder asset that lazily reads the actual structure sometime after all the assets have been loaded.
/// This allows MonoBehaviours to be loaded before their referenced MonoScript. /// This allows MonoBehaviours to be loaded before their referenced MonoScript.
/// </summary> /// </summary>
public sealed class UnloadedStructure : UnityAssetBase public sealed class UnloadedStructure : UnityAssetBase, IDeepCloneable
{ {
private sealed class StatelessAsset : UnityAssetBase private sealed class StatelessAsset : UnityAssetBase, IDeepCloneable
{ {
public static StatelessAsset Instance { get; } = new(); public static StatelessAsset Instance { get; } = new();
private StatelessAsset() private StatelessAsset()
{ {
} }
public override void Reset()
{
}
public override bool? AddToEqualityComparer(IUnityAssetBase other, AssetEqualityComparer comparer)
{
return other is StatelessAsset;
}
IUnityAssetBase IDeepCloneable.DeepClone(PPtrConverter converter) => this;
} }
/// <summary> /// <summary>
@ -75,6 +86,16 @@ public sealed class UnloadedStructure : UnityAssetBase
return null; return null;
} }
private UnityAssetBase LoadStructureOrStatelessAsset()
{
return (UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance;
}
public IUnityAssetBase DeepClone(PPtrConverter converter)
{
return LoadStructure()?.DeepClone(converter) ?? (IUnityAssetBase)StatelessAsset.Instance;
}
#region UnityAssetBase Overrides #region UnityAssetBase Overrides
public override bool FlowMappedInYaml => LoadStructure()?.FlowMappedInYaml ?? base.FlowMappedInYaml; public override bool FlowMappedInYaml => LoadStructure()?.FlowMappedInYaml ?? base.FlowMappedInYaml;
@ -82,22 +103,22 @@ public sealed class UnloadedStructure : UnityAssetBase
public override void WalkEditor(AssetWalker walker) public override void WalkEditor(AssetWalker walker)
{ {
((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkEditor(walker); LoadStructureOrStatelessAsset().WalkEditor(walker);
} }
public override void WalkRelease(AssetWalker walker) public override void WalkRelease(AssetWalker walker)
{ {
((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkRelease(walker); LoadStructureOrStatelessAsset().WalkRelease(walker);
} }
public override void WalkStandard(AssetWalker walker) public override void WalkStandard(AssetWalker walker)
{ {
((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkStandard(walker); LoadStructureOrStatelessAsset().WalkStandard(walker);
} }
public override IEnumerable<(string, PPtr)> FetchDependencies() public override IEnumerable<(string, PPtr)> FetchDependencies()
{ {
return LoadStructure()?.FetchDependencies() ?? Enumerable.Empty<(string, PPtr)>(); return LoadStructure()?.FetchDependencies() ?? [];
} }
public override void WriteEditor(AssetWriter writer) => LoadStructure()?.WriteEditor(writer); public override void WriteEditor(AssetWriter writer) => LoadStructure()?.WriteEditor(writer);
@ -107,5 +128,10 @@ public sealed class UnloadedStructure : UnityAssetBase
public override void CopyValues(IUnityAssetBase? source, PPtrConverter converter) => LoadStructure()?.CopyValues(source, converter); public override void CopyValues(IUnityAssetBase? source, PPtrConverter converter) => LoadStructure()?.CopyValues(source, converter);
public override void Reset() => LoadStructure()?.Reset(); public override void Reset() => LoadStructure()?.Reset();
public override bool? AddToEqualityComparer(IUnityAssetBase other, AssetEqualityComparer comparer)
{
return LoadStructureOrStatelessAsset().AddToEqualityComparer(other, comparer);
}
#endregion #endregion
} }