Move BlockedByActor, IPositionableInfo, IPositionable to Mods.Common.
Actor previously cached targetable locations for static actors as an optimization. As we can no longer reference the IPositionable interface, move this optimization to HitShape instead. Although we lose some of the efficiency of caching the final result on the actor, we gain some by allowing HitShape to cache the results as long as they have not changed. So instead of being limited to static actors, we can extend the caching to currently stationary actor.
This commit is contained in:
@@ -74,6 +74,14 @@ namespace OpenRA.Mods.Common.Traits
|
||||
ITargetableCells targetableCells;
|
||||
Turreted turret;
|
||||
|
||||
((CPos Cell, SubCell SubCell)[] targetableCells,
|
||||
WPos? selfCenterPosition,
|
||||
WRot? selfOrientation,
|
||||
WRot? turretLocalOrientation,
|
||||
WVec? turretOffset) cacheInput;
|
||||
|
||||
WPos[] cachedTargetablePositions;
|
||||
|
||||
public HitShape(Actor self, HitShapeInfo info)
|
||||
: base(info)
|
||||
{
|
||||
@@ -88,14 +96,28 @@ namespace OpenRA.Mods.Common.Traits
|
||||
base.Created(self);
|
||||
}
|
||||
|
||||
bool ITargetablePositions.AlwaysEnabled => Info.RequiresCondition == null;
|
||||
|
||||
IEnumerable<WPos> ITargetablePositions.TargetablePositions(Actor self)
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return Enumerable.Empty<WPos>();
|
||||
|
||||
return TargetablePositions(self);
|
||||
// Check for changes in inputs that affect the result of the TargetablePositions method.
|
||||
// If the inputs have not changed we can cache and reuse the result for later calls.
|
||||
// i.e. we are treating the method as a pure function.
|
||||
var newCacheInput = (
|
||||
Info.UseTargetableCellsOffsets ? targetableCells?.TargetableCells() : null,
|
||||
Info.TargetableOffsets.Length > 0 ? self.CenterPosition : (WPos?)null,
|
||||
Info.TargetableOffsets.Length > 0 ? self.Orientation : (WRot?)null,
|
||||
Info.TargetableOffsets.Length > 0 ? turret?.LocalOrientation : null,
|
||||
Info.TargetableOffsets.Length > 0 ? turret?.Offset : null);
|
||||
if (cachedTargetablePositions == null ||
|
||||
cacheInput != newCacheInput)
|
||||
{
|
||||
cachedTargetablePositions = TargetablePositions(self).ToArray();
|
||||
cacheInput = newCacheInput;
|
||||
}
|
||||
|
||||
return cachedTargetablePositions;
|
||||
}
|
||||
|
||||
IEnumerable<WPos> TargetablePositions(Actor self)
|
||||
|
||||
Reference in New Issue
Block a user