Merge pull request #9262 from RoosterDragon/frozen-unify-dict

Speed up FrozenUnderFog.Tick
This commit is contained in:
Oliver Brakmann
2015-09-26 20:45:58 +02:00
2 changed files with 27 additions and 15 deletions

View File

@@ -41,13 +41,14 @@ namespace OpenRA.Traits
public DamageState DamageState; public DamageState DamageState;
public bool Visible = true; public bool Visible = true;
public bool NeedRenderables; public bool NeedRenderables { get; private set; }
public bool IsRendering { get; private set; } public bool IsRendering { get; private set; }
public FrozenActor(Actor self, PPos[] footprint, Shroud shroud) public FrozenActor(Actor self, PPos[] footprint, Shroud shroud, bool startsRevealed)
{ {
actor = self; actor = self;
this.shroud = shroud; this.shroud = shroud;
NeedRenderables = startsRevealed;
removeFrozenActors = self.TraitsImplementing<IRemoveFrozenActor>().ToArray(); removeFrozenActors = self.TraitsImplementing<IRemoveFrozenActor>().ToArray();
// Consider all cells inside the map area (ignoring the current map bounds) // Consider all cells inside the map area (ignoring the current map bounds)

View File

@@ -38,11 +38,20 @@ namespace OpenRA.Mods.Common.Traits
readonly Lazy<ITooltip> tooltip; readonly Lazy<ITooltip> tooltip;
readonly Lazy<Health> health; readonly Lazy<Health> health;
readonly Dictionary<Player, bool> visible; readonly Dictionary<Player, FrozenState> stateByPlayer = new Dictionary<Player, FrozenState>();
readonly Dictionary<Player, FrozenActor> frozen;
bool initialized; bool initialized;
class FrozenState
{
public readonly FrozenActor FrozenActor;
public bool IsVisible;
public FrozenState(FrozenActor frozenActor)
{
FrozenActor = frozenActor;
}
}
public FrozenUnderFog(ActorInitializer init, FrozenUnderFogInfo info) public FrozenUnderFog(ActorInitializer init, FrozenUnderFogInfo info)
{ {
this.info = info; this.info = info;
@@ -55,9 +64,6 @@ namespace OpenRA.Mods.Common.Traits
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray(); footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<ITooltip>().FirstOrDefault()); tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<ITooltip>().FirstOrDefault());
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>()); health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
frozen = new Dictionary<Player, FrozenActor>();
visible = init.World.Players.ToDictionary(p => p, p => false);
} }
bool IsVisibleInner(Actor self, Player byPlayer) bool IsVisibleInner(Actor self, Player byPlayer)
@@ -67,7 +73,7 @@ namespace OpenRA.Mods.Common.Traits
return self.OccupiesSpace.OccupiedCells() return self.OccupiesSpace.OccupiedCells()
.Any(o => byPlayer.Shroud.IsExplored(o.First)); .Any(o => byPlayer.Shroud.IsExplored(o.First));
return visible[byPlayer]; return initialized && stateByPlayer[byPlayer].IsVisible;
} }
public bool IsVisible(Actor self, Player byPlayer) public bool IsVisible(Actor self, Player byPlayer)
@@ -87,19 +93,21 @@ namespace OpenRA.Mods.Common.Traits
VisibilityHash = 0; VisibilityHash = 0;
foreach (var player in self.World.Players) foreach (var player in self.World.Players)
{ {
bool isVisible;
FrozenActor frozenActor; FrozenActor frozenActor;
bool isVisible;
if (!initialized) if (!initialized)
{ {
frozen[player] = frozenActor = new FrozenActor(self, footprint, player.Shroud); frozenActor = new FrozenActor(self, footprint, player.Shroud, startsRevealed);
frozen[player].NeedRenderables = frozenActor.NeedRenderables = startsRevealed; isVisible = startsRevealed;
stateByPlayer.Add(player, new FrozenState(frozenActor) { IsVisible = isVisible });
player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor); player.PlayerActor.Trait<FrozenActorLayer>().Add(frozenActor);
isVisible = visible[player] |= startsRevealed;
} }
else else
{ {
frozenActor = frozen[player]; var state = stateByPlayer[player];
isVisible = visible[player] = !frozenActor.Visible; frozenActor = state.FrozenActor;
isVisible = !frozenActor.Visible;
state.IsVisible = isVisible;
} }
if (isVisible) if (isVisible)
@@ -127,7 +135,10 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r) public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
{ {
return IsVisible(self, self.World.RenderPlayer) || (initialized && frozen[self.World.RenderPlayer].IsRendering) ? r : SpriteRenderable.None; return
IsVisible(self, self.World.RenderPlayer) ||
(initialized && stateByPlayer[self.World.RenderPlayer].FrozenActor.IsRendering) ?
r : SpriteRenderable.None;
} }
} }
} }