|
|
|
@ -101,7 +101,9 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
[Flags]
|
|
|
|
|
public enum InjectPlayerLoopTimings
|
|
|
|
|
{
|
|
|
|
|
// Preset
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Preset: All loops(default).
|
|
|
|
|
/// </summary>
|
|
|
|
|
All =
|
|
|
|
|
Initialization | LastInitialization |
|
|
|
|
|
EarlyUpdate | LastEarlyUpdate |
|
|
|
|
@ -114,6 +116,9 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
TimeUpdate | LastTimeUpdate,
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Preset: All without last except LastPostLateUpdate.
|
|
|
|
|
/// </summary>
|
|
|
|
|
Standard =
|
|
|
|
|
Initialization |
|
|
|
|
|
EarlyUpdate |
|
|
|
|
@ -126,6 +131,9 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
TimeUpdate,
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Preset: Minimum pattern, Update | FixedUpdate | LastPostLateUpdate
|
|
|
|
|
/// </summary>
|
|
|
|
|
Minimum =
|
|
|
|
|
Update | FixedUpdate | LastPostLateUpdate,
|
|
|
|
|
|
|
|
|
@ -167,6 +175,9 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
|
|
|
|
|
public static class PlayerLoopHelper
|
|
|
|
|
{
|
|
|
|
|
static readonly ContinuationQueue ThrowMarkerContinuationQueue = new ContinuationQueue(PlayerLoopTiming.Initialization);
|
|
|
|
|
static readonly PlayerLoopRunner ThrowMarkerPlayerLoopRunner = new PlayerLoopRunner(PlayerLoopTiming.Initialization);
|
|
|
|
|
|
|
|
|
|
public static SynchronizationContext UnitySynchronizationContext => unitySynchronizationContetext;
|
|
|
|
|
public static int MainThreadId => mainThreadId;
|
|
|
|
|
internal static string ApplicationDataPath => applicationDataPath;
|
|
|
|
@ -220,10 +231,7 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Remove items from previous initializations.
|
|
|
|
|
var source = loopSystem.subSystemList
|
|
|
|
|
.Where(ls => ls.type != loopRunnerYieldType && ls.type != loopRunnerType)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
var source = RemoveRunner(loopSystem, loopRunnerYieldType, loopRunnerType);
|
|
|
|
|
var dest = new PlayerLoopSystem[source.Length + 2];
|
|
|
|
|
|
|
|
|
|
Array.Copy(source, 0, dest, injectOnFirst ? 2 : 0, source.Length);
|
|
|
|
@ -241,6 +249,13 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
return dest;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PlayerLoopSystem[] RemoveRunner(PlayerLoopSystem loopSystem, Type loopRunnerYieldType, Type loopRunnerType)
|
|
|
|
|
{
|
|
|
|
|
return loopSystem.subSystemList
|
|
|
|
|
.Where(ls => ls.type != loopRunnerYieldType && ls.type != loopRunnerType)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PlayerLoopSystem[] InsertUniTaskSynchronizationContext(PlayerLoopSystem loopSystem)
|
|
|
|
|
{
|
|
|
|
|
var loop = new PlayerLoopSystem
|
|
|
|
@ -357,6 +372,22 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
throw new Exception("Target PlayerLoopSystem does not found. Type:" + systemType.FullName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void InsertLoop(PlayerLoopSystem[] copyList, InjectPlayerLoopTimings injectTimings, Type loopType, InjectPlayerLoopTimings targetTimings,
|
|
|
|
|
int index, bool injectOnFirst, Type loopRunnerYieldType, Type loopRunnerType, PlayerLoopTiming playerLoopTiming)
|
|
|
|
|
{
|
|
|
|
|
var i = FindLoopSystemIndex(copyList, loopType);
|
|
|
|
|
if ((injectTimings & targetTimings) == targetTimings)
|
|
|
|
|
{
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], injectOnFirst,
|
|
|
|
|
loopRunnerYieldType, yielders[index] = new ContinuationQueue(playerLoopTiming),
|
|
|
|
|
loopRunnerType, runners[index] = new PlayerLoopRunner(playerLoopTiming));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
copyList[i].subSystemList = RemoveRunner(copyList[i], loopRunnerYieldType, loopRunnerType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Initialize(ref PlayerLoopSystem playerLoop, InjectPlayerLoopTimings injectTimings = InjectPlayerLoopTimings.All)
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_2020_2_OR_NEWER
|
|
|
|
@ -369,60 +400,82 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
|
|
|
|
|
var copyList = playerLoop.subSystemList.ToArray();
|
|
|
|
|
|
|
|
|
|
var i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Initialization));
|
|
|
|
|
if (injectTimings | InjectPlayerLoopTimings.
|
|
|
|
|
// Initialization
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Initialization),
|
|
|
|
|
InjectPlayerLoopTimings.Initialization, 0, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), PlayerLoopTiming.Initialization);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Initialization),
|
|
|
|
|
InjectPlayerLoopTimings.LastInitialization, 1, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldInitialization), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastInitialization), PlayerLoopTiming.LastInitialization);
|
|
|
|
|
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), yielders[0] = new ContinuationQueue(PlayerLoopTiming.Initialization),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldInitialization), yielders[1] = new ContinuationQueue(PlayerLoopTiming.LastInitialization),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), runners[0] = new PlayerLoopRunner(PlayerLoopTiming.Initialization),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastInitialization), runners[1] = new PlayerLoopRunner(PlayerLoopTiming.LastInitialization));
|
|
|
|
|
// EarlyUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.EarlyUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), yielders[2] = new ContinuationQueue(PlayerLoopTiming.EarlyUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldEarlyUpdate), yielders[3] = new ContinuationQueue(PlayerLoopTiming.LastEarlyUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), runners[2] = new PlayerLoopRunner(PlayerLoopTiming.EarlyUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastEarlyUpdate), runners[3] = new PlayerLoopRunner(PlayerLoopTiming.LastEarlyUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.EarlyUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.EarlyUpdate, 2, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), PlayerLoopTiming.EarlyUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.EarlyUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastEarlyUpdate, 3, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldEarlyUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastEarlyUpdate), PlayerLoopTiming.LastEarlyUpdate);
|
|
|
|
|
|
|
|
|
|
// FixedUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.FixedUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), yielders[4] = new ContinuationQueue(PlayerLoopTiming.FixedUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldFixedUpdate), yielders[5] = new ContinuationQueue(PlayerLoopTiming.LastFixedUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), runners[4] = new PlayerLoopRunner(PlayerLoopTiming.FixedUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastFixedUpdate), runners[5] = new PlayerLoopRunner(PlayerLoopTiming.LastFixedUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.FixedUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.FixedUpdate, 4, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), PlayerLoopTiming.FixedUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.FixedUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastFixedUpdate, 5, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldFixedUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastFixedUpdate), PlayerLoopTiming.LastFixedUpdate);
|
|
|
|
|
|
|
|
|
|
// PreUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.PreUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), yielders[6] = new ContinuationQueue(PlayerLoopTiming.PreUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreUpdate), yielders[7] = new ContinuationQueue(PlayerLoopTiming.LastPreUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), runners[6] = new PlayerLoopRunner(PlayerLoopTiming.PreUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreUpdate), runners[7] = new PlayerLoopRunner(PlayerLoopTiming.LastPreUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.PreUpdate, 6, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), PlayerLoopTiming.PreUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastPreUpdate, 7, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreUpdate), PlayerLoopTiming.LastPreUpdate);
|
|
|
|
|
|
|
|
|
|
// Update
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Update));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), yielders[8] = new ContinuationQueue(PlayerLoopTiming.Update),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldUpdate), yielders[9] = new ContinuationQueue(PlayerLoopTiming.LastUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), runners[8] = new PlayerLoopRunner(PlayerLoopTiming.Update),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastUpdate), runners[9] = new PlayerLoopRunner(PlayerLoopTiming.LastUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Update),
|
|
|
|
|
InjectPlayerLoopTimings.Update, 8, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), PlayerLoopTiming.Update);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.Update),
|
|
|
|
|
InjectPlayerLoopTimings.LastUpdate, 9, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastUpdate), PlayerLoopTiming.LastUpdate);
|
|
|
|
|
|
|
|
|
|
// PreLateUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.PreLateUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), yielders[10] = new ContinuationQueue(PlayerLoopTiming.PreLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreLateUpdate), yielders[11] = new ContinuationQueue(PlayerLoopTiming.LastPreLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), runners[10] = new PlayerLoopRunner(PlayerLoopTiming.PreLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreLateUpdate), runners[11] = new PlayerLoopRunner(PlayerLoopTiming.LastPreLateUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreLateUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.PreLateUpdate, 10, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), PlayerLoopTiming.PreLateUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PreLateUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastPreLateUpdate, 11, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreLateUpdate), PlayerLoopTiming.LastPreLateUpdate);
|
|
|
|
|
|
|
|
|
|
// PostLateUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.PostLateUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), yielders[12] = new ContinuationQueue(PlayerLoopTiming.PostLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPostLateUpdate), yielders[13] = new ContinuationQueue(PlayerLoopTiming.LastPostLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), runners[12] = new PlayerLoopRunner(PlayerLoopTiming.PostLateUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPostLateUpdate), runners[13] = new PlayerLoopRunner(PlayerLoopTiming.LastPostLateUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PostLateUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.PostLateUpdate, 12, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), PlayerLoopTiming.PostLateUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.PostLateUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastPostLateUpdate, 13, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPostLateUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPostLateUpdate), PlayerLoopTiming.LastPostLateUpdate);
|
|
|
|
|
|
|
|
|
|
#if UNITY_2020_2_OR_NEWER
|
|
|
|
|
// TimeUpdate
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.TimeUpdate));
|
|
|
|
|
copyList[i].subSystemList = InsertRunner(copyList[i], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldTimeUpdate), yielders[14] = new ContinuationQueue(PlayerLoopTiming.TimeUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldTimeUpdate), yielders[15] = new ContinuationQueue(PlayerLoopTiming.LastTimeUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerTimeUpdate), runners[14] = new PlayerLoopRunner(PlayerLoopTiming.TimeUpdate),
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastTimeUpdate), runners[15] = new PlayerLoopRunner(PlayerLoopTiming.LastTimeUpdate));
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.TimeUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.TimeUpdate, 14, true,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldTimeUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerTimeUpdate), PlayerLoopTiming.TimeUpdate);
|
|
|
|
|
|
|
|
|
|
InsertLoop(copyList, injectTimings, typeof(PlayerLoopType.TimeUpdate),
|
|
|
|
|
InjectPlayerLoopTimings.LastTimeUpdate, 15, false,
|
|
|
|
|
typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldTimeUpdate), typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastTimeUpdate), PlayerLoopTiming.LastTimeUpdate);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Insert UniTaskSynchronizationContext to Update loop
|
|
|
|
|
i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Update));
|
|
|
|
|
var i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Update));
|
|
|
|
|
copyList[i].subSystemList = InsertUniTaskSynchronizationContext(copyList[i]);
|
|
|
|
|
|
|
|
|
|
playerLoop.subSystemList = copyList;
|
|
|
|
@ -431,12 +484,27 @@ namespace Cysharp.Threading.Tasks
|
|
|
|
|
|
|
|
|
|
public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action)
|
|
|
|
|
{
|
|
|
|
|
runners[(int)timing].AddAction(action);
|
|
|
|
|
var runner = runners[(int)timing];
|
|
|
|
|
if (runner == null)
|
|
|
|
|
{
|
|
|
|
|
ThrowInvalidLoopTiming(timing);
|
|
|
|
|
}
|
|
|
|
|
runner.AddAction(action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ThrowInvalidLoopTiming(PlayerLoopTiming playerLoopTiming)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Target playerLoopTiming is not injected. Please check PlayerLoopHelper.Initialize. PlayerLoopTiming:" + playerLoopTiming);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void AddContinuation(PlayerLoopTiming timing, Action continuation)
|
|
|
|
|
{
|
|
|
|
|
yielders[(int)timing].Enqueue(continuation);
|
|
|
|
|
var q = yielders[(int)timing];
|
|
|
|
|
if (q == null)
|
|
|
|
|
{
|
|
|
|
|
ThrowInvalidLoopTiming(timing);
|
|
|
|
|
}
|
|
|
|
|
q.Enqueue(continuation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Diagnostics helper
|
|
|
|
|