public void Add(IScriptRootData data) { if (ScriptNeedsMainThread.TryGetValue(data.ScriptId, out var needMainThread)) { data.ScriptNeedsMainThread = needMainThread; } else { ScriptNeedsMainThread.TryAdd(data.ScriptId, false); } if (WaitForExec.TryAdd(data.ScriptId, data)) { ExecQueue.Enqueue(data.ScriptId); } else { WaitForExec.AddOrUpdate(data.ScriptId, data, (scriptId, oldData) => data); } }
public void ExecNext(int maxCount, int scriptsSyncExecution, ref int syncExecCount, Stopwatch scriptLoopTimeLimiter) { if (BackgroundWorkerToDo.Count > maxCount / 2) { return; } var scriptLoopTimeLimiterStopwatch = scriptLoopTimeLimiter; var timeLimitBackgroundReached = new Func <bool>(() => scriptLoopTimeLimiterStopwatch.ElapsedMilliseconds > EmpyrionScripting.Configuration.Current.ScriptLoopBackgroundTimeLimiterMS); TimeLimitSyncReached = new Func <bool>(() => scriptLoopTimeLimiterStopwatch.ElapsedMilliseconds > EmpyrionScripting.Configuration.Current.ScriptLoopSyncTimeLimiterMS); Log($"ExecNext: {WaitForExec.Count} -> {ExecQueue.Count}", LogLevel.Debug); for (int i = maxCount - 1; i >= 0; i--) { if (ExecQueue.TryDequeue(out var scriptId) && WaitForExec.TryGetValue(scriptId, out var data)) { if (data.ScriptNeedsMainThread) { Interlocked.Increment(ref syncExecCount); if (syncExecCount > scriptsSyncExecution) { ExecQueue.Enqueue(scriptId); } else { ((ScriptRootData)data).ScriptLoopTimeLimitReached = TimeLimitSyncReached; ExecNext(data); } } else { ((ScriptRootData)data).ScriptLoopTimeLimitReached = timeLimitBackgroundReached; ExecNext(data); } }