Merge pull request #7746 from RoosterDragon/shroud-vis-perf

Speed up frozen actor visibility updates.
This commit is contained in:
Matthias Mailänder
2015-04-03 15:20:10 +02:00

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
@@ -24,10 +25,10 @@ namespace OpenRA.Traits
public class FrozenActor public class FrozenActor
{ {
public readonly MPos[] Footprint; public readonly MPos[] Footprint;
public readonly CellRegion FootprintRegion;
public readonly WPos CenterPosition; public readonly WPos CenterPosition;
public readonly Rectangle Bounds; public readonly Rectangle Bounds;
readonly Actor actor; readonly Actor actor;
readonly Func<MPos, bool> isVisibleTest;
public Player Owner; public Player Owner;
@@ -44,13 +45,13 @@ namespace OpenRA.Traits
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud) public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud)
{ {
actor = self; actor = self;
Footprint = footprint; isVisibleTest = shroud.IsVisibleTest(footprintRegion);
FootprintRegion = footprintRegion;
Footprint = footprint;
CenterPosition = self.CenterPosition; CenterPosition = self.CenterPosition;
Bounds = self.Bounds; Bounds = self.Bounds;
UpdateVisibility(shroud); UpdateVisibility();
} }
public uint ID { get { return actor.ActorID; } } public uint ID { get { return actor.ActorID; } }
@@ -64,21 +65,20 @@ namespace OpenRA.Traits
IRenderable[] renderables = NoRenderables; IRenderable[] renderables = NoRenderables;
bool needRenderables; bool needRenderables;
public void Tick(Shroud shroud) public void Tick()
{ {
UpdateVisibility(shroud); UpdateVisibility();
if (flashTicks > 0) if (flashTicks > 0)
flashTicks--; flashTicks--;
} }
void UpdateVisibility(Shroud shroud) void UpdateVisibility()
{ {
var wasVisible = Visible; var wasVisible = Visible;
// We are doing the following LINQ manually to avoid allocating an extra delegate since this is a hot path. // We are doing the following LINQ manually for performance since this is a hot path.
// Visible = !Footprint.Any(shroud.IsVisibleTest(FootprintRegion)); // Visible = !Footprint.Any(isVisibleTest);
var isVisibleTest = shroud.IsVisibleTest(FootprintRegion);
Visible = true; Visible = true;
foreach (var uv in Footprint) foreach (var uv in Footprint)
if (isVisibleTest(uv)) if (isVisibleTest(uv))
@@ -161,7 +161,7 @@ namespace OpenRA.Traits
FrozenHash += hash; FrozenHash += hash;
var frozenActor = kvp.Value; var frozenActor = kvp.Value;
frozenActor.Tick(self.Owner.Shroud); frozenActor.Tick();
if (frozenActor.Visible) if (frozenActor.Visible)
VisibilityHash += hash; VisibilityHash += hash;