From e0cf8a09a99ec05e5fb01296ec23c7db363e7508 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Mon, 10 Feb 2025 10:54:36 -0800 Subject: [PATCH] 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. --- Source/AssetRipper.Assets/IDeepCloneable.cs | 14 +++++++ .../Serializable/SerializableStructure.cs | 4 +- .../Serializable/UnloadedStructure.cs | 38 ++++++++++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 Source/AssetRipper.Assets/IDeepCloneable.cs diff --git a/Source/AssetRipper.Assets/IDeepCloneable.cs b/Source/AssetRipper.Assets/IDeepCloneable.cs new file mode 100644 index 000000000..4a1c8f938 --- /dev/null +++ b/Source/AssetRipper.Assets/IDeepCloneable.cs @@ -0,0 +1,14 @@ +using AssetRipper.Assets.Cloning; +using AssetRipper.Assets.Metadata; + +namespace AssetRipper.Assets; + +public interface IDeepCloneable +{ + /// + /// Deep clones this object. + /// + /// The converter to use for cloning s. + /// The cloned object. + IUnityAssetBase DeepClone(PPtrConverter converter); +} diff --git a/Source/AssetRipper.Import/Structure/Assembly/Serializable/SerializableStructure.cs b/Source/AssetRipper.Import/Structure/Assembly/Serializable/SerializableStructure.cs index 4a71e3120..c22421674 100644 --- a/Source/AssetRipper.Import/Structure/Assembly/Serializable/SerializableStructure.cs +++ b/Source/AssetRipper.Import/Structure/Assembly/Serializable/SerializableStructure.cs @@ -11,7 +11,7 @@ using AssetRipper.SourceGenerated.Classes.ClassID_114; 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 bool FlowMappedInYaml => Type.FlowMappedInYaml; @@ -255,6 +255,8 @@ namespace AssetRipper.Import.Structure.Assembly.Serializable return clone; } + IUnityAssetBase IDeepCloneable.DeepClone(PPtrConverter converter) => DeepClone(converter); + public override void Reset() { foreach (SerializableValue field in Fields) diff --git a/Source/AssetRipper.Import/Structure/Assembly/Serializable/UnloadedStructure.cs b/Source/AssetRipper.Import/Structure/Assembly/Serializable/UnloadedStructure.cs index 7398235b8..7cdc87d88 100644 --- a/Source/AssetRipper.Import/Structure/Assembly/Serializable/UnloadedStructure.cs +++ b/Source/AssetRipper.Import/Structure/Assembly/Serializable/UnloadedStructure.cs @@ -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 allows MonoBehaviours to be loaded before their referenced MonoScript. /// -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(); private StatelessAsset() { } + + public override void Reset() + { + } + + public override bool? AddToEqualityComparer(IUnityAssetBase other, AssetEqualityComparer comparer) + { + return other is StatelessAsset; + } + + IUnityAssetBase IDeepCloneable.DeepClone(PPtrConverter converter) => this; } /// @@ -75,6 +86,16 @@ public sealed class UnloadedStructure : UnityAssetBase 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 public override bool FlowMappedInYaml => LoadStructure()?.FlowMappedInYaml ?? base.FlowMappedInYaml; @@ -82,22 +103,22 @@ public sealed class UnloadedStructure : UnityAssetBase public override void WalkEditor(AssetWalker walker) { - ((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkEditor(walker); + LoadStructureOrStatelessAsset().WalkEditor(walker); } public override void WalkRelease(AssetWalker walker) { - ((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkRelease(walker); + LoadStructureOrStatelessAsset().WalkRelease(walker); } public override void WalkStandard(AssetWalker walker) { - ((UnityAssetBase?)LoadStructure() ?? StatelessAsset.Instance).WalkStandard(walker); + LoadStructureOrStatelessAsset().WalkStandard(walker); } 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); @@ -107,5 +128,10 @@ public sealed class UnloadedStructure : UnityAssetBase public override void CopyValues(IUnityAssetBase? source, PPtrConverter converter) => LoadStructure()?.CopyValues(source, converter); public override void Reset() => LoadStructure()?.Reset(); + + public override bool? AddToEqualityComparer(IUnityAssetBase other, AssetEqualityComparer comparer) + { + return LoadStructureOrStatelessAsset().AddToEqualityComparer(other, comparer); + } #endregion }