227 lines
4.3 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|