using System; using System.Collections.Generic; namespace Barotrauma { /// /// Thread-safe queue for deferring physics body creation operations to the main thread. /// This is necessary because Farseer Physics' DynamicTree is not thread-safe, /// and physics bodies cannot be safely created during parallel item updates. /// static class PhysicsBodyQueue { private static readonly object _lock = new object(); private static readonly Queue _pendingCreations = new Queue(); /// /// Enqueues a physics body creation action to be executed on the main thread. /// This method is thread-safe and can be called from parallel update loops. /// /// The action that creates the physics body public static void EnqueueCreation(Action createAction) { if (createAction == null) { return; } lock (_lock) { _pendingCreations.Enqueue(createAction); } } /// /// Gets the number of pending physics body creation operations. /// public static int PendingCount { get { lock (_lock) { return _pendingCreations.Count; } } } /// /// Processes all pending physics body creation operations. /// Must be called on the main thread, outside of any parallel loops. /// public static void ProcessPendingCreations() { while (true) { Action action; lock (_lock) { if (_pendingCreations.Count == 0) { break; } action = _pendingCreations.Dequeue(); } try { action?.Invoke(); } catch (Exception e) { DebugConsole.ThrowError($"Error processing deferred physics body creation: {e.Message}", e); } } } /// /// Clears all pending physics body creation operations. /// Should be called when ending a round or cleaning up. /// public static void Clear() { lock (_lock) { _pendingCreations.Clear(); } } } }