From a5dd4ffe369c65015b480f7845b227033b32d0ae Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sat, 6 Jul 2024 16:03:36 +0100 Subject: [PATCH] Cache teams in observer logic The player state and teams are fixed after the game starts, so it is safe to cache the resulting teams in the observer logic rather than re-evaluating them each time. --- .../Logic/Ingame/ObserverShroudSelectorLogic.cs | 14 +++++++------- .../Widgets/Logic/Ingame/ObserverStatsLogic.cs | 15 +++++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs index b990115c83..48542417ed 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic const string NoTeam = "label-no-team"; readonly CameraOption combined, disableShroud; - readonly IOrderedEnumerable> teams; + readonly IGrouping[] teams; readonly bool limitViews; readonly HotkeyReference combinedViewKey = new(); @@ -112,12 +112,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic teams = world.Players.Where(p => !p.NonCombatant && p.Playable) .Select(p => new CameraOption(this, p)) .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team) - .OrderBy(g => g.Key); + .OrderBy(g => g.Key) + .ToArray(); - var teamsList = teams.ToList(); - var noTeams = teamsList.Count == 1; + var noTeams = teams.Length == 1; var totalPlayers = 0; - foreach (var t in teamsList) + foreach (var t in teams) { totalPlayers += t.Count(); var label = noTeams ? TranslationProvider.GetString(Players) : t.Key > 0 @@ -210,8 +210,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9) { var key = (int)e.Key - (int)Keycode.NUMBER_0; - var team = teams.Where(t => t.Key == key).SelectMany(s => s).ToList(); - if (team.Count == 0) + var team = teams.SingleOrDefault(t => t.Key == key)?.ToList(); + if (team == null || team.Count == 0) return false; if (e.Modifiers == Modifiers.Shift) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs index 07d0109fec..3579595627 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs @@ -79,8 +79,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly LineGraphWidget incomeGraph; readonly LineGraphWidget armyValueGraph; readonly ScrollItemWidget teamTemplate; - readonly IEnumerable players; - readonly IOrderedEnumerable> teams; + readonly Player[] players; + readonly IGrouping[] teams; readonly bool hasTeams; readonly World world; readonly WorldRenderer worldRenderer; @@ -100,9 +100,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic for (var i = 0; i < keyNames.Length; i++) statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); - players = world.Players.Where(p => !p.NonCombatant && p.Playable); - teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); - hasTeams = !(teams.Count() == 1 && teams.First().Key == 0); + players = world.Players.Where(p => !p.NonCombatant && p.Playable).ToArray(); + teams = players + .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team) + .OrderBy(g => g.Key) + .ToArray(); + hasTeams = !(teams.Length == 1 && teams[0].Key == 0); basicStatsHeaders = widget.Get("BASIC_STATS_HEADERS"); economyStatsHeaders = widget.Get("ECONOMY_STATS_HEADERS"); @@ -595,7 +598,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic } // HACK The height of the templates and the scrollpanel needs to be kept in synch - bool ShowScrollBar => players.Count() + (hasTeams ? teams.Count() : 0) > 10; + bool ShowScrollBar => players.Length + (hasTeams ? teams.Length : 0) > 10; sealed class StatsDropDownOption {