59 lines
1.4 KiB
C#
59 lines
1.4 KiB
C#
using System.Collections.Concurrent;
|
||
using System.Threading.Tasks;
|
||
using UnityEngine;
|
||
using System;
|
||
|
||
public class UnityMainThreadDispatcher : MonoBehaviour
|
||
{
|
||
private static UnityMainThreadDispatcher instance;
|
||
private readonly ConcurrentQueue<Action> actionQueue = new ConcurrentQueue<Action>();
|
||
|
||
public static UnityMainThreadDispatcher Instance
|
||
{
|
||
get
|
||
{
|
||
if (instance == null)
|
||
{
|
||
var go = new GameObject("UnityMainThreadDispatcher");
|
||
DontDestroyOnLoad(go);
|
||
instance = go.AddComponent<UnityMainThreadDispatcher>();
|
||
}
|
||
return instance;
|
||
}
|
||
}
|
||
|
||
// Для синхронного выполнения
|
||
public void Enqueue(Action action)
|
||
{
|
||
actionQueue.Enqueue(action);
|
||
}
|
||
|
||
// Для асинхронного выполнения с ожиданием
|
||
public Task EnqueueAsync(Action action)
|
||
{
|
||
var tcs = new TaskCompletionSource<bool>();
|
||
|
||
actionQueue.Enqueue(() =>
|
||
{
|
||
try
|
||
{
|
||
action();
|
||
tcs.SetResult(true);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
tcs.SetException(e);
|
||
}
|
||
});
|
||
|
||
return tcs.Task;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
while (actionQueue.TryDequeue(out var action))
|
||
{
|
||
action();
|
||
}
|
||
}
|
||
} |