diff --git a/Assets/Mirror/Core/NetworkBehaviour.cs b/Assets/Mirror/Core/NetworkBehaviour.cs index 1f885f0176..7e820e1a24 100644 --- a/Assets/Mirror/Core/NetworkBehaviour.cs +++ b/Assets/Mirror/Core/NetworkBehaviour.cs @@ -766,6 +766,13 @@ public static bool SyncVarNetworkIdentityEqual(NetworkIdentity newIdentity, uint return newNetId == netIdField; } + // Anonymous method instance is instantiated upon entering the method containing it. + // Deferred hooks should only be added in a nested method to avoid allocations when not adding a deferred hook. + void AddDeferredSyncVarHook(Action hook, T capturedPrevious, T capturedNew) + { + deferredSyncVarHooks.Add(() => hook(capturedPrevious, capturedNew)); + } + // move the [SyncVar] generated OnDeserialize C# to avoid much IL. // // before: @@ -832,7 +839,7 @@ public void GeneratedSyncVarDeserialize(ref T field, Action OnChanged, // Capture values in closure for deferred execution T capturedPrevious = previous; T capturedNew = field; - deferredSyncVarHooks.Add(() => OnChanged(capturedPrevious, capturedNew)); + AddDeferredSyncVarHook(OnChanged, capturedPrevious, capturedNew); } else { @@ -910,7 +917,7 @@ public void GeneratedSyncVarDeserialize_GameObject(ref GameObject field, Action< { GameObject capturedPrevious = previousGameObject; GameObject capturedNew = field; - deferredSyncVarHooks.Add(() => OnChanged(capturedPrevious, capturedNew)); + AddDeferredSyncVarHook(OnChanged, capturedPrevious, capturedNew); } else { @@ -988,7 +995,7 @@ public void GeneratedSyncVarDeserialize_NetworkIdentity(ref NetworkIdentity fiel { NetworkIdentity capturedPrevious = previousIdentity; NetworkIdentity capturedNew = field; - deferredSyncVarHooks.Add(() => OnChanged(capturedPrevious, capturedNew)); + AddDeferredSyncVarHook(OnChanged, capturedPrevious, capturedNew); } else { @@ -1068,7 +1075,7 @@ public void GeneratedSyncVarDeserialize_NetworkBehaviour(ref T field, Action< { T capturedPrevious = previousBehaviour; T capturedNew = field; - deferredSyncVarHooks.Add(() => OnChanged(capturedPrevious, capturedNew)); + AddDeferredSyncVarHook(OnChanged, capturedPrevious, capturedNew); } else { diff --git a/Assets/Mirror/Core/SyncDictionary.cs b/Assets/Mirror/Core/SyncDictionary.cs index f9555715be..d0fb04e74e 100644 --- a/Assets/Mirror/Core/SyncDictionary.cs +++ b/Assets/Mirror/Core/SyncDictionary.cs @@ -378,9 +378,7 @@ void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool chec TKey capturedKey = key; TValue capturedItem = item; TValue capturedOld = oldItem; - - networkBehaviour.deferredSyncCollectionActions.Add(() => - InvokeActions(capturedOp, capturedKey, capturedItem, capturedOld)); + AddDeferredOperation(capturedOp, capturedKey, capturedItem, capturedOld); } else { @@ -390,6 +388,12 @@ void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool chec } } + void AddDeferredOperation(Operation capturedOp, TKey capturedKey, TValue capturedItem, TValue capturedOld) + { + networkBehaviour.deferredSyncCollectionActions.Add(() => + InvokeActions(capturedOp, capturedKey, capturedItem, capturedOld)); + } + void InvokeActions(Operation op, TKey key, TValue item, TValue oldItem) { switch (op) diff --git a/Assets/Mirror/Core/SyncList.cs b/Assets/Mirror/Core/SyncList.cs index eec88f13e8..d7b186bd02 100644 --- a/Assets/Mirror/Core/SyncList.cs +++ b/Assets/Mirror/Core/SyncList.cs @@ -139,9 +139,7 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA int capturedIndex = itemIndex; T capturedOld = oldItem; T capturedNew = newItem; - - networkBehaviour.deferredSyncCollectionActions.Add(() => - InvokeActions(capturedOp, capturedIndex, capturedOld, capturedNew)); + AddDeferredOperation(capturedOp, capturedIndex, capturedOld, capturedNew); } else { @@ -151,6 +149,12 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA } } + void AddDeferredOperation(Operation capturedOp, int capturedIndex, T capturedOld, T capturedNew) + { + networkBehaviour.deferredSyncCollectionActions.Add(() => + InvokeActions(capturedOp, capturedIndex, capturedOld, capturedNew)); + } + void InvokeActions(Operation op, int itemIndex, T oldItem, T newItem) { switch (op) diff --git a/Assets/Mirror/Core/SyncSet.cs b/Assets/Mirror/Core/SyncSet.cs index a098e1164d..8ff3bd5ae2 100644 --- a/Assets/Mirror/Core/SyncSet.cs +++ b/Assets/Mirror/Core/SyncSet.cs @@ -130,9 +130,7 @@ void AddOperation(Operation op, T oldItem, T newItem, bool checkAccess, bool sho Operation capturedOp = op; T capturedOld = oldItem; T capturedNew = newItem; - - networkBehaviour.deferredSyncCollectionActions.Add(() => - InvokeActions(capturedOp, capturedOld, capturedNew)); + AddDeferredOperation(capturedOp, capturedOld, capturedNew); } else { @@ -142,6 +140,12 @@ void AddOperation(Operation op, T oldItem, T newItem, bool checkAccess, bool sho } } + void AddDeferredOperation(Operation capturedOp, T capturedOld, T capturedNew) + { + networkBehaviour.deferredSyncCollectionActions.Add(() => + InvokeActions(capturedOp, capturedOld, capturedNew)); + } + void AddOperation(Operation op, bool checkAccess) => AddOperation(op, default, default, checkAccess, true); void InvokeActions(Operation op, T oldItem, T newItem)