LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DigitalRuby/ThunderAndLightning/LightningThreadState.cs
2023-12-22 18:30:10 -05:00

169 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
namespace DigitalRuby.ThunderAndLightning
{
public class LightningThreadState
{
internal readonly int mainThreadId;
internal readonly bool multiThreaded;
private Thread lightningThread;
private AutoResetEvent lightningThreadEvent = new AutoResetEvent(initialState: false);
private readonly Queue<Action> actionsForBackgroundThread = new Queue<Action>();
private readonly Queue<KeyValuePair<Action<bool>, ManualResetEvent>> actionsForMainThread = new Queue<KeyValuePair<Action<bool>, ManualResetEvent>>();
public bool Running = true;
private bool isTerminating;
private bool UpdateMainThreadActionsOnce(bool inDestroy)
{
KeyValuePair<Action<bool>, ManualResetEvent> keyValuePair;
lock (actionsForMainThread)
{
if (actionsForMainThread.Count == 0)
{
return false;
}
keyValuePair = actionsForMainThread.Dequeue();
}
try
{
keyValuePair.Key(inDestroy);
}
catch
{
}
if (keyValuePair.Value != null)
{
keyValuePair.Value.Set();
}
return true;
}
private void BackgroundThreadMethod()
{
Action action = null;
while (Running)
{
try
{
if (!lightningThreadEvent.WaitOne(500))
{
continue;
}
while (true)
{
lock (actionsForBackgroundThread)
{
if (actionsForBackgroundThread.Count == 0)
{
break;
}
action = actionsForBackgroundThread.Dequeue();
goto IL_0051;
}
IL_0051:
action();
}
}
catch (ThreadAbortException)
{
}
catch (Exception ex2)
{
Debug.LogErrorFormat("Lightning thread exception: {0}", ex2);
}
}
}
public LightningThreadState(bool multiThreaded)
{
mainThreadId = Thread.CurrentThread.ManagedThreadId;
this.multiThreaded = multiThreaded;
lightningThread = new Thread(BackgroundThreadMethod)
{
IsBackground = true,
Name = "LightningBoltScriptThread"
};
lightningThread.Start();
}
public void TerminateAndWaitForEnd(bool inDestroy)
{
isTerminating = true;
while (true)
{
if (UpdateMainThreadActionsOnce(inDestroy))
{
continue;
}
lock (actionsForBackgroundThread)
{
if (actionsForBackgroundThread.Count == 0)
{
break;
}
}
}
}
public void UpdateMainThreadActions()
{
if (multiThreaded)
{
while (UpdateMainThreadActionsOnce(inDestroy: false))
{
}
}
}
public bool AddActionForMainThread(Action<bool> action, bool waitForAction = false)
{
if (isTerminating)
{
return false;
}
if (Thread.CurrentThread.ManagedThreadId == mainThreadId || !multiThreaded)
{
action(obj: true);
return true;
}
ManualResetEvent manualResetEvent = (waitForAction ? new ManualResetEvent(initialState: false) : null);
lock (actionsForMainThread)
{
actionsForMainThread.Enqueue(new KeyValuePair<Action<bool>, ManualResetEvent>(action, manualResetEvent));
}
manualResetEvent?.WaitOne(10000);
return true;
}
public bool AddActionForBackgroundThread(Action action)
{
if (isTerminating)
{
return false;
}
if (!multiThreaded)
{
action();
}
else
{
lock (actionsForBackgroundThread)
{
actionsForBackgroundThread.Enqueue(action);
}
lightningThreadEvent.Set();
}
return true;
}
}
}