diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index a9ddcffa4b..2c9eeff87c 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -40,6 +40,7 @@ namespace OpenRA public static Settings Settings; public static CursorManager Cursor; public static bool HideCursor; + static WorldRenderer worldRenderer; static string modLaunchWrapper; @@ -589,7 +590,7 @@ namespace OpenRA if (Ui.LastTickTime.ShouldAdvance(tick)) { Ui.LastTickTime.AdvanceTickTime(tick); - Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, Ui.Tick); + Sync.RunUnsynced(world, Ui.Tick); Cursor.Tick(); } @@ -601,14 +602,14 @@ namespace OpenRA Sound.Tick(); - Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, orderManager.TickImmediate); + Sync.RunUnsynced(world, orderManager.TickImmediate); if (world == null) return; if (orderManager.TryTick()) { - Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () => + Sync.RunUnsynced(world, () => { world.OrderGenerator.Tick(world); }); @@ -620,7 +621,7 @@ namespace OpenRA // Wait until we have done our first world Tick before TickRendering if (orderManager.LocalFrameNumber > 0) - Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () => world.TickRender(worldRenderer)); + Sync.RunUnsynced(world, () => world.TickRender(worldRenderer)); } benchmark?.Tick(LocalTick); diff --git a/OpenRA.Game/Input/InputHandler.cs b/OpenRA.Game/Input/InputHandler.cs index e8c46e69eb..18d8833902 100644 --- a/OpenRA.Game/Input/InputHandler.cs +++ b/OpenRA.Game/Input/InputHandler.cs @@ -37,17 +37,17 @@ namespace OpenRA public void OnKeyInput(KeyInput input) { - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => Ui.HandleKeyPress(input)); + Sync.RunUnsynced(world, () => Ui.HandleKeyPress(input)); } public void OnTextInput(string text) { - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => Ui.HandleTextInput(text)); + Sync.RunUnsynced(world, () => Ui.HandleTextInput(text)); } public void OnMouseInput(MouseInput input) { - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => Ui.HandleInput(input)); + Sync.RunUnsynced(world, () => Ui.HandleInput(input)); } } diff --git a/OpenRA.Game/Sync.cs b/OpenRA.Game/Sync.cs index 40f3e389a1..542de78c6c 100644 --- a/OpenRA.Game/Sync.cs +++ b/OpenRA.Game/Sync.cs @@ -161,6 +161,11 @@ namespace OpenRA return t.GetHashCode(); } + public static void RunUnsynced(World world, Action fn) + { + RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => { fn(); return true; }); + } + public static void RunUnsynced(bool checkSyncHash, World world, Action fn) { RunUnsynced(checkSyncHash, world, () => { fn(); return true; }); @@ -168,13 +173,18 @@ namespace OpenRA static bool inUnsyncedCode = false; + public static T RunUnsynced(World world, Func fn) + { + return RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, fn); + } + public static T RunUnsynced(bool checkSyncHash, World world, Func fn) { - if (world == null) + // PERF: Detect sync changes in top level entry point only. Do not recalculate sync hash during reentry. + if (inUnsyncedCode || world == null) return fn(); var sync = checkSyncHash ? world.SyncHash() : 0; - var prevInUnsyncedCode = inUnsyncedCode; inUnsyncedCode = true; try @@ -183,7 +193,7 @@ namespace OpenRA } finally { - inUnsyncedCode = prevInUnsyncedCode; + inUnsyncedCode = false; if (checkSyncHash && sync != world.SyncHash()) throw new InvalidOperationException("RunUnsynced: sync-changing code may not run here"); } diff --git a/OpenRA.Mods.Common/Traits/World/LoadWidgetAtGameStart.cs b/OpenRA.Mods.Common/Traits/World/LoadWidgetAtGameStart.cs index b8116d1997..ed6c53fd2b 100644 --- a/OpenRA.Mods.Common/Traits/World/LoadWidgetAtGameStart.cs +++ b/OpenRA.Mods.Common/Traits/World/LoadWidgetAtGameStart.cs @@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits var optionsButton = root.GetOrNull("OPTIONS_BUTTON"); world.SetPauseState(false); if (optionsButton != null) - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, optionsButton.OnClick); + Sync.RunUnsynced(world, optionsButton.OnClick); } } } diff --git a/OpenRA.Mods.Common/Traits/World/Selection.cs b/OpenRA.Mods.Common/Traits/World/Selection.cs index 4c9f9573a7..b048fa054b 100644 --- a/OpenRA.Mods.Common/Traits/World/Selection.cs +++ b/OpenRA.Mods.Common/Traits/World/Selection.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var sel in a.TraitsImplementing()) sel.Selected(a); - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => world.OrderGenerator.SelectionChanged(world, actors)); + Sync.RunUnsynced(world, () => world.OrderGenerator.SelectionChanged(world, actors)); foreach (var ns in worldNotifySelection) ns.SelectionChanged(); } @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits if (actors.Remove(a)) { UpdateHash(); - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => world.OrderGenerator.SelectionChanged(world, actors)); + Sync.RunUnsynced(world, () => world.OrderGenerator.SelectionChanged(world, actors)); foreach (var ns in worldNotifySelection) ns.SelectionChanged(); } @@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var sel in a.TraitsImplementing()) sel.Selected(a); - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => world.OrderGenerator.SelectionChanged(world, actors)); + Sync.RunUnsynced(world, () => world.OrderGenerator.SelectionChanged(world, actors)); foreach (var ns in worldNotifySelection) ns.SelectionChanged(); @@ -148,7 +148,7 @@ namespace OpenRA.Mods.Common.Traits { actors.Clear(); UpdateHash(); - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => world.OrderGenerator.SelectionChanged(world, actors)); + Sync.RunUnsynced(world, () => world.OrderGenerator.SelectionChanged(world, actors)); foreach (var ns in worldNotifySelection) ns.SelectionChanged(); } @@ -170,7 +170,7 @@ namespace OpenRA.Mods.Common.Traits if (removed > 0) { UpdateHash(); - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, () => world.OrderGenerator.SelectionChanged(world, actors)); + Sync.RunUnsynced(world, () => world.OrderGenerator.SelectionChanged(world, actors)); foreach (var ns in worldNotifySelection) ns.SelectionChanged(); } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs index 3c2e50b630..f8a638ae56 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs @@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var optionsButton = playerRoot.GetOrNull("OPTIONS_BUTTON"); if (optionsButton != null) - Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, world, optionsButton.OnClick); + Sync.RunUnsynced(world, optionsButton.OnClick); }; } } diff --git a/OpenRA.Mods.Common/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Mods.Common/Widgets/WorldInteractionControllerWidget.cs index 8e1375cb95..4e7110dc26 100644 --- a/OpenRA.Mods.Common/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/WorldInteractionControllerWidget.cs @@ -211,7 +211,7 @@ namespace OpenRA.Mods.Common.Widgets public override string GetCursor(int2 screenPos) { - return Sync.RunUnsynced(Game.Settings.Debug.SyncCheckUnsyncedCode, World, () => + return Sync.RunUnsynced(World, () => { // Always show an arrow while selecting if (IsValidDragbox)