Unstable 0.2 Defer physics operations during parallel updates

Introduces a thread-safe queue for deferring physics operations (such as body creation and transforms) to the main thread, ensuring Farseer Physics is not accessed from parallel contexts. Updates Holdable, Item, MapEntity, and GameScreen to use the new PhysicsBodyQueue for safe physics operations during parallel updates, and refactors PhysicsBodyQueue to support general deferred physics actions.
This commit is contained in:
Eero
2025-12-28 15:10:06 +08:00
parent 49355fe32b
commit f485583621
5 changed files with 261 additions and 46 deletions
@@ -178,9 +178,23 @@ namespace Barotrauma
Parallel.Invoke(parallelOptions,
() => GameMain.ParticleManager.Update((float)deltaTime),
() => { if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, cam); }
() =>
{
PhysicsBodyQueue.IsInParallelContext = true;
try
{
if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, cam);
}
finally
{
PhysicsBodyQueue.IsInParallelContext = false;
}
}
);
// Process any physics operations queued during Level update
PhysicsBodyQueue.ProcessPendingOperations();
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Update:Particles+Level", sw.ElapsedTicks);
@@ -246,9 +260,34 @@ namespace Barotrauma
#elif SERVER
Parallel.Invoke(parallelOptions,
() => { if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, Camera.Instance); },
() => Character.UpdateAll((float)deltaTime, Camera.Instance)
() =>
{
PhysicsBodyQueue.IsInParallelContext = true;
try
{
if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, Camera.Instance);
}
finally
{
PhysicsBodyQueue.IsInParallelContext = false;
}
},
() =>
{
PhysicsBodyQueue.IsInParallelContext = true;
try
{
Character.UpdateAll((float)deltaTime, Camera.Instance);
}
finally
{
PhysicsBodyQueue.IsInParallelContext = false;
}
}
);
// Process any physics operations queued during parallel updates
PhysicsBodyQueue.ProcessPendingOperations();
#endif
var submarines = Submarine.Loaded.ToList();