using System; using System.Collections.Generic; using System.Threading; using UnityEngine; namespace Rokid.UXR.Utility { public class Loom : MonoBehaviour { /// A delayed queue item. public class DelayedQueueItem { /// The time. public float time; /// The action. public Action action; } /// The current. private static Loom m_Current; /// Number of. private int m_Count; /// True once initialization is complete. private static bool m_Initialized; /// Identifier for the thread. private static int m_ThreadId = -1; /// The actions. private List m_Actions = new List(); /// The delayed. private List m_Delayed = new List(); /// Gets the current. /// The current. public static Loom Current { get { if (!Loom.m_Initialized) { Loom.Initialize(); } return Loom.m_Current; } } /// Initializes this object. public static void Initialize() { bool flag = !Loom.m_Initialized; if (flag && Loom.m_ThreadId != -1 && Loom.m_ThreadId != Thread.CurrentThread.ManagedThreadId) { return; } if (flag) { GameObject gameObject = new GameObject("MainThreadDispather"); gameObject.hideFlags = HideFlags.DontSave; UnityEngine.Object.DontDestroyOnLoad(gameObject); if (Loom.m_Current) { if (Application.isPlaying) { UnityEngine.Object.Destroy(Loom.m_Current.gameObject); } else { UnityEngine.Object.DestroyImmediate(Loom.m_Current.gameObject); } } Loom.m_Current = gameObject.AddComponent(); UnityEngine.Object.DontDestroyOnLoad(Loom.m_Current); Loom.m_Initialized = true; Loom.m_ThreadId = Thread.CurrentThread.ManagedThreadId; } } /// Executes the 'destroy' action. private void OnDestroy() { Loom.m_Initialized = false; } /// Queue on main thread. /// The action. public static void QueueOnMainThread(Action action) { Loom.QueueOnMainThread(action, 0f); } /// Queue on main thread. /// The action. /// The time. public static void QueueOnMainThread(Action action, float time) { if (time != 0f) { List delayed = Loom.Current.m_Delayed; lock (delayed) { Loom.Current.m_Delayed.Add(new Loom.DelayedQueueItem { time = Time.time + time, action = action }); } } else { List actions = Loom.Current.m_Actions; lock (actions) { Loom.Current.m_Actions.Add(action); } } } /// Executes the 'asynchronous' operation. /// The action. public static void RunAsync(Action action) { new Thread(new ParameterizedThreadStart(Loom.RunAction)) { Priority = System.Threading.ThreadPriority.Normal }.Start(action); } /// Executes the action. /// The action. private static void RunAction(object action) { ((Action)action)?.Invoke(); } /// Updates this object. private void Update() { List actions = this.m_Actions; if (actions.Count > 0) { lock (actions) { for (int i = 0; i < this.m_Actions.Count; i++) { this.m_Actions[i](); } this.m_Actions.Clear(); } } List delayed = this.m_Delayed; if (delayed.Count > 0) { lock (delayed) { for (int j = 0; j < this.m_Delayed.Count; j++) { Loom.DelayedQueueItem delayedQueueItem = this.m_Delayed[j]; if (delayedQueueItem.time <= Time.time) { delayedQueueItem.action(); this.m_Delayed.RemoveAt(j); j--; } } } } } } }