mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 03:14:47 +00:00
78 lines
2.2 KiB
C#
78 lines
2.2 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace JNGame.Util
|
|||
|
{
|
|||
|
/// Author: Pim de Witte (pimdewitte.com) and contributors, https://github.com/PimDeWitte/UnityMainThreadDispatcher
|
|||
|
/// <summary>
|
|||
|
/// A thread-safe class which holds a queue with actions to execute on the next Update() method. It can be used to make calls to the main thread for
|
|||
|
/// things such as UI Manipulation in Unity. It was developed for use in combination with the Firebase Unity plugin, which uses separate threads for event handling
|
|||
|
/// </summary>
|
|||
|
public class UnityMainThreadDispatcher : SingletonScene<UnityMainThreadDispatcher> {
|
|||
|
|
|||
|
private readonly Queue<Action> _executionQueue = new Queue<Action>();
|
|||
|
|
|||
|
public void Update() {
|
|||
|
lock(_executionQueue) {
|
|||
|
while (_executionQueue.Count > 0) {
|
|||
|
_executionQueue.Dequeue().Invoke();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Locks the queue and adds the IEnumerator to the queue
|
|||
|
/// </summary>
|
|||
|
/// <param name="action">IEnumerator function that will be executed from the main thread.</param>
|
|||
|
public void Enqueue(IEnumerator action) {
|
|||
|
lock (_executionQueue) {
|
|||
|
_executionQueue.Enqueue (() => {
|
|||
|
StartCoroutine(action);
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Locks the queue and adds the Action to the queue
|
|||
|
/// </summary>
|
|||
|
/// <param name="action">function that will be executed from the main thread.</param>
|
|||
|
public void Enqueue(Action action)
|
|||
|
{
|
|||
|
Enqueue(ActionWrapper(action));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Locks the queue and adds the Action to the queue, returning a Task which is completed when the action completes
|
|||
|
/// </summary>
|
|||
|
/// <param name="action">function that will be executed from the main thread.</param>
|
|||
|
/// <returns>A Task that can be awaited until the action completes</returns>
|
|||
|
public Task EnqueueAsync(Action action)
|
|||
|
{
|
|||
|
var tcs = new TaskCompletionSource<bool>();
|
|||
|
|
|||
|
void WrappedAction() {
|
|||
|
try
|
|||
|
{
|
|||
|
action();
|
|||
|
tcs.TrySetResult(true);
|
|||
|
} catch (Exception ex)
|
|||
|
{
|
|||
|
tcs.TrySetException(ex);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Enqueue(ActionWrapper(WrappedAction));
|
|||
|
return tcs.Task;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
IEnumerator ActionWrapper(Action a)
|
|||
|
{
|
|||
|
a();
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|