Minor changes to reduce allocation.

- Cache a predicate in ActorMap.
- Use short circuiting to skip a call to HasTrait in AttackBase.
- In AutoTarget.ScanForTarget, move the check for the scan time above the calculations since we can skip them if it's not time yet.
- In AutoTarget.ChooseTarget, merge four Where calls into one.
This commit is contained in:
RoosterDragon
2014-06-12 04:04:39 +01:00
parent e0c59511fb
commit b8b8b1e2df
3 changed files with 16 additions and 9 deletions

View File

@@ -51,6 +51,7 @@ namespace OpenRA.Traits
// to ensure consistency during a tick // to ensure consistency during a tick
readonly List<Actor> addActorPosition = new List<Actor>(); readonly List<Actor> addActorPosition = new List<Actor>();
readonly HashSet<Actor> removeActorPosition = new HashSet<Actor>(); readonly HashSet<Actor> removeActorPosition = new HashSet<Actor>();
readonly Predicate<Actor> actorShouldBeRemoved;
public ActorMap(World world, ActorMapInfo info) public ActorMap(World world, ActorMapInfo info)
{ {
@@ -64,6 +65,9 @@ namespace OpenRA.Traits
for (var j = 0; j < rows; j++) for (var j = 0; j < rows; j++)
for (var i = 0; i < cols; i++) for (var i = 0; i < cols; i++)
actors[j * cols + i] = new List<Actor>(); actors[j * cols + i] = new List<Actor>();
// Cache this delegate so it does not have to be allocated repeatedly.
actorShouldBeRemoved = removeActorPosition.Contains;
} }
public IEnumerable<Actor> GetUnitsAt(CPos a) public IEnumerable<Actor> GetUnitsAt(CPos a)
@@ -144,7 +148,7 @@ namespace OpenRA.Traits
// Position updates are done in one pass // Position updates are done in one pass
// to ensure consistency during a tick // to ensure consistency during a tick
foreach (var bin in actors) foreach (var bin in actors)
bin.RemoveAll(removeActorPosition.Contains); bin.RemoveAll(actorShouldBeRemoved);
removeActorPosition.Clear(); removeActorPosition.Clear();

View File

@@ -157,7 +157,7 @@ namespace OpenRA.Mods.RA
public bool IsReachableTarget(Target target, bool allowMove) public bool IsReachableTarget(Target target, bool allowMove)
{ {
return HasAnyValidWeapons(target) return HasAnyValidWeapons(target)
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (self.HasTrait<IMove>() && allowMove)); && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.HasTrait<IMove>()));
} }
class AttackOrderTargeter : IOrderTargeter class AttackOrderTargeter : IOrderTargeter

View File

@@ -118,11 +118,13 @@ namespace OpenRA.Mods.RA
} }
public Actor ScanForTarget(Actor self, Actor currentTarget) public Actor ScanForTarget(Actor self, Actor currentTarget)
{
if (nextScanTime <= 0)
{ {
var range = info.ScanRadius > 0 ? WRange.FromCells(info.ScanRadius) : attack.GetMaximumRange(); var range = info.ScanRadius > 0 ? WRange.FromCells(info.ScanRadius) : attack.GetMaximumRange();
if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range))
if (nextScanTime <= 0)
return ChooseTarget(self, range); return ChooseTarget(self, range);
}
return currentTarget; return currentTarget;
} }
@@ -148,10 +150,11 @@ namespace OpenRA.Mods.RA
var inRange = self.World.FindActorsInCircle(self.CenterPosition, range); var inRange = self.World.FindActorsInCircle(self.CenterPosition, range);
return inRange return inRange
.Where(a => a.AppearsHostileTo(self)) .Where(a =>
.Where(a => !a.HasTrait<AutoTargetIgnore>()) a.AppearsHostileTo(self) &&
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) !a.HasTrait<AutoTargetIgnore>() &&
.Where(a => self.Owner.Shroud.IsTargetable(a)) attack.HasAnyValidWeapons(Target.FromActor(a)) &&
self.Owner.Shroud.IsTargetable(a))
.ClosestTo(self); .ClosestTo(self);
} }
} }