fix: noisy memory leak warning on Unity 2019 (#700)

Closes: #696
This commit is contained in:
bd_ 2024-02-26 01:03:16 -08:00 committed by GitHub
parent 1666f96d61
commit 7a2385352c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 148 additions and 108 deletions

View File

@ -0,0 +1,41 @@
using System;
namespace nadena.dev.modular_avatar.core.armature_lock
{
internal abstract class ArmatureLock : IDisposable
{
private bool _enableAssemblyReloadCallback;
protected bool EnableAssemblyReloadCallback
{
get => _enableAssemblyReloadCallback;
set
{
if (_enableAssemblyReloadCallback == value) return;
_enableAssemblyReloadCallback = value;
#if UNITY_EDITOR
if (value)
{
UnityEditor.AssemblyReloadEvents.beforeAssemblyReload += OnDomainUnload;
}
else
{
UnityEditor.AssemblyReloadEvents.beforeAssemblyReload -= OnDomainUnload;
}
#endif
}
}
public abstract void Prepare();
public abstract LockResult Execute();
public abstract bool IsStable();
public abstract void Dispose();
private void OnDomainUnload()
{
// Unity 2019 does not call deferred callbacks before domain unload completes,
// so we need to make sure to immediately destroy all our TransformAccessArrays.
DeferDestroy.DestroyImmediate(this);
}
}
}

View File

@ -18,8 +18,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
internal static ArmatureLockConfig instance { get; } = new ArmatureLockConfig();
#endif
[SerializeField]
private bool _globalEnable = true;
[SerializeField] private bool _globalEnable = true;
internal bool GlobalEnable
{
@ -28,10 +27,10 @@ namespace nadena.dev.modular_avatar.core.armature_lock
{
if (value == _globalEnable) return;
#if UNITY_EDITOR
#if UNITY_EDITOR
Undo.RecordObject(this, "Toggle Edit Mode Bone Sync");
Menu.SetChecked(UnityMenuItems.TopMenu_EditModeBoneSync, value);
#endif
#endif
_globalEnable = value;
@ -47,7 +46,8 @@ namespace nadena.dev.modular_avatar.core.armature_lock
[InitializeOnLoadMethod]
static void Init()
{
EditorApplication.delayCall += () => {
EditorApplication.delayCall += () =>
{
Menu.SetChecked(UnityMenuItems.TopMenu_EditModeBoneSync, instance._globalEnable);
};
}
@ -74,7 +74,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
private readonly ModularAvatarMergeArmature _mama;
private readonly GetTransformsDelegate _getTransforms;
private IArmatureLock _lock;
private ArmatureLock _lock;
private bool GlobalEnable => ArmatureLockConfig.instance.GlobalEnable;
private bool _updateActive;
@ -134,7 +134,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
public ArmatureLockController(ModularAvatarMergeArmature mama, GetTransformsDelegate getTransforms)
{
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload += Dispose;
AssemblyReloadEvents.beforeAssemblyReload += OnDomainUnload;
#endif
this._mama = mama;
@ -287,12 +287,19 @@ namespace nadena.dev.modular_avatar.core.armature_lock
_lock?.Dispose();
_lock = null;
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload -= Dispose;
#endif
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload -= OnDomainUnload;
#endif
_controllers.Remove(_mama);
UpdateActive = false;
}
private void OnDomainUnload()
{
// Unity 2019 does not call deferred callbacks before domain unload completes,
// so we need to make sure to immediately destroy all our TransformAccessArrays.
DeferDestroy.DestroyImmediate(this);
}
}
}

View File

@ -13,7 +13,7 @@ using UnityEngine.Jobs;
namespace nadena.dev.modular_avatar.core.armature_lock
{
internal class BidirectionalArmatureLock : IDisposable, IArmatureLock
internal class BidirectionalArmatureLock : ArmatureLock, IDisposable
{
private bool _disposed;
private TransformAccessArray _baseBoneAccess, _mergeBoneAccess;
@ -129,7 +129,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
}
}
public void Dispose()
public override void Dispose()
{
if (_disposed) return;
@ -148,7 +148,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
_disposed = true;
}
public void Prepare()
public override void Prepare()
{
if (_disposed) return;
@ -194,7 +194,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
return true;
}
public bool IsStable()
public override bool IsStable()
{
Prepare();
if (!CheckConsistency()) return false;
@ -203,7 +203,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
return WroteAny.Value == 0;
}
public LockResult Execute()
public override LockResult Execute()
{
if (!CheckConsistency()) return LockResult.Failed;

View File

@ -1,6 +1,7 @@
#region
using System;
using UnityEngine;
#endregion
@ -8,8 +9,29 @@ namespace nadena.dev.modular_avatar.core.armature_lock
{
internal static class DeferDestroy
{
private static bool _immediate = false;
internal static void DestroyImmediate(IDisposable obj)
{
var oldValue = _immediate;
_immediate = true;
try
{
obj.Dispose();
}
finally
{
_immediate = oldValue;
}
}
internal static void DeferDestroyObj(IDisposable obj)
{
if (_immediate)
{
obj.Dispose();
return;
}
#if UNITY_EDITOR
UnityEditor.EditorApplication.delayCall += () => obj.Dispose();
#endif

View File

@ -1,11 +0,0 @@
using System;
namespace nadena.dev.modular_avatar.core.armature_lock
{
internal interface IArmatureLock : IDisposable
{
void Prepare();
LockResult Execute();
bool IsStable();
}
}

View File

@ -16,7 +16,7 @@ using UnityEditor;
namespace nadena.dev.modular_avatar.core.armature_lock
{
internal class OnewayArmatureLock : IDisposable, IArmatureLock
internal class OnewayArmatureLock : ArmatureLock, IDisposable
{
struct BoneStaticData
{
@ -189,9 +189,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
_baseBonesAccessor = new TransformAccessArray(_baseBones);
_mergeBonesAccessor = new TransformAccessArray(_mergeBones);
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload += Dispose;
#endif
EnableAssemblyReloadCallback = true;
}
private bool SmallScale(Vector3 scale)
@ -201,7 +199,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
return (scale.x < epsilon || scale.y < epsilon || scale.z < epsilon);
}
public void Prepare()
public override void Prepare()
{
if (_disposed) return;
@ -255,7 +253,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
return true;
}
public bool IsStable()
public override bool IsStable()
{
Prepare();
if (!CheckConsistency()) return false;
@ -269,7 +267,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
/// Executes the armature lock job.
/// </summary>
/// <returns>True if successful, false if cached data was invalidated and needs recreating</returns>
public LockResult Execute()
public override LockResult Execute()
{
if (!CheckConsistency()) return LockResult.Failed;
@ -296,7 +294,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
}
}
public void Dispose()
public override void Dispose()
{
if (_disposed) return;
@ -312,9 +310,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
DeferDestroy.DeferDestroyObj(_mergeBonesAccessor);
_disposed = true;
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload -= Dispose;
#endif
EnableAssemblyReloadCallback = false;
}
}
}

View File

@ -26,19 +26,18 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3825275463613500755}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.023681391, y: 1.0559628, z: -0.6872994}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3646968714803193661}
- {fileID: 3646968713996568948}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!95 &3825275463613500750
Animator:
serializedVersion: 5
serializedVersion: 3
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@ -51,12 +50,10 @@ Animator:
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
m_KeepAnimatorControllerStateOnDisable: 0
--- !u!114 &3825275463613500753
MonoBehaviour:
m_ObjectHideFlags: 0
@ -325,12 +322,40 @@ MonoBehaviour:
contentType: 0
assetBundleUnityVersion:
fallbackStatus: 0
--- !u!114 &3825275463971368602
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4167925416990528462}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fd7cab7d93b403280f2f9da978d8a4f, type: 3}
m_Name:
m_EditorClassIdentifier:
Bindings:
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_0
LocalBlendshape: shape_0_local
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_1
LocalBlendshape: shape_1
- ReferenceMesh:
referencePath: MissingMesh
Blendshape: missing_mesh_shape
LocalBlendshape: missing_mesh_shape
- ReferenceMesh:
referencePath:
Blendshape: missing_mesh_shape_2
LocalBlendshape: missing_mesh_shape_2
--- !u!1001 &3825275463173128406
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 3825275463613500751}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
@ -429,9 +454,6 @@ PrefabInstance:
value: BaseMesh
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 14ac2ad30c5d3444ca37f76cea5a7047, type: 3}
--- !u!4 &3646968714803193661 stripped
Transform:
@ -444,7 +466,6 @@ PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 3825275463613500751}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
@ -548,52 +569,16 @@ PrefabInstance:
value: SyncedMesh
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
insertIndex: -1
addedObject: {fileID: 3825275463971368602}
m_SourcePrefab: {fileID: 100100000, guid: 14ac2ad30c5d3444ca37f76cea5a7047, type: 3}
--- !u!4 &3646968713996568948 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
--- !u!1 &4167925416990528462 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
--- !u!114 &3825275463971368602
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
--- !u!4 &3646968713996568948 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4167925416990528462}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fd7cab7d93b403280f2f9da978d8a4f, type: 3}
m_Name:
m_EditorClassIdentifier:
Bindings:
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_0
LocalBlendshape: shape_0_local
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_1
LocalBlendshape: shape_1
- ReferenceMesh:
referencePath: MissingMesh
Blendshape: missing_mesh_shape
LocalBlendshape: missing_mesh_shape
- ReferenceMesh:
referencePath:
Blendshape: missing_mesh_shape_2
LocalBlendshape: missing_mesh_shape_2