A game about forced loneliness, made by TACStudios
1namespace UnityEngine.InputSystem.Utilities
2{
3 // Keeps a copy of the callback list while executing so that the callback list can safely
4 // be mutated from within callbacks.
5 internal struct CallbackArray<TDelegate>
6 where TDelegate : System.Delegate
7 {
8 private bool m_CannotMutateCallbacksArray;
9 private InlinedArray<TDelegate> m_Callbacks;
10 private InlinedArray<TDelegate> m_CallbacksToAdd;
11 private InlinedArray<TDelegate> m_CallbacksToRemove;
12
13 public int length => m_Callbacks.length;
14
15 public TDelegate this[int index] => m_Callbacks[index];
16
17 public void Clear()
18 {
19 m_Callbacks.Clear();
20 m_CallbacksToAdd.Clear();
21 m_CallbacksToRemove.Clear();
22 }
23
24 public void AddCallback(TDelegate dlg)
25 {
26 if (m_CannotMutateCallbacksArray)
27 {
28 if (m_CallbacksToAdd.Contains(dlg))
29 return;
30 var removeIndex = m_CallbacksToRemove.IndexOf(dlg);
31 if (removeIndex != -1)
32 m_CallbacksToRemove.RemoveAtByMovingTailWithCapacity(removeIndex);
33 m_CallbacksToAdd.AppendWithCapacity(dlg);
34 return;
35 }
36
37 if (!m_Callbacks.Contains(dlg))
38 m_Callbacks.AppendWithCapacity(dlg, capacityIncrement: 4);
39 }
40
41 public void RemoveCallback(TDelegate dlg)
42 {
43 if (m_CannotMutateCallbacksArray)
44 {
45 if (m_CallbacksToRemove.Contains(dlg))
46 return;
47 var addIndex = m_CallbacksToAdd.IndexOf(dlg);
48 if (addIndex != -1)
49 m_CallbacksToAdd.RemoveAtByMovingTailWithCapacity(addIndex);
50 m_CallbacksToRemove.AppendWithCapacity(dlg);
51 return;
52 }
53
54 var index = m_Callbacks.IndexOf(dlg);
55 if (index >= 0)
56 m_Callbacks.RemoveAtWithCapacity(index);
57 }
58
59 public void LockForChanges()
60 {
61 m_CannotMutateCallbacksArray = true;
62 }
63
64 public void UnlockForChanges()
65 {
66 m_CannotMutateCallbacksArray = false;
67
68 // Process mutations that have happened while we were executing callbacks.
69 for (var i = 0; i < m_CallbacksToRemove.length; ++i)
70 RemoveCallback(m_CallbacksToRemove[i]);
71 for (var i = 0; i < m_CallbacksToAdd.length; ++i)
72 AddCallback(m_CallbacksToAdd[i]);
73
74 m_CallbacksToAdd.Clear();
75 m_CallbacksToRemove.Clear();
76 }
77 }
78}