123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using UnityEngine;
- public class Loom : MonoBehaviour {
- #region 公共字段
-
-
-
- public static int maxThreads = 8;
- #endregion
- #region 私有字段
-
-
-
- private static int numThreads;
-
-
-
- private static Loom _current;
- private int _count;
-
-
-
- private static bool initialized;
- private List<Action> _actions;
- private List<DelayedQueueItem> _delayed;
- private List<DelayedQueueItem> _currentDelayed;
-
-
-
- private List<Action> _currentActions;
- #endregion
- #region 公有属性
-
-
-
- public static Loom Current {
- get {
- Initialize();
- return _current;
- }
- }
- #endregion
- #region Unity3d API
- void Awake() {
- _current = this;
- initialized = true;
- _actions = new List<Action>();
- _delayed = new List<DelayedQueueItem>();
- _currentDelayed = new List<DelayedQueueItem>();
- _currentActions = new List<Action>();
- }
- void Update() {
- lock (_actions) {
- _currentActions.Clear();
- _currentActions.AddRange(_actions);
- _actions.Clear();
- }
- foreach (Action a in _currentActions) {
- a();
- }
- lock (_delayed) {
- _currentDelayed.Clear();
- _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
- foreach (var item in _currentDelayed)
- _delayed.Remove(item);
- }
- foreach (var delayed in _currentDelayed) {
- delayed.action();
- }
- }
- void OnDisable() {
- if (_current == this) {
- _current = null;
- }
- }
- private void OnDestroy() {
- initialized = false;
- }
- #endregion Unity3d API
- #region Static Methods
-
-
-
- private static void Initialize() {
- if (!initialized) {
- if (!Application.isPlaying)
- return;
- initialized = true;
- GameObject g = new GameObject("Loom");
- DontDestroyOnLoad(g);
- _current = g.AddComponent<Loom>();
- }
- }
-
-
-
- public struct DelayedQueueItem {
- public float time;
- public Action action;
- }
-
-
-
- public static void QueueOnMainThread(Action action) {
- QueueOnMainThread(action, 0f);
- }
-
-
-
- public static void QueueOnMainThread(Action action, float time) {
- if (time != 0) {
- lock (Current._delayed) {
-
- Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
- }
- } else {
- if (Current != null && Current._actions != null) {
- lock (Current._actions) {
- Current._actions.Add(action);
- }
- }
- }
- }
-
-
-
- public static Thread RunAsync(Action a) {
- Initialize();
- while (numThreads >= maxThreads) {
- Thread.Sleep(1);
- }
- Interlocked.Increment(ref numThreads);
- ThreadPool.QueueUserWorkItem(RunAction, a);
- return null;
- }
- private static void RunAction(object action) {
- try {
- ((Action)action)();
- } catch (Exception e) {
- Debug.Log(e.Message);
- Debug.Log(e.Source);
- } finally {
- Interlocked.Decrement(ref numThreads);
- }
- }
- #endregion of Static Methods
- }
|