MatchmakerServer/Matchmaker/BaseServer/ThreadManager.cs
2023-01-15 13:26:28 -08:00

93 lines
No EOL
2.5 KiB
C#
Executable file

namespace Matchmaker.Server.BaseServer;
internal static class ThreadManager
{
private static readonly List<Action> ExecuteOnMainThreadList = new();
private static readonly List<Action> ExecuteCopiedOnMainThread = new();
private static bool _actionToExecuteOnMainThread;
/// <summary>
/// Controls whether or not the Main Thread should run. Set to FALSE to shut down Main Thread.
/// </summary>
private static bool _isRunning;
private static Thread? _thread;
/// <summary>Sets an action to be executed on the main thread.</summary>
/// <param name="action">The action to be executed on the main thread.</param>
public static void ExecuteOnMainThread(Action action)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (action == null)
{
Terminal.LogWarn("No action to execute on main thread!");
return;
}
lock (ExecuteOnMainThreadList)
{
ExecuteOnMainThreadList.Add(action);
_actionToExecuteOnMainThread = true;
}
}
/// <summary>
/// Start the Main Thread so Packets can be acted upon
/// </summary>
public static void Start()
{
_isRunning = true;
_thread = new Thread(MainThread);
_thread.Start();
}
/// <summary>
/// Stop the Main Thread
/// </summary>
public static void Stop()
{
_isRunning = false;
}
/// <summary>
/// Executes all code meant to run on the main thread. NOTE: Call this ONLY from the main thread.
/// </summary>
public static void UpdateMain()
{
if (!_actionToExecuteOnMainThread) return;
ExecuteCopiedOnMainThread.Clear();
lock (ExecuteOnMainThreadList)
{
ExecuteCopiedOnMainThread.AddRange(ExecuteOnMainThreadList);
ExecuteOnMainThreadList.Clear();
_actionToExecuteOnMainThread = false;
}
foreach (var t in ExecuteCopiedOnMainThread)
{
t();
}
}
private static void MainThread()
{
var nextLoop = DateTime.Now;
while (_isRunning)
{
while (nextLoop < DateTime.Now)
{
GameLogic.Update();
nextLoop = nextLoop.AddMilliseconds(Constants.MsPerTick);
if (nextLoop > DateTime.Now)
{
Thread.Sleep(nextLoop - DateTime.Now);
}
}
}
}
}