Loom.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading;
  6. using UnityEngine;
  7. public struct DelayedQueueItem
  8. {
  9. public float time;
  10. public Action action;
  11. }
  12. public class Loom : MonoBehaviour
  13. {
  14. /// <summary>
  15. /// 最大线程数量
  16. /// </summary>
  17. public static int maxThreads = 8;
  18. /// <summary>
  19. /// 线程数量
  20. /// </summary>
  21. static int numThreads;
  22. private static Loom _currentLoom;
  23. public static Loom CurrentLoom
  24. {
  25. get
  26. {
  27. Initialize();
  28. return _currentLoom;
  29. }
  30. }
  31. /// <summary>
  32. /// 是否已经初始化
  33. /// </summary>
  34. static bool initialized;
  35. /// <summary>
  36. /// 作为初始化方法自己调用,可在初始化场景调用一次即可
  37. /// </summary>
  38. public static void Initialize()
  39. {
  40. if (!initialized)
  41. {
  42. if (!Application.isPlaying)
  43. return;
  44. initialized = true;
  45. GameObject g = new GameObject("Loom");
  46. //####永不销毁
  47. DontDestroyOnLoad(g);
  48. _currentLoom = g.AddComponent<Loom>();
  49. }
  50. }
  51. /// <summary>
  52. /// 延迟执行的队列
  53. /// </summary>
  54. private List<DelayedQueueItem> _delayedQueueItems = new List<DelayedQueueItem>();
  55. /// <summary>
  56. /// 目前正在延迟执行的队列
  57. /// </summary>
  58. private List<DelayedQueueItem> _currentDelayedQueueItems = new List<DelayedQueueItem>();
  59. /// <summary>
  60. /// 新添加的ACTION
  61. /// </summary>
  62. private List<Action> _newActions = new List<Action>();
  63. /// <summary>
  64. /// 不延迟执行
  65. /// </summary>
  66. private List<Action> _CurrentNoDelayActions = new List<Action>();
  67. public static void QueueOnMainThread(Action action)
  68. {
  69. QueueOnMainThread(action, 0f);
  70. }
  71. /// <summary>
  72. /// 添加到主线程执行
  73. /// </summary>
  74. /// <param name="action"></param>
  75. /// <param name="delayTime"></param>
  76. public static void QueueOnMainThread(Action action, float delayTime)
  77. {
  78. if (delayTime != 0)
  79. {
  80. if (CurrentLoom != null)
  81. {
  82. lock (CurrentLoom._delayedQueueItems)
  83. {
  84. CurrentLoom._delayedQueueItems.Add(new DelayedQueueItem { time = Time.time + delayTime, action = action });
  85. }
  86. }
  87. }
  88. else
  89. {
  90. if (CurrentLoom != null)
  91. {
  92. lock (CurrentLoom._newActions)
  93. {
  94. CurrentLoom._newActions.Add(action);
  95. }
  96. }
  97. }
  98. }
  99. public static Thread RunAsync(Action action)
  100. {
  101. Initialize();
  102. while (numThreads >= maxThreads)
  103. {
  104. //将当前线程挂起指定的毫秒数。
  105. Thread.Sleep(1);
  106. }
  107. //递增线程数量(Interlocked.Increment:以原子操作的形式递增指定变量的值并存储结果)
  108. Interlocked.Increment(ref numThreads);
  109. //将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行
  110. ThreadPool.QueueUserWorkItem(RunAction, action);
  111. return null;
  112. }
  113. private static void RunAction(object action)
  114. {
  115. try
  116. {
  117. ((Action)action)();
  118. }
  119. catch
  120. {
  121. }
  122. finally
  123. {
  124. //递减线程数量(Interlocked.Increment:以原子操作的形式递增指定变量的值并存储结果)
  125. Interlocked.Decrement(ref numThreads);
  126. }
  127. }
  128. void Update()
  129. {
  130. lock (_newActions)
  131. {
  132. _CurrentNoDelayActions.Clear();
  133. _CurrentNoDelayActions.AddRange(_newActions);
  134. _newActions.Clear();
  135. }
  136. foreach (var actionItem in _CurrentNoDelayActions)
  137. {
  138. actionItem();
  139. }
  140. lock (_delayedQueueItems)
  141. {
  142. _currentDelayedQueueItems.Clear();
  143. _currentDelayedQueueItems.AddRange(_delayedQueueItems.Where(d => d.time <= Time.time));
  144. foreach (var item in _currentDelayedQueueItems)
  145. {
  146. _delayedQueueItems.Remove(item);
  147. }
  148. }
  149. foreach (var delayed in _currentDelayedQueueItems)
  150. {
  151. delayed.action();
  152. }
  153. }
  154. void OnDisable()
  155. {
  156. if (_currentLoom == this)
  157. {
  158. _currentLoom = null;
  159. }
  160. }
  161. }