Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3387,21 +3387,9 @@ public static void UpdateAll(float deltaTime, Camera cam)

characterUpdateTick++;

if (characterUpdateTick % CharacterUpdateInterval == 0)
for (int i = 0; i < CharacterList.Count; i++)
{
for (int i = 0; i < CharacterList.Count; i++)
{
if (GameMain.LuaCs.Game.UpdatePriorityCharacters.Contains(CharacterList[i])) continue;

CharacterList[i].Update(deltaTime * CharacterUpdateInterval, cam);
}
}

foreach (Character character in GameMain.LuaCs.Game.UpdatePriorityCharacters)
{
if (character.Removed) { continue; }
Debug.Assert(character is { Removed: false });
character.Update(deltaTime, cam);
CharacterList[i].Update(deltaTime, cam);
}

#if CLIENT
Expand Down
1 change: 1 addition & 0 deletions Barotrauma/BarotraumaShared/SharedSource/Map/Gap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ public bool RefreshOutsideCollider()
{
SingleThreadWorker.GlobalWorker.AddAction(() =>
{
if (outsideCollisionBlocker == null) { return; }
outsideCollisionBlocker.Enabled = false;
});

Expand Down
14 changes: 7 additions & 7 deletions Barotrauma/BarotraumaShared/SharedSource/Map/MapEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,8 @@ public static void UpdateAll(float deltaTime, Camera cam, ParallelOptions parall
// Buffer lists to avoid repeated allocations
var hullList = Hull.HullList.ToList();
var structureList = Structure.WallList.ToList();
var gapList = Gap.GapList.ToList();
// First, WHY THIS LINQ GOT A NULL ERROR? Second, WHY??
List<Gap> shuffledGaps = Gap.GapList?.OrderBy(g => Rand.Int(int.MaxValue)).ToList() ?? Gap.GapList.ToList();
var itemList = Item.ItemList.ToList();

// First phase: parallel updates that have no order dependencies
Expand Down Expand Up @@ -679,14 +680,12 @@ public static void UpdateAll(float deltaTime, Camera cam, ParallelOptions parall

// moved waterflow reset here to see if we can reduce at least some time
{
// if crashed, go ask the god damn physics engine :(
var shuffledGaps = gapList.OrderBy(g => Rand.Int(int.MaxValue)).ToList();
if (shuffledGaps == null) { shuffledGaps = Gap.GapList; }
Parallel.ForEach(shuffledGaps, parallelOptions, gap =>
{
gap.ResetWaterFlowThisFrame();
gap.Update(deltaTime, cam);
});
SingleThreadWorker.GlobalWorker.RunActions();
},
// Powered components update
() =>
Expand All @@ -695,6 +694,8 @@ public static void UpdateAll(float deltaTime, Camera cam, ParallelOptions parall
}
);

SingleThreadWorker.GlobalWorker.RunActions();

#if CLIENT
// Hull Cheats need to be executed after Hull update
Hull.UpdateCheats(deltaTime, cam);
Expand All @@ -709,15 +710,14 @@ public static void UpdateAll(float deltaTime, Camera cam, ParallelOptions parall
// Item update (Item.Update() is not thread-safe and must be executed on the main thread)
Item.UpdatePendingConditionUpdates(deltaTime);

float scaledDeltaTime = deltaTime * MapEntityUpdateInterval;
Item lastUpdatedItem = null;

try
{
foreach (Item item in itemList)
{
lastUpdatedItem = item;
item.Update(scaledDeltaTime, cam);
item.Update(deltaTime, cam);
}
}
catch (InvalidOperationException e)
Expand All @@ -729,7 +729,7 @@ public static void UpdateAll(float deltaTime, Camera cam, ParallelOptions parall
throw new InvalidOperationException($"Error while updating item {lastUpdatedItem?.Name ?? "null"}", innerException: e);
}

UpdateAllProjSpecific(scaledDeltaTime);
UpdateAllProjSpecific(deltaTime);
Spawner?.Update();

#if CLIENT
Expand Down
59 changes: 14 additions & 45 deletions Barotrauma/BarotraumaShared/SharedSource/Screens/GameScreen.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//#define RUN_PHYSICS_IN_SEPARATE_THREAD

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using System.Threading;
using FarseerPhysics.Dynamics;
using FarseerPhysics;
Expand All @@ -23,9 +21,10 @@ partial class GameScreen : Screen
private object updateLock = new object();
private double physicsTime;

// -2 here bcuz we alread have a SEEM thread there
private static readonly ParallelOptions parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = Math.Max(4, Environment.ProcessorCount - 1)
MaxDegreeOfParallelism = Math.Max(4, Environment.ProcessorCount - 2)
};

#if CLIENT
Expand Down Expand Up @@ -78,14 +77,6 @@ public override void Select()

MapEntity.ClearHighlightedEntities();

#if RUN_PHYSICS_IN_SEPARATE_THREAD
var physicsThread = new Thread(ExecutePhysics)
{
Name = "Physics thread",
IsBackground = true
};
physicsThread.Start();
#endif
}

public override void Deselect()
Expand Down Expand Up @@ -114,14 +105,10 @@ public override void Deselect()
public override void Update(double deltaTime)
{

#warning For now CL side performance counter is partly useless bucz multiple changes on such things. Need time to take care of it

#if RUN_PHYSICS_IN_SEPARATE_THREAD
physicsTime += deltaTime;
lock (updateLock)
{
#endif
var submarines = Submarine.Loaded.ToList();
var physicsBodies = PhysicsBody.List.ToList();

#warning For now CL side performance counter is partly useless bucz multiple changes on such things. Need time to take care of it

#if DEBUG && CLIENT
if (GameMain.GameSession != null && !DebugConsole.IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
Expand Down Expand Up @@ -150,8 +137,6 @@ public override void Update(double deltaTime)

GameTime += deltaTime;

var physicsBodies = PhysicsBody.List.ToList();

Parallel.ForEach(physicsBodies, parallelOptions, body =>
{
if ((body.Enabled || body.UserData is Character) &&
Expand All @@ -162,14 +147,6 @@ public override void Update(double deltaTime)
});
GameMain.GameSession?.Update((float)deltaTime);

Parallel.ForEach(physicsBodies, parallelOptions, body =>
{
if (body.Enabled && body.BodyType != BodyType.Static)
{
body.SetPrevTransform(body.SimPosition, body.Rotation);
}
});

MapEntity.ClearHighlightedEntities();

#if CLIENT
Expand Down Expand Up @@ -254,20 +231,19 @@ public override void Update(double deltaTime)
StatusEffect.UpdateAll((float)deltaTime);
#endif

var submarines = Submarine.Loaded.ToList();

Parallel.ForEach(submarines, parallelOptions, sub =>
foreach (Submarine sub in submarines)
{
sub.SetPrevTransform(sub.Position);
});
}

Parallel.ForEach(physicsBodies, parallelOptions, body =>
foreach (var body in physicsBodies)
{
if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static)
{
body.SetPrevTransform(body.SimPosition, body.Rotation);
if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static)
{
body.SetPrevTransform(body.SimPosition, body.Rotation);
}
});
}


#if CLIENT
MapEntity.UpdateAll((float)deltaTime, cam, parallelOptions);
Expand Down Expand Up @@ -306,8 +282,6 @@ public override void Update(double deltaTime)
GameMain.PerformanceCounter.AddElapsedTicks("Update:Submarine", sw.ElapsedTicks);
sw.Restart();
#endif

#if !RUN_PHYSICS_IN_SEPARATE_THREAD
try
{
GameMain.World.Step((float)Timing.Step);
Expand All @@ -318,17 +292,12 @@ public override void Update(double deltaTime)
DebugConsole.ThrowError(errorMsg, e);
GameAnalyticsManager.AddErrorEventOnce("GameScreen.Update:WorldLockedException" + e.Message, GameAnalyticsManager.ErrorSeverity.Critical, errorMsg);
}
#endif

#if CLIENT
sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("Update:Physics", sw.ElapsedTicks);
#endif
UpdateProjSpecific(deltaTime);

#if RUN_PHYSICS_IN_SEPARATE_THREAD
}
#endif
}

partial void UpdateProjSpecific(double deltaTime);
Expand Down
16 changes: 14 additions & 2 deletions Barotrauma/BarotraumaShared/SharedSource/SingleThreadWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@ public class SingleThreadWorker

public static SingleThreadWorker GlobalWorker = new SingleThreadWorker();

/// <summary>
/// Initilize a SingleThreadWorker
/// SingleThreadWorker or STW for short is a FIFO queue ensure single-thread execution of a series of actions.
/// </summary>
public SingleThreadWorker()
{
ActionQueue = new ConcurrentQueue<Action>();
}

/// <summary>
/// Add a pending action in a STW queue
/// </summary>
/// <param name="action"></param>
public void AddAction(Action action)
{
ActionQueue.Enqueue(action);
}

/// <summary>
/// Run all pending actions in the STW queue
/// </summary>
[STAThread]
public void RunActions()
{
Expand All @@ -32,8 +43,9 @@ public void RunActions()
{
// 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 = ConsoleColor.Yellow;
Console.WriteLine($"WARNING: Error occurred when running Single Thread Actions. " +
$"If the server didn't crash or stop responding then this should be fine \n{e}");
Console.ForegroundColor = Console.ForegroundColor;
}
}
Expand Down