mirror of https://github.com/Cysharp/UniTask
Less raw loops.
parent
95c93b7c3d
commit
5c9c4f5cac
|
@ -68,6 +68,55 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||||
return (buffer, index);
|
return (buffer, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Swap<T>(IList<T> array, int indexA, int indexB)
|
||||||
|
{
|
||||||
|
var tmp = array[indexA];
|
||||||
|
array[indexA] = array[indexB];
|
||||||
|
array[indexB] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the index of the first element satisfying the <paramref name="predicate"/>.
|
||||||
|
/// Returns -1 if no such element exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The array to search.</param>
|
||||||
|
/// <param name="predicate">The predicate use to search the array.</param>
|
||||||
|
/// <typeparam name="T">The type of elements in the array.</typeparam>
|
||||||
|
/// <returns>Index of the first element satisfying the <paramref name="predicate"/> otherwise returns -1.</returns>
|
||||||
|
public static int FirstIndexOf<T>(IReadOnlyList<T> array, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < array.Count; ++i)
|
||||||
|
{
|
||||||
|
if (!predicate(array[i])) continue;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reorders the elements in <paramref name="array"/> in such a way that all elements for which the <paramref name="predicate"/>
|
||||||
|
/// returns <c>true </c> precede the elements for which <paramref name="predicate"/> returns <c>false</c>.
|
||||||
|
/// Relative order of the elements is not preserved.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The array to partition.</param>
|
||||||
|
/// <param name="predicate">The predicate that determine how the elements are partitioned.</param>
|
||||||
|
/// <typeparam name="T">The type of the elements in the array.</typeparam>
|
||||||
|
/// <returns>Return the index of first element of the second group.</returns>
|
||||||
|
public static int Partition<T>(T[] array, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
var pivot = FirstIndexOf(array, element => !predicate(element));
|
||||||
|
if (pivot == -1) return array.Length;
|
||||||
|
for (var i = pivot + 1; i < array.Length; ++i)
|
||||||
|
{
|
||||||
|
if (!predicate(array[i])) continue;
|
||||||
|
Swap(array, pivot, i);
|
||||||
|
++pivot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pivot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
using System;
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cysharp.Threading.Tasks.Internal
|
namespace Cysharp.Threading.Tasks.Internal
|
||||||
|
@ -131,6 +130,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||||
void PostLateUpdate() => RunCore();
|
void PostLateUpdate() => RunCore();
|
||||||
void LastPostLateUpdate() => RunCore();
|
void LastPostLateUpdate() => RunCore();
|
||||||
|
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerHidden]
|
[System.Diagnostics.DebuggerHidden]
|
||||||
void RunCore()
|
void RunCore()
|
||||||
{
|
{
|
||||||
|
@ -141,84 +141,28 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||||
|
|
||||||
lock (arrayLock)
|
lock (arrayLock)
|
||||||
{
|
{
|
||||||
var j = tail - 1;
|
var pivot = ArrayUtil.Partition(loopItems, playerLoopItem =>
|
||||||
|
|
||||||
// eliminate array-bound check for i
|
|
||||||
for (int i = 0; i < loopItems.Length; i++)
|
|
||||||
{
|
{
|
||||||
var action = loopItems[i];
|
try
|
||||||
if (action != null)
|
{
|
||||||
|
return playerLoopItem != null && playerLoopItem.MoveNext();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!action.MoveNext())
|
unhandledExceptionCallback(e);
|
||||||
{
|
return false;
|
||||||
loopItems[i] = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue; // next i
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
loopItems[i] = null;
|
return false;
|
||||||
try
|
|
||||||
{
|
|
||||||
unhandledExceptionCallback(ex);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// find null, loop from tail
|
for (var i = pivot; i < loopItems.Length; ++i)
|
||||||
while (i < j)
|
loopItems[i] = null;
|
||||||
{
|
|
||||||
var fromTail = loopItems[j];
|
|
||||||
if (fromTail != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!fromTail.MoveNext())
|
|
||||||
{
|
|
||||||
loopItems[j] = null;
|
|
||||||
j--;
|
|
||||||
continue; // next j
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// swap
|
|
||||||
loopItems[i] = fromTail;
|
|
||||||
loopItems[j] = null;
|
|
||||||
j--;
|
|
||||||
goto NEXT_LOOP; // next i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
loopItems[j] = null;
|
|
||||||
j--;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
unhandledExceptionCallback(ex);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
continue; // next j
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tail = i; // loop end
|
|
||||||
break; // LOOP END
|
|
||||||
|
|
||||||
NEXT_LOOP:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lock (runningAndQueueLock)
|
lock (runningAndQueueLock)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue