-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
while raising, if an unregister happens:
- a listener that was already handled will swap indices with the last element on unregister, making the last listener being not invoked
- iterating backwards has the issue just the other way arround: that newly registered listeners would be not detected.
- in general raise should be somewhat "atomic" and adding listeners to an event that is being raised right now should not have immediate effect, but only on the next raise invocation.
In my changes I keep a list of "mutations" if raise is being invoked right now. also, Raise could be invoked in a nested fashion.
public static void Raise(T ev)
{
...
raiseStackDepth++;
try
{
for (int i = 0, n = bindings.Count; i < n; i++)
{
var internalBind = bindings[i];
internalBind.OnEvent?.Invoke(ev);
internalBind.OnEventArgs?.Invoke();
}
}
finally
{
raiseStackDepth--;
if (raiseStackDepth == 0)
{
foreach (var mutation in mutations)
{
if (mutation.Type == EventBindingMutation<T>.MutationType.Register)
Register(mutation.Binding);
else if (mutation.Type == EventBindingMutation<T>.MutationType.Unregister)
Unregister(mutation.Binding);
}
mutations.Clear();
}
}
...
}
furthermore:
handling the array manually has barely any benefit over using a List<> as resizing logic is basically the same.
Metadata
Metadata
Assignees
Labels
No labels