From 8bfe8a2c374a82a9eb87224fb8f4849f44549499 Mon Sep 17 00:00:00 2001 From: NotAlwaysTrue <77662224+NotAlwaysTrue@users.noreply.github.com> Date: Thu, 8 Jan 2026 12:40:30 +0800 Subject: [PATCH] OBT/1.0.14 Fixed parallelism count issue Added SingleThreadWorker to handle single-thread related works Fixed incorrect order when updating gaps Potentially Fixed #39 --- .../BarotraumaShared/SharedSource/Map/Gap.cs | 6 ++- .../SharedSource/Map/MapEntity.cs | 4 +- .../SharedSource/Screens/GameScreen.cs | 5 ++- .../SharedSource/SingleThreadWorker.cs | 43 +++++++++++++++++++ .../Dynamics/Body.cs | 14 ------ 5 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 Barotrauma/BarotraumaShared/SharedSource/SingleThreadWorker.cs diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs index 75b051e2b..a79e4c1c6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs @@ -812,7 +812,11 @@ namespace Barotrauma if (outsideCollisionBlocker == null) { return false; } if (IsRoomToRoom || Submarine == null || open <= 0.0f || linkedTo.Count == 0 || linkedTo[0] is not Hull) { - outsideCollisionBlocker.AddToDisableQueue(); + SingleThreadWorker.GlobalWorker.AddAction(() => + { + outsideCollisionBlocker.Enabled = false; + }); + return false; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/MapEntity.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/MapEntity.cs index 1a5a78d7b..d64738684 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/MapEntity.cs @@ -681,12 +681,12 @@ namespace Barotrauma { // if crashed, go ask the god damn physics engine :( var shuffledGaps = gapList.OrderBy(g => Rand.Int(int.MaxValue)).ToList(); - Parallel.ForEach(gapList, parallelOptions, gap => + Parallel.ForEach(shuffledGaps, parallelOptions, gap => { gap.ResetWaterFlowThisFrame(); gap.Update(deltaTime, cam); }); - FarseerPhysics.Dynamics.Body.QueueDisable(); + SingleThreadWorker.GlobalWorker.RunActions(); }, // Powered components update () => diff --git a/Barotrauma/BarotraumaShared/SharedSource/Screens/GameScreen.cs b/Barotrauma/BarotraumaShared/SharedSource/Screens/GameScreen.cs index e737621b5..496d79bb1 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Screens/GameScreen.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Screens/GameScreen.cs @@ -25,7 +25,7 @@ namespace Barotrauma private static readonly ParallelOptions parallelOptions = new ParallelOptions { - MaxDegreeOfParallelism = Environment.ProcessorCount > 0 ? Environment.ProcessorCount * 2 : 16, + MaxDegreeOfParallelism = Math.Max(4, Environment.ProcessorCount - 1) }; #if CLIENT @@ -287,6 +287,7 @@ namespace Barotrauma Ragdoll.UpdateAll((float)deltaTime, cam); #elif SERVER Ragdoll.UpdateAll((float)deltaTime, Camera.Instance); + SingleThreadWorker.GlobalWorker.RunActions(); #endif #if CLIENT @@ -295,7 +296,7 @@ namespace Barotrauma sw.Restart(); #endif - foreach(Submarine sub in submarines) + foreach (Submarine sub in submarines) { sub.Update((float)deltaTime); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/SingleThreadWorker.cs b/Barotrauma/BarotraumaShared/SharedSource/SingleThreadWorker.cs new file mode 100644 index 000000000..6902f8a28 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/SingleThreadWorker.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Concurrent; + +namespace Barotrauma +{ + public class SingleThreadWorker + { + private ConcurrentQueue ActionQueue; + + public static SingleThreadWorker GlobalWorker = new SingleThreadWorker(); + + public SingleThreadWorker() + { + ActionQueue = new ConcurrentQueue(); + } + + public void AddAction(Action action) + { + ActionQueue.Enqueue(action); + } + + [STAThread] + public void RunActions() + { + while (ActionQueue.TryDequeue(out Action action)) + { + try + { + action(); + } + catch (Exception e) + { + // Just try-catch and do nothing but print errorlogs. We cannot afford crashing the game. + ConsoleColor originalForeground = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"WARNING: Error occurred when running Single Thread Actions \n{e}"); + Console.ForegroundColor = Console.ForegroundColor; + } + } + } + + } +} diff --git a/Libraries/Farseer Physics Engine 3.5/Dynamics/Body.cs b/Libraries/Farseer Physics Engine 3.5/Dynamics/Body.cs index ddd554c01..9a7ad1056 100644 --- a/Libraries/Farseer Physics Engine 3.5/Dynamics/Body.cs +++ b/Libraries/Farseer Physics Engine 3.5/Dynamics/Body.cs @@ -350,20 +350,6 @@ namespace FarseerPhysics.Dynamics } } - private static ConcurrentQueue DisableQueue = new ConcurrentQueue(); - - public static void QueueDisable() - { - while (DisableQueue.TryDequeue(out var pendingbody)) - { - pendingbody.Enabled = false; - } - } - - public void AddToDisableQueue() - { - DisableQueue.Enqueue(this); - } /// /// Create all proxies.