MainThreadDispather.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Threading;
  14. using UnityEngine;
  15. /// <summary> A main thread dispather. </summary>
  16. [ExecuteInEditMode]
  17. public class MainThreadDispather : MonoBehaviour
  18. {
  19. /// <summary> A delayed queue item. </summary>
  20. public class DelayedQueueItem
  21. {
  22. /// <summary> The time. </summary>
  23. public float time;
  24. /// <summary> The action. </summary>
  25. public Action action;
  26. }
  27. /// <summary> The current. </summary>
  28. private static MainThreadDispather m_Current;
  29. /// <summary> Number of. </summary>
  30. private int m_Count;
  31. /// <summary> Current time. </summary>
  32. private static float m_CurrentTime;
  33. /// <summary> True once initialization is complete. </summary>
  34. private static bool m_Initialized;
  35. /// <summary> Identifier for the thread. </summary>
  36. private static int m_ThreadId = -1;
  37. /// <summary> The actions. </summary>
  38. private List<Action> m_Actions = new List<Action>();
  39. /// <summary> The delayed. </summary>
  40. private List<MainThreadDispather.DelayedQueueItem> m_Delayed = new List<MainThreadDispather.DelayedQueueItem>();
  41. /// <summary> Gets the current. </summary>
  42. /// <value> The current. </value>
  43. public static MainThreadDispather Current
  44. {
  45. get
  46. {
  47. if (!MainThreadDispather.m_Initialized)
  48. {
  49. MainThreadDispather.Initialize();
  50. }
  51. return MainThreadDispather.m_Current;
  52. }
  53. }
  54. /// <summary> Initializes this object. </summary>
  55. public static void Initialize()
  56. {
  57. bool flag = !MainThreadDispather.m_Initialized;
  58. if (flag && MainThreadDispather.m_ThreadId != -1 && MainThreadDispather.m_ThreadId != Thread.CurrentThread.ManagedThreadId)
  59. {
  60. return;
  61. }
  62. if (flag)
  63. {
  64. GameObject gameObject = new GameObject("MainThreadDispather");
  65. gameObject.hideFlags = HideFlags.DontSave;
  66. UnityEngine.Object.DontDestroyOnLoad(gameObject);
  67. if (MainThreadDispather.m_Current)
  68. {
  69. if (Application.isPlaying)
  70. {
  71. UnityEngine.Object.Destroy(MainThreadDispather.m_Current.gameObject);
  72. }
  73. else
  74. {
  75. UnityEngine.Object.DestroyImmediate(MainThreadDispather.m_Current.gameObject);
  76. }
  77. }
  78. MainThreadDispather.m_Current = gameObject.AddComponent<MainThreadDispather>();
  79. UnityEngine.Object.DontDestroyOnLoad(MainThreadDispather.m_Current);
  80. MainThreadDispather.m_Initialized = true;
  81. MainThreadDispather.m_ThreadId = Thread.CurrentThread.ManagedThreadId;
  82. MainThreadDispather.m_CurrentTime = Time.time;
  83. }
  84. }
  85. /// <summary> Executes the 'destroy' action. </summary>
  86. private void OnDestroy()
  87. {
  88. MainThreadDispather.m_Initialized = false;
  89. }
  90. /// <summary> Queue on main thread. </summary>
  91. /// <param name="action"> The action.</param>
  92. public static void QueueOnMainThread(Action action)
  93. {
  94. MainThreadDispather.QueueOnMainThread(action, 0f);
  95. }
  96. /// <summary> Queue on main thread. </summary>
  97. /// <param name="action"> The action.</param>
  98. /// <param name="time"> The time.</param>
  99. public static void QueueOnMainThread(Action action, float time)
  100. {
  101. if (time != 0f)
  102. {
  103. List<MainThreadDispather.DelayedQueueItem> delayed = MainThreadDispather.Current.m_Delayed;
  104. lock (delayed)
  105. {
  106. MainThreadDispather.Current.m_Delayed.Add(new MainThreadDispather.DelayedQueueItem
  107. {
  108. time = m_CurrentTime + time,
  109. action = action
  110. });
  111. }
  112. }
  113. else
  114. {
  115. List<Action> actions = MainThreadDispather.Current.m_Actions;
  116. lock (actions)
  117. {
  118. MainThreadDispather.Current.m_Actions.Add(action);
  119. }
  120. }
  121. }
  122. /// <summary> Executes the 'asynchronous' operation. </summary>
  123. /// <param name="action"> The action.</param>
  124. public static void RunAsync(Action action)
  125. {
  126. new Thread(new ParameterizedThreadStart(MainThreadDispather.RunAction))
  127. {
  128. Priority = System.Threading.ThreadPriority.Normal
  129. }.Start(action);
  130. }
  131. /// <summary> Executes the action. </summary>
  132. /// <param name="action"> The action.</param>
  133. private static void RunAction(object action)
  134. {
  135. ((Action)action)?.Invoke();
  136. }
  137. /// <summary> Updates this object. </summary>
  138. private void Update()
  139. {
  140. MainThreadDispather.m_CurrentTime = Time.time;
  141. List<Action> actions = this.m_Actions;
  142. if (actions.Count > 0)
  143. {
  144. lock (actions)
  145. {
  146. for (int i = 0; i < this.m_Actions.Count; i++)
  147. {
  148. this.m_Actions[i]();
  149. }
  150. this.m_Actions.Clear();
  151. }
  152. }
  153. List<MainThreadDispather.DelayedQueueItem> delayed = this.m_Delayed;
  154. if (delayed.Count > 0)
  155. {
  156. lock (delayed)
  157. {
  158. for (int j = 0; j < this.m_Delayed.Count; j++)
  159. {
  160. MainThreadDispather.DelayedQueueItem delayedQueueItem = this.m_Delayed[j];
  161. if (delayedQueueItem.time <= MainThreadDispather.m_CurrentTime)
  162. {
  163. delayedQueueItem.action();
  164. this.m_Delayed.RemoveAt(j);
  165. j--;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }