diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs index 965cfeec8..212f4b56b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs @@ -297,6 +297,7 @@ namespace Barotrauma public void Update() { Hook?.Update(); + LuaCsTimer.Update(); } public void Stop() @@ -312,6 +313,7 @@ namespace Barotrauma if (Thread.CurrentThread == GameMain.MainThread) { Hook?.Call("stop"); + LuaCsTimer.Clear(); } Game?.Stop(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs index 0b9a53ada..d2c35bf52 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsUtility.cs @@ -13,28 +13,12 @@ using System.Xml.Linq; namespace Barotrauma { - public partial class LuaCsTimer - { - public static long LastUpdateTime = 0; - - public static double Time - { - get - { - return GetTime(); - } - } - - public static void Wait(LuaCsAction action, int millisecondDelay) - { - GameMain.LuaCs.Hook.EnqueueTimed((float)Timing.TotalTime + (millisecondDelay / 1000f), action); - } - - public static double GetTime() - { - return Timing.TotalTime; - } + public class LuaCsTimer + { + public static long LastUpdateTime = 0; + public static double Time => Timing.TotalTime; + public static float GetUsageMemory() { Process proc = Process.GetCurrentProcess(); @@ -43,7 +27,82 @@ namespace Barotrauma return memory; } - } + + private class TimerComparer : IComparer + { + public int Compare(TimedAction timedAction1, TimedAction timedAction2) + { + if (timedAction1 == null || timedAction2 == null) + return 0; + return -Math.Sign(timedAction2.executionTime - timedAction1.executionTime); + } + } + + private class TimedAction + { + public LuaCsAction action + { + get; + private set; + } + + private int delayMs; + + public double executionTime + { + get; + private set; + } + public TimedAction(LuaCsAction action, int delayMs) + { + this.action = action; + this.delayMs = delayMs; + executionTime = Time + (delayMs / 1000f); + } + } + + private static List timedActions = new List(); + + private static void AddTimer(TimedAction timedAction) + { + int insertionPoint = timedActions.BinarySearch(timedAction, new TimerComparer()); + + if (insertionPoint < 0) + { + insertionPoint = ~insertionPoint; + } + + timedActions.Insert(insertionPoint, timedAction); + } + + public static void Update() + { + while (timedActions.Count > 0) + { + TimedAction timedAction = timedActions[0]; + if (Time >= timedAction.executionTime) + { + timedAction.action(); + timedActions.RemoveAt(0); + } + else + { + break; + } + } + } + + public static void Clear() + { + timedActions = new List(); + } + + public static void Wait(LuaCsAction action, int millisecondDelay) + { + TimedAction timedAction = new TimedAction(action, millisecondDelay); + AddTimer(timedAction); + } + } partial class LuaCsFile {