using System; using System.Collections.Generic; using System.Linq; using System.Threading; using UnityEngine; using UnityEngine.SceneManagement; namespace Artngame.SKYMASTER { public class LoomSKYMASTER : MonoBehaviour { public class DelayedQueueItem { public float time; public Action action; public string name; } private static bool _quitting; private static LoomSKYMASTER _current; private int _count; private static bool _initialized; private static int _threadId; private readonly List _actions = new List(); private readonly List _delayed = new List(); private readonly Action[] _toRun = new Action[4000]; public static LoomSKYMASTER Current { get { Initialize(); return _current; } } private void OnApplicationQuit() { _quitting = true; } public static void Initialize() { if (!Application.isPlaying || _quitting) { return; } bool flag = !_initialized; if (!flag && _threadId == Thread.CurrentThread.ManagedThreadId && _current == null) { flag = true; } if (!flag) { return; } foreach (LoomSKYMASTER item in Resources.FindObjectsOfTypeAll(typeof(LoomSKYMASTER)).Cast()) { UnityEngine.Object.DestroyImmediate(item.gameObject); } _current = new GameObject("Loom").AddComponent(); _initialized = true; _threadId = Thread.CurrentThread.ManagedThreadId; } private void Awake() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDestroy() { _actions.Clear(); _delayed.Clear(); if (_current == this) { _initialized = false; } } public static void QueueOnMainThread(Action action, string name) { QueueOnMainThread(action, 0f, name); } public static void QueueOnMainThread(Action action, float time, string name) { if (!Application.isPlaying) { return; } if (Math.Abs(time - 0f) > float.Epsilon || !string.IsNullOrEmpty(name)) { lock (Current._delayed) { DelayedQueueItem delayedQueueItem = null; if (!string.IsNullOrEmpty(name)) { delayedQueueItem = Current._delayed.FirstOrDefault((DelayedQueueItem d) => d.name == name); } if (delayedQueueItem != null) { delayedQueueItem.time = Time.time + time; } else { DelayedQueueItem delayedQueueItem2 = new DelayedQueueItem(); delayedQueueItem2.name = name; delayedQueueItem2.time = Time.time + time; delayedQueueItem2.action = action; Current._delayed.Add(delayedQueueItem2); } return; } } lock (Current._actions) { Current._actions.Add(action); } } public static void QueueOnMainThread(Action action) { QueueOnMainThread(action, 0f); } public static void QueueOnMainThread(Action action, float time) { QueueOnMainThread(action, time, null); } public static void RunAsync(Action action) { Thread thread = new Thread(RunAction); thread.Priority = System.Threading.ThreadPriority.Normal; thread.Start(action); } private static void RunAction(object action) { ((Action)action)(); } private void Update() { if (Current != this) { if (Application.isPlaying) { UnityEngine.Object.DestroyImmediate(base.gameObject); } return; } if (!Application.isPlaying) { _actions.Clear(); _delayed.Clear(); return; } int num = Mathf.Min(_actions.Count, 4000); lock (_actions) { _actions.CopyTo(0, _toRun, 0, num); if (num == _actions.Count) { _actions.Clear(); } else { _actions.RemoveRange(0, num); } } for (int i = 0; i < num; i++) { try { _toRun[i](); } catch (Exception exception) { Debug.LogException(exception); } } lock (_delayed) { num = 0; int num2 = _delayed.Count - 1; while (num2 >= 0 && num < 3999) { if (_delayed[num2].time <= Time.time) { _toRun[num++] = _delayed[num2].action; _delayed.RemoveAt(num2); } num2--; } } for (int j = 0; j < num; j++) { try { _toRun[j](); } catch (Exception exception2) { Debug.LogException(exception2); } } } private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { _actions.Clear(); _delayed.Clear(); } } }