Files
2026-03-04 10:03:45 +08:00

227 lines
4.3 KiB
C#

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<Action> _actions = new List<Action>();
private readonly List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
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<LoomSKYMASTER>())
{
UnityEngine.Object.DestroyImmediate(item.gameObject);
}
_current = new GameObject("Loom").AddComponent<LoomSKYMASTER>();
_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();
}
}
}