mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
更新Demo
更新Demo
This commit is contained in:
581
UnityProject/Packages/UniTask/Runtime/PlayerLoopHelper.cs
Normal file
581
UnityProject/Packages/UniTask/Runtime/PlayerLoopHelper.cs
Normal file
@@ -0,0 +1,581 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System.Threading;
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
using UnityEngine.LowLevel;
|
||||
using PlayerLoopType = UnityEngine.PlayerLoop;
|
||||
#else
|
||||
using UnityEngine.Experimental.LowLevel;
|
||||
using PlayerLoopType = UnityEngine.Experimental.PlayerLoop;
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class UniTaskLoopRunners
|
||||
{
|
||||
public struct UniTaskLoopRunnerInitialization { };
|
||||
public struct UniTaskLoopRunnerEarlyUpdate { };
|
||||
public struct UniTaskLoopRunnerFixedUpdate { };
|
||||
public struct UniTaskLoopRunnerPreUpdate { };
|
||||
public struct UniTaskLoopRunnerUpdate { };
|
||||
public struct UniTaskLoopRunnerPreLateUpdate { };
|
||||
public struct UniTaskLoopRunnerPostLateUpdate { };
|
||||
|
||||
// Last
|
||||
|
||||
public struct UniTaskLoopRunnerLastInitialization { };
|
||||
public struct UniTaskLoopRunnerLastEarlyUpdate { };
|
||||
public struct UniTaskLoopRunnerLastFixedUpdate { };
|
||||
public struct UniTaskLoopRunnerLastPreUpdate { };
|
||||
public struct UniTaskLoopRunnerLastUpdate { };
|
||||
public struct UniTaskLoopRunnerLastPreLateUpdate { };
|
||||
public struct UniTaskLoopRunnerLastPostLateUpdate { };
|
||||
|
||||
// Yield
|
||||
|
||||
public struct UniTaskLoopRunnerYieldInitialization { };
|
||||
public struct UniTaskLoopRunnerYieldEarlyUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldFixedUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldPreUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldPreLateUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldPostLateUpdate { };
|
||||
|
||||
// Yield Last
|
||||
|
||||
public struct UniTaskLoopRunnerLastYieldInitialization { };
|
||||
public struct UniTaskLoopRunnerLastYieldEarlyUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldFixedUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldPreUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldPreLateUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldPostLateUpdate { };
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
public struct UniTaskLoopRunnerTimeUpdate { };
|
||||
public struct UniTaskLoopRunnerLastTimeUpdate { };
|
||||
public struct UniTaskLoopRunnerYieldTimeUpdate { };
|
||||
public struct UniTaskLoopRunnerLastYieldTimeUpdate { };
|
||||
#endif
|
||||
}
|
||||
|
||||
public enum PlayerLoopTiming
|
||||
{
|
||||
Initialization = 0,
|
||||
LastInitialization = 1,
|
||||
|
||||
EarlyUpdate = 2,
|
||||
LastEarlyUpdate = 3,
|
||||
|
||||
FixedUpdate = 4,
|
||||
LastFixedUpdate = 5,
|
||||
|
||||
PreUpdate = 6,
|
||||
LastPreUpdate = 7,
|
||||
|
||||
Update = 8,
|
||||
LastUpdate = 9,
|
||||
|
||||
PreLateUpdate = 10,
|
||||
LastPreLateUpdate = 11,
|
||||
|
||||
PostLateUpdate = 12,
|
||||
LastPostLateUpdate = 13,
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
// Unity 2020.2 added TimeUpdate https://docs.unity3d.com/2020.2/Documentation/ScriptReference/PlayerLoop.TimeUpdate.html
|
||||
TimeUpdate = 14,
|
||||
LastTimeUpdate = 15,
|
||||
#endif
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum InjectPlayerLoopTimings
|
||||
{
|
||||
/// <summary>
|
||||
/// Preset: All loops(default).
|
||||
/// </summary>
|
||||
All =
|
||||
Initialization | LastInitialization |
|
||||
EarlyUpdate | LastEarlyUpdate |
|
||||
FixedUpdate | LastFixedUpdate |
|
||||
PreUpdate | LastPreUpdate |
|
||||
Update | LastUpdate |
|
||||
PreLateUpdate | LastPreLateUpdate |
|
||||
PostLateUpdate | LastPostLateUpdate
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
| TimeUpdate | LastTimeUpdate,
|
||||
#else
|
||||
,
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Preset: All without last except LastPostLateUpdate.
|
||||
/// </summary>
|
||||
Standard =
|
||||
Initialization |
|
||||
EarlyUpdate |
|
||||
FixedUpdate |
|
||||
PreUpdate |
|
||||
Update |
|
||||
PreLateUpdate |
|
||||
PostLateUpdate | LastPostLateUpdate
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
| TimeUpdate
|
||||
#endif
|
||||
,
|
||||
|
||||
/// <summary>
|
||||
/// Preset: Minimum pattern, Update | FixedUpdate | LastPostLateUpdate
|
||||
/// </summary>
|
||||
Minimum =
|
||||
Update | FixedUpdate | LastPostLateUpdate,
|
||||
|
||||
// PlayerLoopTiming
|
||||
|
||||
Initialization = 1,
|
||||
LastInitialization = 2,
|
||||
|
||||
EarlyUpdate = 4,
|
||||
LastEarlyUpdate = 8,
|
||||
|
||||
FixedUpdate = 16,
|
||||
LastFixedUpdate = 32,
|
||||
|
||||
PreUpdate = 64,
|
||||
LastPreUpdate = 128,
|
||||
|
||||
Update = 256,
|
||||
LastUpdate = 512,
|
||||
|
||||
PreLateUpdate = 1024,
|
||||
LastPreLateUpdate = 2048,
|
||||
|
||||
PostLateUpdate = 4096,
|
||||
LastPostLateUpdate = 8192
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
,
|
||||
// Unity 2020.2 added TimeUpdate https://docs.unity3d.com/2020.2/Documentation/ScriptReference/PlayerLoop.TimeUpdate.html
|
||||
TimeUpdate = 16384,
|
||||
LastTimeUpdate = 32768
|
||||
#endif
|
||||
}
|
||||
|
||||
public interface IPlayerLoopItem
|
||||
{
|
||||
bool MoveNext();
|
||||
}
|
||||
|
||||
public static class PlayerLoopHelper
|
||||
{
|
||||
static readonly ContinuationQueue ThrowMarkerContinuationQueue = new ContinuationQueue(PlayerLoopTiming.Initialization);
|
||||
static readonly PlayerLoopRunner ThrowMarkerPlayerLoopRunner = new PlayerLoopRunner(PlayerLoopTiming.Initialization);
|
||||
|
||||
public static SynchronizationContext UnitySynchronizationContext => unitySynchronizationContext;
|
||||
public static int MainThreadId => mainThreadId;
|
||||
internal static string ApplicationDataPath => applicationDataPath;
|
||||
|
||||
public static bool IsMainThread => Thread.CurrentThread.ManagedThreadId == mainThreadId;
|
||||
|
||||
static int mainThreadId;
|
||||
static string applicationDataPath;
|
||||
static SynchronizationContext unitySynchronizationContext;
|
||||
static ContinuationQueue[] yielders;
|
||||
static PlayerLoopRunner[] runners;
|
||||
internal static bool IsEditorApplicationQuitting { get; private set; }
|
||||
static PlayerLoopSystem[] InsertRunner(PlayerLoopSystem loopSystem,
|
||||
bool injectOnFirst,
|
||||
Type loopRunnerYieldType, ContinuationQueue cq,
|
||||
Type loopRunnerType, PlayerLoopRunner runner)
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.playModeStateChanged += (state) =>
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.ExitingEditMode)
|
||||
{
|
||||
IsEditorApplicationQuitting = true;
|
||||
// run rest action before clear.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Run();
|
||||
runner.Clear();
|
||||
}
|
||||
if (cq != null)
|
||||
{
|
||||
cq.Run();
|
||||
cq.Clear();
|
||||
}
|
||||
IsEditorApplicationQuitting = false;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
var yieldLoop = new PlayerLoopSystem
|
||||
{
|
||||
type = loopRunnerYieldType,
|
||||
updateDelegate = cq.Run
|
||||
};
|
||||
|
||||
var runnerLoop = new PlayerLoopSystem
|
||||
{
|
||||
type = loopRunnerType,
|
||||
updateDelegate = runner.Run
|
||||
};
|
||||
|
||||
// Remove items from previous initializations.
|
||||
var source = RemoveRunner(loopSystem, loopRunnerYieldType, loopRunnerType);
|
||||
var dest = new PlayerLoopSystem[source.Length + 2];
|
||||
|
||||
Array.Copy(source, 0, dest, injectOnFirst ? 2 : 0, source.Length);
|
||||
if (injectOnFirst)
|
||||
{
|
||||
dest[0] = yieldLoop;
|
||||
dest[1] = runnerLoop;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[dest.Length - 2] = yieldLoop;
|
||||
dest[dest.Length - 1] = runnerLoop;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
type = typeof(UniTaskSynchronizationContext),
|
||||
updateDelegate = UniTaskSynchronizationContext.Run
|
||||
};
|
||||
|
||||
// Remove items from previous initializations.
|
||||
var source = loopSystem.subSystemList
|
||||
.Where(ls => ls.type != typeof(UniTaskSynchronizationContext))
|
||||
.ToArray();
|
||||
|
||||
var dest = new System.Collections.Generic.List<PlayerLoopSystem>(source);
|
||||
|
||||
var index = dest.FindIndex(x => x.type.Name == "ScriptRunDelayedTasks");
|
||||
if (index == -1)
|
||||
{
|
||||
index = dest.FindIndex(x => x.type.Name == "UniTaskLoopRunnerUpdate");
|
||||
}
|
||||
|
||||
dest.Insert(index + 1, loop);
|
||||
|
||||
return dest.ToArray();
|
||||
}
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||||
#else
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
#endif
|
||||
static void Init()
|
||||
{
|
||||
// capture default(unity) sync-context.
|
||||
unitySynchronizationContext = SynchronizationContext.Current;
|
||||
mainThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
try
|
||||
{
|
||||
applicationDataPath = Application.dataPath;
|
||||
}
|
||||
catch { }
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
|
||||
// When domain reload is disabled, re-initialization is required when entering play mode;
|
||||
// otherwise, pending tasks will leak between play mode sessions.
|
||||
var domainReloadDisabled = UnityEditor.EditorSettings.enterPlayModeOptionsEnabled &&
|
||||
UnityEditor.EditorSettings.enterPlayModeOptions.HasFlag(UnityEditor.EnterPlayModeOptions.DisableDomainReload);
|
||||
if (!domainReloadDisabled && runners != null) return;
|
||||
#else
|
||||
if (runners != null) return; // already initialized
|
||||
#endif
|
||||
|
||||
var playerLoop =
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
PlayerLoop.GetCurrentPlayerLoop();
|
||||
#else
|
||||
PlayerLoop.GetDefaultPlayerLoop();
|
||||
#endif
|
||||
|
||||
Initialize(ref playerLoop);
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static void InitOnEditor()
|
||||
{
|
||||
// Execute the play mode init method
|
||||
Init();
|
||||
|
||||
// register an Editor update delegate, used to forcing playerLoop update
|
||||
EditorApplication.update += ForceEditorPlayerLoopUpdate;
|
||||
}
|
||||
|
||||
private static void ForceEditorPlayerLoopUpdate()
|
||||
{
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode || EditorApplication.isCompiling || EditorApplication.isUpdating)
|
||||
{
|
||||
// Not in Edit mode, don't interfere
|
||||
return;
|
||||
}
|
||||
|
||||
// EditorApplication.QueuePlayerLoopUpdate causes performance issue, don't call directly.
|
||||
// EditorApplication.QueuePlayerLoopUpdate();
|
||||
|
||||
if (yielders != null)
|
||||
{
|
||||
foreach (var item in yielders)
|
||||
{
|
||||
if (item != null) item.Run();
|
||||
}
|
||||
}
|
||||
|
||||
if (runners != null)
|
||||
{
|
||||
foreach (var item in runners)
|
||||
{
|
||||
if (item != null) item.Run();
|
||||
}
|
||||
}
|
||||
|
||||
UniTaskSynchronizationContext.Run();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
private static int FindLoopSystemIndex(PlayerLoopSystem[] playerLoopList, Type systemType)
|
||||
{
|
||||
for (int i = 0; i < playerLoopList.Length; i++)
|
||||
{
|
||||
if (playerLoopList[i].type == systemType)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
yielders = new ContinuationQueue[16];
|
||||
runners = new PlayerLoopRunner[16];
|
||||
#else
|
||||
yielders = new ContinuationQueue[14];
|
||||
runners = new PlayerLoopRunner[14];
|
||||
#endif
|
||||
|
||||
var copyList = playerLoop.subSystemList.ToArray();
|
||||
|
||||
// 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);
|
||||
|
||||
// EarlyUpdate
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
var i = FindLoopSystemIndex(copyList, typeof(PlayerLoopType.Update));
|
||||
copyList[i].subSystemList = InsertUniTaskSynchronizationContext(copyList[i]);
|
||||
|
||||
playerLoop.subSystemList = copyList;
|
||||
PlayerLoop.SetPlayerLoop(playerLoop);
|
||||
}
|
||||
|
||||
public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem 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)
|
||||
{
|
||||
var q = yielders[(int)timing];
|
||||
if (q == null)
|
||||
{
|
||||
ThrowInvalidLoopTiming(timing);
|
||||
}
|
||||
q.Enqueue(continuation);
|
||||
}
|
||||
|
||||
// Diagnostics helper
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
|
||||
public static void DumpCurrentPlayerLoop()
|
||||
{
|
||||
var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop();
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine($"PlayerLoop List");
|
||||
foreach (var header in playerLoop.subSystemList)
|
||||
{
|
||||
sb.AppendFormat("------{0}------", header.type.Name);
|
||||
sb.AppendLine();
|
||||
|
||||
if (header.subSystemList is null)
|
||||
{
|
||||
sb.AppendFormat("{0} has no subsystems!", header.ToString());
|
||||
sb.AppendLine();
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var subSystem in header.subSystemList)
|
||||
{
|
||||
sb.AppendFormat("{0}", subSystem.type.Name);
|
||||
sb.AppendLine();
|
||||
|
||||
if (subSystem.subSystemList != null)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("More Subsystem:" + subSystem.subSystemList.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log(sb.ToString());
|
||||
}
|
||||
|
||||
public static bool IsInjectedUniTaskPlayerLoop()
|
||||
{
|
||||
var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop();
|
||||
|
||||
foreach (var header in playerLoop.subSystemList)
|
||||
{
|
||||
if (header.subSystemList is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var subSystem in header.subSystemList)
|
||||
{
|
||||
if (subSystem.type == typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user