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 actions = new List(); List currentActions = new List(); List delayedList = new List(); List currentDelayedList = new List(); 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(); } } } }