Fixed #12
This commit is contained in:
NotAlwaysTrue
2025-12-26 01:16:05 +08:00
parent 81f44969ee
commit e715fdc835
4 changed files with 56 additions and 75 deletions
@@ -479,7 +479,7 @@ namespace Barotrauma
{ {
foreach (Fixture fixture in triggerBody.FarseerBody.FixtureList) foreach (Fixture fixture in triggerBody.FarseerBody.FixtureList)
{ {
ContactEdge contactEdge = fixture.Body.ContactList; ContactEdge contactEdge = fixture.Body.ContactList.CreateCopy();
while (contactEdge != null) while (contactEdge != null)
{ {
if (contactEdge.Contact != null && if (contactEdge.Contact != null &&
@@ -652,34 +652,28 @@ namespace Barotrauma
bool shouldUpdatePower = mapEntityUpdateTick % PoweredUpdateInterval == 0; bool shouldUpdatePower = mapEntityUpdateTick % PoweredUpdateInterval == 0;
// Buffer lists to avoid repeated allocations // Buffer lists to avoid repeated allocations
var hullList = shouldUpdateMapEntities ? Hull.HullList.ToList() : null; List<Hull> hullList = new List<Hull>(Hull.HullList);
var structureList = shouldUpdateMapEntities ? Structure.WallList.ToList() : null; List<Structure> structureList = new List<Structure>(Structure.WallList);
var gapList = Gap.GapList.ToList(); List<Gap> gapList = new List<Gap>(Gap.GapList);
var itemList = shouldUpdateMapEntities ? Item.ItemList.ToList() : null; List<Item> itemList = new List<Item>(Item.ItemList);
// 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
() => () =>
{ {
if (shouldUpdateMapEntities && hullList != null) Parallel.ForEach(hullList, parallelOptions, hull =>
{ {
Parallel.ForEach(hullList, parallelOptions, hull => hull.Update(deltaTime, cam);
{ });
hull.Update(deltaTime * MapEntityUpdateInterval, cam);
});
}
}, },
// Structure parallel update // Structure parallel update
() => () =>
{ {
if (shouldUpdateMapEntities && structureList != null) Parallel.ForEach(structureList, parallelOptions, structure =>
{ {
Parallel.ForEach(structureList, parallelOptions, structure => structure.Update(deltaTime, cam);
{ });
structure.Update(deltaTime * MapEntityUpdateInterval, cam);
});
}
}, },
// Gap reset (must be done before update) // Gap reset (must be done before update)
() => () =>
@@ -694,7 +688,7 @@ namespace Barotrauma
{ {
if (shouldUpdatePower) if (shouldUpdatePower)
{ {
Powered.UpdatePower(deltaTime * PoweredUpdateInterval); Powered.UpdatePower(deltaTime);
} }
} }
); );
@@ -721,33 +715,30 @@ 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)
if (shouldUpdateMapEntities && itemList != null) Item.UpdatePendingConditionUpdates(deltaTime);
float scaledDeltaTime = deltaTime;
Item lastUpdatedItem = null;
try
{ {
Item.UpdatePendingConditionUpdates(deltaTime); foreach (Item item in itemList)
float scaledDeltaTime = deltaTime * MapEntityUpdateInterval;
Item lastUpdatedItem = null;
try
{ {
foreach (Item item in itemList) lastUpdatedItem = item;
{ 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);
}
UpdateAllProjSpecific(scaledDeltaTime);
Spawner?.Update();
} }
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);
Spawner?.Update();
#if CLIENT #if CLIENT
sw.Stop(); sw.Stop();
@@ -151,23 +151,16 @@ namespace Barotrauma
var physicsBodies = PhysicsBody.List.ToList(); var physicsBodies = PhysicsBody.List.ToList();
Parallel.Invoke(parallelOptions, Parallel.ForEach(physicsBodies, parallelOptions, body =>
() =>
{ {
Parallel.ForEach(physicsBodies, parallelOptions, body => if ((body.Enabled || body.UserData is Character) &&
body.BodyType != BodyType.Static)
{ {
if ((body.Enabled || body.UserData is Character) && body.Update();
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)
{ {
@@ -183,10 +176,8 @@ namespace Barotrauma
var sw = new System.Diagnostics.Stopwatch(); var sw = new System.Diagnostics.Stopwatch();
sw.Start(); sw.Start();
Parallel.Invoke(parallelOptions, GameMain.ParticleManager.Update((float)deltaTime);
() => GameMain.ParticleManager.Update((float)deltaTime), if (Level.Loaded != null) Level.Loaded.Update((float)deltaTime, cam);
() => { 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);
@@ -252,25 +243,25 @@ namespace Barotrauma
Character.Controlled?.UpdateLocalCursor(cam); Character.Controlled?.UpdateLocalCursor(cam);
#elif SERVER #elif SERVER
Parallel.Invoke(parallelOptions, 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();
Parallel.ForEach(submarines, parallelOptions, sub => foreach(Submarine sub in submarines)
{ {
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);
@@ -302,11 +293,10 @@ 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)
Parallel.ForEach(submarines, parallelOptions, sub =>
{ {
sub.Update((float)deltaTime); sub.Update((float)deltaTime);
}); }
#if CLIENT #if CLIENT
sw.Stop(); sw.Stop();