Files
adriadri6972 d3d9c5f833 upload project
2025-07-31 15:21:08 +02:00

86 lines
2.9 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace Unity.XR.XREAL
{
/// <summary>
/// A singleton MonoBehaviour class that dispatches actions to be executed on the Unity main thread.
/// </summary>
public class XREALMainThreadDispather : SingletonMonoBehaviour<XREALMainThreadDispather>
{
ConcurrentQueue<Action> m_Actions = new ConcurrentQueue<Action>();
ConcurrentQueue<Action> m_RunningActions = new ConcurrentQueue<Action>();
/// <summary>
/// Event invoked every frame during the Update method.
/// </summary>
public static event Action OnUpdate;
/// <summary>
/// Queues an action to be executed on the Unity main thread in the next frame.
/// </summary>
/// <param name="action">The action to execute on the main thread.</param>
public void QueueOnMainThread(Action action)
{
m_Actions.Enqueue(action);
}
/// <summary>
/// Queues an action to be executed on the Unity main thread after a specified delay.
/// Returns a CancellationTokenSource that can be used to cancel the scheduled action.
/// </summary>
/// <param name="action">The action to execute on the main thread.</param>
/// <param name="delaySeconds">The delay in seconds before the action is executed.</param>
/// <returns>A CancellationTokenSource that can be used to cancel the scheduled action.</returns>
public CancellationTokenSource QueueOnMainThreadWithDelay(Action action, float delaySeconds)
{
CancellationTokenSource ctSource = new CancellationTokenSource();
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
if (!ctSource.IsCancellationRequested)
m_Actions.Enqueue(action);
}, ctSource.Token);
return ctSource;
}
void Update()
{
OnUpdate?.Invoke();
if (m_Actions.Count > 0)
{
(m_Actions, m_RunningActions) = (m_RunningActions, m_Actions);
while (m_RunningActions.TryDequeue(out var action))
{
try
{
action.Invoke();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
}
}
#if UNITY_ANDROID && !UNITY_EDITOR
void OnApplicationPause(bool pause)
{
Debug.Log($"[XREALMainThreadDispather] OnApplicationPause: {pause}");
if (pause)
{
XREALPlugin.PauseSession();
}
else
{
XREALPlugin.ResumeSession();
}
}
#endif
}
}