2023-04-03 11:04:31 +08:00

125 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using UnityEngine;
namespace BF
{
public class LoomManager : ManagerBase
{
static LoomManager instance;
public int maxThreads = 8;
int numThreads;
List<Action> actions = new List<Action>();
List<Action> currentActions = new List<Action>();
List<Delayed> delayedList = new List<Delayed>();
List<Delayed> currentDelayedList = new List<Delayed>();
public static LoomManager Create()
{
BFLog.LogAssert(instance == null, "This method only allows BFMain to call once");
instance = new LoomManager();
return instance;
}
LoomManager() { }
public void QueueOnMainThread(Action action)
{
QueueOnMainThread(action, 0f);
}
public void QueueOnMainThread(Action action, float time)
{
if (time != 0)
{
lock (delayedList)
{
delayedList.Add(new Delayed
{
time = Time.time + time,
action = action
});
}
}
else
{
lock (actions)
{
actions.Add(action);
}
}
}
public Thread RunAsync(Action action)
{
while (numThreads >= maxThreads)
{
Thread.Sleep(1);
}
Interlocked.Increment(ref numThreads);
ThreadPool.QueueUserWorkItem(RunAction, action);
return null;
}
void RunAction(object action)
{
try
{
((Action)action)();
}
catch
{
}
finally
{
Interlocked.Decrement(ref numThreads);
}
}
public override void Update()
{
if (actions.Count > 0)
{
lock (actions)
{
currentActions.Clear();
currentActions.AddRange(actions);
actions.Clear();
}
foreach (var a in currentActions)
{
a();
}
currentActions.Clear();
}
if (delayedList.Count > 0)
{
lock (delayedList)
{
currentDelayedList.Clear();
for (int i = delayedList.Count - 1; i >= 0; i--)
{
if(delayedList[i].time <= Time.time)
{
currentDelayedList.Add(delayedList[i]);
delayedList.RemoveAt(i);
}
}
}
foreach (var delayed in currentDelayedList)
{
delayed.action();
}
currentDelayedList.Clear();
}
}
}
}