using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
namespace JEngine.Core
{
public static unsafe class ThreadMgr
{
public struct ThreadTaskAwaiter : INotifyCompletion
{
public int Index;
public void GetResult()
{
}
public bool IsCompleted
=> false;
public void OnCompleted(Action continuation)
{
Actions[Index] = continuation;
}
public ThreadTaskAwaiter GetAwaiter()
{
return this;
}
}
private static int GetIndex()
{
bool gotLock = false;
try
{
_createLock.Enter(ref gotLock);
byte* ptr = UsageList;
byte* max = ptr + MaxSize;
while (ptr < max)
{
if (*ptr == 0)
{
*ptr = 1;
break;
}
ptr++;
}
if (ptr == max)
throw new Exception("ThreadMgr: ThreadTaskAwaiter is full!");
return (int)(ptr - UsageList);
}
finally
{
if (gotLock) _createLock.Exit();
}
}
private static void SetCompleted(int index)
{
if (UsageList[index] == 0 || index < 0 || index >= MaxSize)
return;
Action act = Actions[index];
try
{
UsageList[index] = 0;
act?.Invoke();
}
catch (Exception e)
{
Debug.LogException(e);
}
}
///
/// 待执行任务
///
private static readonly Action[] Actions = new Action[MaxSize];
///
/// 使用列表
///
private static readonly byte* UsageList = (byte*)UnsafeUtility.Malloc(MaxSize, 4, Allocator.Persistent);
///
/// 最大数量
///
private const int MaxSize = 10000;
///
/// 锁
///
private static SpinLock _createLock;
///
/// Init ThreadMgr
///
public static void Initialize()
{
//注册Update到LifeCycleMgr
_updateTaskId = LifeCycleMgr.Instance.AddUpdateTask(Update, () => _active);
//默认运行
Activate();
GC.AddMemoryPressure(MaxSize);
}
///
/// Task id
///
private static Guid _updateTaskId;
///
/// status of activeness
///
private static bool _active;
///
/// Activate threadMgr to execute loop
///
public static void Activate()
{
_active = true;
}
///
/// Deactivate threadMgr to stop loop
///
public static void Deactivate()
{
_active = false;
}
///
/// Stop the current threadMgr, requires re-initialize to rerun
///
public static void Stop()
{
LifeCycleMgr.Instance.RemoveUpdateItem(_updateTaskId);
}
///
/// Item to execute
///
private struct DelayedQueueItem
{
public float Time;
public Action Action;
public bool MainThread;
}
///
/// Actions Queue
///
private static readonly ConcurrentQueue Delayed = new ConcurrentQueue();
///
/// Queue an action with param on main thread to run
///
///
///
[Obsolete("Use QueueOnMainThread instead")]
public static ThreadTaskAwaiter QueueOnMainThread(Action