From 8d3cec5bea531fe1d53d4e21df19363acfe12ba3 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sun, 11 Oct 2020 11:57:22 +0100 Subject: [PATCH] When a render method has nothing to render, eagerly return. By eagerly returning an empty enumerable in these cases, this avoids allocating an enumerable for the whole render method if nothing will be drawn. --- .../Traits/CombatDebugOverlay.cs | 9 +++-- OpenRA.Mods.Common/Traits/HitShape.cs | 7 +++- .../Traits/Render/DrawLineToTarget.cs | 35 +++++++++++-------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs index a5fa9156fe..213683e62f 100644 --- a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs @@ -55,13 +55,18 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IRenderAnnotations.RenderAnnotations(Actor self, WorldRenderer wr) { if (debugVis == null || !debugVis.CombatGeometry || self.World.FogObscures(self)) - yield break; + return Enumerable.Empty(); + return RenderAnnotations(self, wr); + } + + IEnumerable RenderAnnotations(Actor self, WorldRenderer wr) + { var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList(); if (blockers.Count > 0) { var height = new WVec(0, 0, blockers.Max(b => b.BlockingHeight.Length)); - yield return new LineAnnotationRenderable(self.CenterPosition, self.CenterPosition + height, 1, Color.Orange); + yield return new LineAnnotationRenderable(self.CenterPosition, self.CenterPosition + height, 1, Color.Orange); } var activeShapes = shapes.Where(Exts.IsTraitEnabled); diff --git a/OpenRA.Mods.Common/Traits/HitShape.cs b/OpenRA.Mods.Common/Traits/HitShape.cs index c232f4fbf2..903e9f1634 100644 --- a/OpenRA.Mods.Common/Traits/HitShape.cs +++ b/OpenRA.Mods.Common/Traits/HitShape.cs @@ -90,8 +90,13 @@ namespace OpenRA.Mods.Common.Traits IEnumerable ITargetablePositions.TargetablePositions(Actor self) { if (IsTraitDisabled) - yield break; + return Enumerable.Empty(); + return TargetablePositions(self); + } + + IEnumerable TargetablePositions(Actor self) + { if (Info.UseTargetableCellsOffsets && targetableCells != null) foreach (var c in targetableCells.TargetableCells()) yield return self.World.Map.CenterOfCell(c.Cell); diff --git a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs index f017d9a338..286368167e 100644 --- a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs +++ b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs @@ -63,17 +63,27 @@ namespace OpenRA.Mods.Common.Traits ShowTargetLines(self); } - IEnumerable IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr) + bool ShouldRender(Actor self) { if (!self.Owner.IsAlliedWith(self.World.LocalPlayer) || Game.Settings.Game.TargetLines == TargetLinesType.Disabled) - yield break; + return false; // Players want to see the lines when in waypoint mode. var force = Game.GetModifierKeys().HasModifier(Modifiers.Shift) || self.World.OrderGenerator is ForceModifiersOrderGenerator; - if (Game.RunTime > lifetime && !force) - yield break; + return force || Game.RunTime <= lifetime; + } + IEnumerable IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr) + { + if (!ShouldRender(self)) + return Enumerable.Empty(); + + return RenderAboveShroud(self, wr); + } + + IEnumerable RenderAboveShroud(Actor self, WorldRenderer wr) + { var pal = wr.Palette(TileSet.TerrainPaletteInternalName); var a = self.CurrentActivity; for (; a != null; a = a.NextActivity) @@ -87,13 +97,7 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IRenderAnnotationsWhenSelected.RenderAnnotations(Actor self, WorldRenderer wr) { - if (!self.Owner.IsAlliedWith(self.World.LocalPlayer) || Game.Settings.Game.TargetLines == TargetLinesType.Disabled) - return Enumerable.Empty(); - - // Players want to see the lines when in waypoint mode. - var force = Game.GetModifierKeys().HasModifier(Modifiers.Shift) || self.World.OrderGenerator is ForceModifiersOrderGenerator; - - if (Game.RunTime > lifetime && !force) + if (!ShouldRender(self)) return Enumerable.Empty(); renderableCache.Clear(); @@ -108,8 +112,8 @@ namespace OpenRA.Mods.Common.Traits { if (n.Target.Type != TargetType.Invalid && n.Tile == null) { - var lineWidth = renderableCache.Any() ? info.QueuedLineWidth : info.LineWidth; - var markerWidth = renderableCache.Any() ? info.QueuedMarkerWidth : info.MarkerWidth; + var lineWidth = renderableCache.Count > 0 ? info.QueuedLineWidth : info.LineWidth; + var markerWidth = renderableCache.Count > 0 ? info.QueuedMarkerWidth : info.MarkerWidth; var pos = n.Target.CenterPosition; renderableCache.Add(new TargetLineRenderable(new[] { prev, pos }, n.Color, lineWidth, markerWidth)); @@ -118,9 +122,12 @@ namespace OpenRA.Mods.Common.Traits } } + if (renderableCache.Count == 0) + return Enumerable.Empty(); + // Reverse draw order so target markers are drawn on top of the next line renderableCache.Reverse(); - return renderableCache; + return renderableCache.ToArray(); } bool IRenderAnnotationsWhenSelected.SpatiallyPartitionable { get { return false; } }