using System; using System.Collections.Generic; using System.Diagnostics; namespace Barotrauma { public class LuaCsTimer { public static double Time => Timing.TotalTime; public static double GetTime() => Time; public static double AccumulatorMax { get { return Timing.AccumulatorMax; } set { Timing.AccumulatorMax = value; } } 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; } public double ExecutionTime { get; private set; } public TimedAction(LuaCsAction action, int delayMs) { this.Action = action; ExecutionTime = Time + (delayMs / 1000f); } } private List timedActions = new List(); private void AddTimer(TimedAction timedAction) { int insertionPoint = timedActions.BinarySearch(timedAction, new TimerComparer()); if (insertionPoint < 0) { insertionPoint = ~insertionPoint; } timedActions.Insert(insertionPoint, timedAction); } public void Update() { List timedActionsToRemove = new List(); for (int i = 0; i < timedActions.Count; i++) { TimedAction timedAction = timedActions[i]; if (Time >= timedAction.ExecutionTime) { try { timedAction.Action(); } catch (Exception e) { GameMain.LuaCs.HandleException(e, LuaCsMessageOrigin.CSharpMod); } timedActionsToRemove.Add(timedAction); } else { break; } } foreach (TimedAction timedAction in timedActionsToRemove) { timedActions.Remove(timedAction); } } public void Clear() { timedActions = new List(); } public void Wait(LuaCsAction action, int millisecondDelay) { TimedAction timedAction = new TimedAction(action, millisecondDelay); AddTimer(timedAction); } } }