OBT/1.0.3

Restored multiple removed parallel stuff
Restored PF support(why)
Fixed #7
This commit is contained in:
NotAlwaysTrue
2025-12-27 02:12:25 +08:00
committed by GitHub
4 changed files with 109 additions and 85 deletions
@@ -8,6 +8,9 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using static Barotrauma.EosInterface.Ownership; using static Barotrauma.EosInterface.Ownership;
// DO NOT TOUCH ANYTHING HERE
// OR EVERYTHING WILL FAIL
namespace Barotrauma.Networking namespace Barotrauma.Networking
{ {
class ServerEntityEvent : NetEntityEvent class ServerEntityEvent : NetEntityEvent
@@ -652,28 +652,34 @@ namespace Barotrauma
bool shouldUpdatePower = mapEntityUpdateTick % PoweredUpdateInterval == 0; bool shouldUpdatePower = mapEntityUpdateTick % PoweredUpdateInterval == 0;
// Buffer lists to avoid repeated allocations // Buffer lists to avoid repeated allocations
List<Hull> hullList = new List<Hull>(Hull.HullList); var hullList = shouldUpdateMapEntities ? Hull.HullList.ToList() : null;
List<Structure> structureList = new List<Structure>(Structure.WallList); var structureList = shouldUpdateMapEntities ? Structure.WallList.ToList() : null;
List<Gap> gapList = new List<Gap>(Gap.GapList); var gapList = Gap.GapList.ToList();
List<Item> itemList = new List<Item>(Item.ItemList); var itemList = shouldUpdateMapEntities ? Item.ItemList.ToList() : null;
// First phase: parallel updates that have no order dependencies // First phase: parallel updates that have no order dependencies
Parallel.Invoke(parallelOptions, Parallel.Invoke(parallelOptions,
// Hull parallel update // Hull parallel update
() => () =>
{ {
Parallel.ForEach(hullList, parallelOptions, hull => if (shouldUpdateMapEntities && hullList != null)
{ {
hull.Update(deltaTime, cam); Parallel.ForEach(hullList, parallelOptions, hull =>
}); {
hull.Update(deltaTime * MapEntityUpdateInterval, cam);
});
}
}, },
// Structure parallel update // Structure parallel update
() => () =>
{ {
Parallel.ForEach(structureList, parallelOptions, structure => if (shouldUpdateMapEntities && structureList != null)
{ {
structure.Update(deltaTime, cam); Parallel.ForEach(structureList, parallelOptions, structure =>
}); {
structure.Update(deltaTime * MapEntityUpdateInterval, cam);
});
}
}, },
// Gap reset (must be done before update) // Gap reset (must be done before update)
() => () =>
@@ -688,7 +694,7 @@ namespace Barotrauma
{ {
if (shouldUpdatePower) if (shouldUpdatePower)
{ {
Powered.UpdatePower(deltaTime); Powered.UpdatePower(deltaTime * PoweredUpdateInterval);
} }
} }
); );
@@ -715,30 +721,33 @@ namespace Barotrauma
#endif #endif
// Item update (Item.Update() is not thread-safe and must be executed on the main thread) // Item update (Item.Update() is not thread-safe and must be executed on the main thread)
Item.UpdatePendingConditionUpdates(deltaTime); if (shouldUpdateMapEntities && itemList != null)
float scaledDeltaTime = deltaTime;
Item lastUpdatedItem = null;
try
{ {
foreach (Item item in itemList) Item.UpdatePendingConditionUpdates(deltaTime);
float scaledDeltaTime = deltaTime * MapEntityUpdateInterval;
Item lastUpdatedItem = null;
try
{ {
lastUpdatedItem = item; foreach (Item item in itemList)
item.Update(scaledDeltaTime, cam); {
lastUpdatedItem = item;
item.Update(scaledDeltaTime, cam);
}
}
catch (InvalidOperationException e)
{
GameAnalyticsManager.AddErrorEventOnce(
"MapEntity.UpdateAll:ItemUpdateInvalidOperation",
GameAnalyticsManager.ErrorSeverity.Critical,
$"Error while updating item {lastUpdatedItem?.Name ?? "null"}: {e.Message}");
throw new InvalidOperationException($"Error while updating item {lastUpdatedItem?.Name ?? "null"}", innerException: e);
} }
}
catch (InvalidOperationException e)
{
GameAnalyticsManager.AddErrorEventOnce(
"MapEntity.UpdateAll:ItemUpdateInvalidOperation",
GameAnalyticsManager.ErrorSeverity.Critical,
$"Error while updating item {lastUpdatedItem?.Name ?? "null"}: {e.Message}");
throw new InvalidOperationException($"Error while updating item {lastUpdatedItem?.Name ?? "null"}", innerException: e);
}
UpdateAllProjSpecific(scaledDeltaTime); UpdateAllProjSpecific(scaledDeltaTime);
Spawner?.Update(); Spawner?.Update();
}
#if CLIENT #if CLIENT
sw.Stop(); sw.Stop();
@@ -2,16 +2,17 @@
using Barotrauma.IO; using Barotrauma.IO;
using Barotrauma.Items.Components; using Barotrauma.Items.Components;
using Barotrauma.Networking; using Barotrauma.Networking;
using Barotrauma.PerkBehaviors;
using FarseerPhysics; using FarseerPhysics;
using FarseerPhysics.Dynamics; using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Barotrauma.PerkBehaviors;
using Voronoi2; using Voronoi2;
namespace Barotrauma namespace Barotrauma
@@ -508,23 +509,16 @@ namespace Barotrauma
return dockedBorders; return dockedBorders;
} }
private readonly HashSet<Submarine> connectedSubs; private readonly ConcurrentBag<Submarine> connectedSubs;
/// <summary> /// <summary>
/// Returns a list of all submarines that are connected to this one via docking ports, including this sub. /// Returns a list of all submarines that are connected to this one via docking ports, including this sub.
/// </summary> /// </summary>
public IEnumerable<Submarine> GetConnectedSubs() public ConcurrentBag<Submarine> GetConnectedSubs()
{ {
return connectedSubs; return connectedSubs;
} }
public void RefreshConnectedSubs() private void GetConnectedSubsRecursive(ConcurrentBag<Submarine> subs)
{
connectedSubs.Clear();
connectedSubs.Add(this);
GetConnectedSubsRecursive(connectedSubs);
}
private void GetConnectedSubsRecursive(HashSet<Submarine> subs)
{ {
foreach (Submarine dockedSub in DockedTo) foreach (Submarine dockedSub in DockedTo)
{ {
@@ -534,6 +528,12 @@ namespace Barotrauma
} }
} }
public void RefreshConnectedSubs()
{
connectedSubs.Clear();
connectedSubs.Add(this);
GetConnectedSubsRecursive(connectedSubs);
}
/// <summary> /// <summary>
/// Attempt to find a spawn position close to the specified position where the sub doesn't collide with walls/ruins /// Attempt to find a spawn position close to the specified position where the sub doesn't collide with walls/ruins
/// </summary> /// </summary>
@@ -1551,6 +1551,7 @@ namespace Barotrauma
if (includingConnectedSubs) if (includingConnectedSubs)
{ {
// Performance-sensitive code -> implemented without Linq. // Performance-sensitive code -> implemented without Linq.
foreach (Submarine s in connectedSubs) foreach (Submarine s in connectedSubs)
{ {
if (s == entity.Submarine && (allowDifferentTeam || entity.Submarine.TeamID == TeamID) && (allowDifferentType || entity.Submarine.Info.Type == Info.Type)) if (s == entity.Submarine && (allowDifferentTeam || entity.Submarine.TeamID == TeamID) && (allowDifferentType || entity.Submarine.Info.Type == Info.Type))
@@ -1642,7 +1643,7 @@ namespace Barotrauma
{ {
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
connectedSubs = new HashSet<Submarine>(2) connectedSubs = new ConcurrentBag<Submarine>
{ {
this this
}; };
@@ -1829,7 +1830,7 @@ namespace Barotrauma
} }
} }
if (Screen.Selected is { IsEditor : false }) if (Screen.Selected is { IsEditor: false })
{ {
foreach (Identifier layer in Info.LayersHiddenByDefault) foreach (Identifier layer in Info.LayersHiddenByDefault)
{ {
@@ -151,16 +151,23 @@ namespace Barotrauma
var physicsBodies = PhysicsBody.List.ToList(); var physicsBodies = PhysicsBody.List.ToList();
Parallel.ForEach(physicsBodies, parallelOptions, body => Parallel.Invoke(parallelOptions,
() =>
{ {
if ((body.Enabled || body.UserData is Character) && Parallel.ForEach(physicsBodies, parallelOptions, body =>
body.BodyType != BodyType.Static)
{ {
body.Update(); if ((body.Enabled || body.UserData is Character) &&
} body.BodyType != BodyType.Static)
}); {
body.Update();
GameMain.GameSession?.Update((float)deltaTime); }
});
},
() =>
{
GameMain.GameSession?.Update((float)deltaTime);
}
);
foreach (PhysicsBody body in physicsBodies) foreach (PhysicsBody body in physicsBodies)
{ {
@@ -176,8 +183,10 @@ namespace Barotrauma
var sw = new System.Diagnostics.Stopwatch(); var sw = new System.Diagnostics.Stopwatch();
sw.Start(); sw.Start();
GameMain.ParticleManager.Update((float)deltaTime); Parallel.Invoke(parallelOptions,
if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, cam); () => GameMain.ParticleManager.Update((float)deltaTime),
() => { if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, cam); }
);
sw.Stop(); sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Update:Particles+Level", sw.ElapsedTicks); GameMain.PerformanceCounter.AddElapsedTicks("Update:Particles+Level", sw.ElapsedTicks);
@@ -243,25 +252,26 @@ namespace Barotrauma
Character.Controlled?.UpdateLocalCursor(cam); Character.Controlled?.UpdateLocalCursor(cam);
#elif SERVER #elif SERVER
if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, Camera.Instance); if (Level.Loaded != null)
{
Level.Loaded.Update((float)deltaTime, Camera.Instance);
}
Character.UpdateAll((float)deltaTime, Camera.Instance); Character.UpdateAll((float)deltaTime, Camera.Instance);
#endif #endif
var submarines = Submarine.Loaded.ToList(); var submarines = Submarine.Loaded.ToList();
foreach(Submarine sub in submarines) Parallel.ForEach(submarines, parallelOptions, sub =>
{ {
sub.SetPrevTransform(sub.Position); sub.SetPrevTransform(sub.Position);
} });
// Parallel.ForEach(physicsBodies, parallelOptions, body =>
foreach (PhysicsBody body in physicsBodies)
{ {
if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static) if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static)
{ {
body.SetPrevTransform(body.SimPosition, body.Rotation); body.SetPrevTransform(body.SimPosition, body.Rotation);
} }
} });
#if CLIENT #if CLIENT
MapEntity.UpdateAll((float)deltaTime, cam, parallelOptions); MapEntity.UpdateAll((float)deltaTime, cam, parallelOptions);
@@ -293,7 +303,8 @@ namespace Barotrauma
GameMain.PerformanceCounter.AddElapsedTicks("Update:Ragdolls", sw.ElapsedTicks); GameMain.PerformanceCounter.AddElapsedTicks("Update:Ragdolls", sw.ElapsedTicks);
sw.Restart(); sw.Restart();
#endif #endif
foreach (var sub in submarines)
foreach(Submarine sub in submarines)
{ {
sub.Update((float)deltaTime); sub.Update((float)deltaTime);
} }