Merge pull request #487 from Cysharp/hadashiA/fix-test
Fix TriggerEvent problem with iterate breaking on Remove when it has multiple handlersmaster
commit
c170af5642
|
@ -20,8 +20,6 @@ namespace Cysharp.Threading.Tasks
|
||||||
{
|
{
|
||||||
ITriggerHandler<T> head; // head.prev is last
|
ITriggerHandler<T> head; // head.prev is last
|
||||||
ITriggerHandler<T> iteratingHead;
|
ITriggerHandler<T> iteratingHead;
|
||||||
|
|
||||||
bool preserveRemoveSelf;
|
|
||||||
ITriggerHandler<T> iteratingNode;
|
ITriggerHandler<T> iteratingNode;
|
||||||
|
|
||||||
void LogError(Exception ex)
|
void LogError(Exception ex)
|
||||||
|
@ -55,18 +53,9 @@ namespace Cysharp.Threading.Tasks
|
||||||
Remove(h);
|
Remove(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preserveRemoveSelf)
|
// If `h` itself is removed by OnNext, h.Next is null.
|
||||||
{
|
// Therefore, instead of looking at h.Next, the `iteratingNode` reference itself is replaced.
|
||||||
preserveRemoveSelf = false;
|
h = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
|
||||||
h = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h = h.Next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
|
@ -97,9 +86,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
|
@ -132,9 +120,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
|
@ -167,9 +154,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
LogError(ex);
|
LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
preserveRemoveSelf = false;
|
var next = h == iteratingNode ? h.Next : iteratingNode;
|
||||||
iteratingNode = null;
|
iteratingNode = null;
|
||||||
var next = h.Next;
|
|
||||||
Remove(h);
|
Remove(h);
|
||||||
h = next;
|
h = next;
|
||||||
}
|
}
|
||||||
|
@ -241,71 +227,65 @@ namespace Cysharp.Threading.Tasks
|
||||||
{
|
{
|
||||||
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
if (handler == null) throw new ArgumentNullException(nameof(handler));
|
||||||
|
|
||||||
if (iteratingNode != null && iteratingNode == handler)
|
var prev = handler.Prev;
|
||||||
|
var next = handler.Next;
|
||||||
|
|
||||||
|
if (next != null)
|
||||||
{
|
{
|
||||||
// if remove self, reserve remove self after invoke completed.
|
next.Prev = prev;
|
||||||
preserveRemoveSelf = true;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (handler == head)
|
||||||
{
|
{
|
||||||
var prev = handler.Prev;
|
head = next;
|
||||||
var next = handler.Next;
|
|
||||||
|
|
||||||
if (next != null)
|
|
||||||
{
|
|
||||||
next.Prev = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler == head)
|
|
||||||
{
|
|
||||||
head = next;
|
|
||||||
}
|
|
||||||
else if (handler == iteratingHead)
|
|
||||||
{
|
|
||||||
iteratingHead = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// when handler is head, prev indicate last so don't use it.
|
|
||||||
if (prev != null)
|
|
||||||
{
|
|
||||||
prev.Next = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (head != null)
|
|
||||||
{
|
|
||||||
if (head.Prev == handler)
|
|
||||||
{
|
|
||||||
if (prev != head)
|
|
||||||
{
|
|
||||||
head.Prev = prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
head.Prev = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iteratingHead != null)
|
|
||||||
{
|
|
||||||
if (iteratingHead.Prev == handler)
|
|
||||||
{
|
|
||||||
if (prev != iteratingHead.Prev)
|
|
||||||
{
|
|
||||||
iteratingHead.Prev = prev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iteratingHead.Prev = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.Prev = null;
|
|
||||||
handler.Next = null;
|
|
||||||
}
|
}
|
||||||
|
// when handler is head, prev indicate last so don't use it.
|
||||||
|
else if (prev != null)
|
||||||
|
{
|
||||||
|
prev.Next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler == iteratingNode)
|
||||||
|
{
|
||||||
|
iteratingNode = next;
|
||||||
|
}
|
||||||
|
if (handler == iteratingHead)
|
||||||
|
{
|
||||||
|
iteratingHead = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head != null)
|
||||||
|
{
|
||||||
|
if (head.Prev == handler)
|
||||||
|
{
|
||||||
|
if (prev != head)
|
||||||
|
{
|
||||||
|
head.Prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.Prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iteratingHead != null)
|
||||||
|
{
|
||||||
|
if (iteratingHead.Prev == handler)
|
||||||
|
{
|
||||||
|
if (prev != iteratingHead.Prev)
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iteratingHead.Prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Prev = null;
|
||||||
|
handler.Next = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue