123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.LowLevel;
- using PlayerLoopType = UnityEngine.PlayerLoop;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- namespace LitMotion
- {
- /// <summary>
- /// Types of PlayerLoop inserted for motion updates
- /// </summary>
- public static class LitMotionLoopRunners
- {
- public struct LitMotionInitialization { };
- public struct LitMotionEarlyUpdate { };
- public struct LitMotionFixedUpdate { };
- public struct LitMotionPreUpdate { };
- public struct LitMotionUpdate { };
- public struct LitMotionPreLateUpdate { };
- public struct LitMotionPostLateUpdate { };
- public struct LitMotionTimeUpdate { };
- }
- internal enum PlayerLoopTiming
- {
- Initialization = 0,
- EarlyUpdate = 1,
- FixedUpdate = 2,
- PreUpdate = 3,
- Update = 4,
- PreLateUpdate = 5,
- PostLateUpdate = 6,
- TimeUpdate = 7,
- }
- internal static class PlayerLoopHelper
- {
- public static event Action OnInitialization;
- public static event Action OnEarlyUpdate;
- public static event Action OnFixedUpdate;
- public static event Action OnPreUpdate;
- public static event Action OnUpdate;
- public static event Action OnPreLateUpdate;
- public static event Action OnPostLateUpdate;
- public static event Action OnTimeUpdate;
- static bool initialized;
- [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
- static void Init()
- {
- #if UNITY_EDITOR
- var domainReloadDisabled = EditorSettings.enterPlayModeOptionsEnabled && EditorSettings.enterPlayModeOptions.HasFlag(EnterPlayModeOptions.DisableDomainReload);
- if (!domainReloadDisabled && initialized) return;
- #else
- if (initialized) return;
- #endif
- OnInitialization += static () => MotionDispatcher.Update(PlayerLoopTiming.Initialization);
- OnEarlyUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.EarlyUpdate);
- OnFixedUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.FixedUpdate);
- OnPreUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.PreUpdate);
- OnUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.Update);
- OnPreLateUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.PreLateUpdate);
- OnPostLateUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.PostLateUpdate);
- OnTimeUpdate += static () => MotionDispatcher.Update(PlayerLoopTiming.TimeUpdate);
- var playerLoop = PlayerLoop.GetCurrentPlayerLoop();
- Initialize(ref playerLoop);
- }
- public static void Initialize(ref PlayerLoopSystem playerLoop)
- {
- initialized = true;
- var newLoop = playerLoop.subSystemList.ToArray();
- InsertLoop(newLoop, typeof(PlayerLoopType.Initialization), typeof(LitMotionLoopRunners.LitMotionInitialization), static () => OnInitialization?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.EarlyUpdate), typeof(LitMotionLoopRunners.LitMotionEarlyUpdate), static () => OnEarlyUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.FixedUpdate), typeof(LitMotionLoopRunners.LitMotionFixedUpdate), static () => OnFixedUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.PreUpdate), typeof(LitMotionLoopRunners.LitMotionPreUpdate), static () => OnPreUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.Update), typeof(LitMotionLoopRunners.LitMotionUpdate), static () => OnUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.PreLateUpdate), typeof(LitMotionLoopRunners.LitMotionPreLateUpdate), static () => OnPreLateUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.PostLateUpdate), typeof(LitMotionLoopRunners.LitMotionPostLateUpdate), static () => OnPostLateUpdate?.Invoke());
- InsertLoop(newLoop, typeof(PlayerLoopType.TimeUpdate), typeof(LitMotionLoopRunners.LitMotionTimeUpdate), static () => OnTimeUpdate?.Invoke());
- playerLoop.subSystemList = newLoop;
- PlayerLoop.SetPlayerLoop(playerLoop);
- }
- static void InsertLoop(PlayerLoopSystem[] loopSystems, Type loopType, Type loopRunnerType, PlayerLoopSystem.UpdateFunction updateDelegate)
- {
- var i = FindLoopSystemIndex(loopSystems, loopType);
- ref var loop = ref loopSystems[i];
- loop.subSystemList = InsertRunner(loop.subSystemList, loopRunnerType, updateDelegate);
- }
- 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 PlayerLoopSystem[] InsertRunner(PlayerLoopSystem[] subSystemList, Type loopRunnerType, PlayerLoopSystem.UpdateFunction updateDelegate)
- {
- var source = subSystemList.Where(x => x.type != loopRunnerType).ToArray();
- var dest = new PlayerLoopSystem[source.Length + 1];
- Array.Copy(source, 0, dest, 1, source.Length);
- dest[0] = new PlayerLoopSystem
- {
- type = loopRunnerType,
- updateDelegate = updateDelegate
- };
- return dest;
- }
- }
- }
|