Tackle the last of the low hanging fruit for memory allocations in the main game loop.

- Avoid calling string.Split twice in SprintFont.Measure.
- Change ActorsInBox method of ActorMap and ScreenMap to avoid allocating and intermediate list. As a bonus this allows the sequence to be lazily consumed. Also avoid LINQ in these methods.
- In FrozenUnderFog.TickRender, the method exits early if no players are visible so the attempt at lazy generation was not needed.
- Unwrap a LINQ Any call in ClassicProductionQueue.Tick.
- Merge some successive Where calls in ProximityCapturable into single predicates.
This commit is contained in:
RoosterDragon
2014-06-21 01:31:19 +01:00
parent a5d765e100
commit 8a60880cf1
6 changed files with 33 additions and 38 deletions

View File

@@ -111,18 +111,13 @@ namespace OpenRA.Mods.RA
public void TickRender(WorldRenderer wr, Actor self)
{
if (self.Destroyed || !initialized || !visible.Any(v => v.Value))
if (self.Destroyed || !initialized || !visible.Values.Any(v => v))
return;
IRenderable[] renderables = null;
var renderables = self.Render(wr).ToArray();
foreach (var player in self.World.Players)
if (visible[player])
{
// Lazily generate a copy of the underlying data.
if (renderables == null)
renderables = self.Render(wr).ToArray();
frozen[player].Renderables = renderables;
}
}
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)

View File

@@ -45,10 +45,13 @@ namespace OpenRA.Mods.RA
public override void Tick(Actor self)
{
isActive = self.World.ActorsWithTrait<Production>()
.Any(x => x.Actor.Owner == self.Owner
&& x.Trait.Info.Produces.Contains(Info.Type));
isActive = false;
foreach (var x in self.World.ActorsWithTrait<Production>())
if (x.Actor.Owner == self.Owner && x.Trait.Info.Produces.Contains(Info.Type))
{
isActive = true;
break;
}
base.Tick(self);
}

View File

@@ -110,32 +110,26 @@ namespace OpenRA.Mods.RA
IEnumerable<Actor> UnitsInRange()
{
return Self.World.FindActorsInCircle(Self.CenterPosition, WRange.FromCells(Info.Range))
.Where(a => a.IsInWorld && a != Self && !a.Destroyed)
.Where(a => !a.Owner.NonCombatant);
.Where(a => a.IsInWorld && a != Self && !a.Destroyed && !a.Owner.NonCombatant);
}
bool IsClear(Actor self, Player currentOwner, Player originalOwner)
{
return UnitsInRange().Where(a => a.Owner != originalOwner)
.Where(a => a.Owner != currentOwner)
.Where(a => CanBeCapturedBy(a))
.All(a => WorldUtils.AreMutualAllies(a.Owner, currentOwner));
return UnitsInRange()
.All(a => a.Owner == originalOwner || a.Owner == currentOwner ||
WorldUtils.AreMutualAllies(a.Owner, currentOwner) || !CanBeCapturedBy(a));
}
// TODO exclude other NeutralActor that arent permanent
bool IsStillInRange(Actor self)
{
return UnitsInRange()
.Where(a => a.Owner == self.Owner)
.Where(a => CanBeCapturedBy(a))
.Any();
return UnitsInRange().Any(a => a.Owner == self.Owner && CanBeCapturedBy(a));
}
IEnumerable<Actor> CaptorsInRange(Actor self)
{
return UnitsInRange()
.Where(a => a.Owner != OriginalOwner)
.Where(a => CanBeCapturedBy(a));
.Where(a => a.Owner != OriginalOwner && CanBeCapturedBy(a));
}
// TODO exclude other NeutralActor that arent permanent
@@ -146,8 +140,8 @@ namespace OpenRA.Mods.RA
int CountPlayersNear(Actor self, Player ignoreMe)
{
return CaptorsInRange(self).Select(a => a.Owner)
.Distinct().Count(p => p != ignoreMe);
return CaptorsInRange(self).Select(a => a.Owner).Where(p => p != ignoreMe)
.Distinct().Count();
}
}
}