/****************************************************************************
* Copyright 2019 Nreal Techonology Limited. All rights reserved.
*
* This file is part of NRSDK.
*
* https://www.nreal.ai/
*
*****************************************************************************/
namespace NRKernal
{
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Threading;
/// Only works at Android runtime.
public class AsyncTaskExecuter : SingleTon
{
/// Queue of tasks.
public Queue m_TaskQueue = new Queue();
#if !UNITY_EDITOR
public AsyncTaskExecuter()
{
Thread thread = new Thread(RunAsyncTask);
thread.IsBackground = true;
thread.Name = "AsyncTaskExecuter";
thread.Start();
}
private void RunAsyncTask()
{
while (true)
{
Thread.Sleep(5);
if (m_TaskQueue.Count != 0)
{
lock (m_TaskQueue)
{
var task = m_TaskQueue.Dequeue();
try
{
task?.Invoke();
}
catch (Exception e)
{
NRDebugger.Error("[AsyncTaskExecuter] Execute async task error:" + e.ToString());
throw;
}
}
}
}
}
#endif
/// Executes the action.
/// The task.
public void RunAction(Action task)
{
lock (m_TaskQueue)
{
#if !UNITY_EDITOR
m_TaskQueue.Enqueue(task);
#else
task?.Invoke();
#endif
}
}
/// Executes a task witch has a timeout opration.
/// The task.
/// The timeout opration.If the task does not time out, it is not
/// executed.
/// The delay.
internal void RunAction(Action task, Action timeoutOpration, float delay)
{
var cancleToken = new CancellationTokenSource();
if (delay > 0 && timeoutOpration != null)
{
Task.Factory.StartNew(async () =>
{
await Task.Delay((int)(delay * 1000));
if (cancleToken.IsCancellationRequested)
{
return;
}
try
{
NRDebugger.Info("[AsyncTaskExecuter] Run action timeout...");
timeoutOpration?.Invoke();
}
catch (Exception e)
{
NRDebugger.Error("[AsyncTaskExecuter] Run action timeout exeption:" + e.ToString());
throw;
}
}, cancleToken.Token);
}
Task.Factory.StartNew(() =>
{
try
{
task?.Invoke();
}
catch (Exception)
{
throw;
}
cancleToken.Cancel();
});
}
}
}