Cache TargetablePositions in Actor

To speed up Target.Positions.
This commit is contained in:
reaperrr
2018-03-14 01:48:24 +01:00
committed by Paul Chote
parent 4c16e51f92
commit 0c52ff3ae5
5 changed files with 29 additions and 10 deletions

View File

@@ -77,6 +77,8 @@ namespace OpenRA
readonly IMouseBounds[] mouseBounds;
readonly IVisibilityModifier[] visibilityModifiers;
readonly IDefaultVisibility defaultVisibility;
readonly ITargetablePositions[] targetablePositions;
WPos[] staticTargetablePositions;
internal Actor(World world, string name, TypeDictionary initDict)
{
@@ -118,6 +120,15 @@ namespace OpenRA
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
defaultVisibility = Trait<IDefaultVisibility>();
Targetables = TraitsImplementing<ITargetable>().ToArray();
targetablePositions = TraitsImplementing<ITargetablePositions>().ToArray();
world.AddFrameEndTask(w =>
{
// Caching this in a AddFrameEndTask, because trait construction order might cause problems if done directly at creation time.
// All actors that can move should have IMove, if not it's pretty safe to assume the actor is immobile and
// all targetable positions can be cached if all ITargetablePositions have no conditional requirements.
if (!Info.HasTraitInfo<IMoveInfo>() && targetablePositions.All(tp => tp.AlwaysEnabled))
staticTargetablePositions = targetablePositions.SelectMany(tp => tp.TargetablePositions(this)).ToArray();
});
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
}
@@ -368,6 +379,18 @@ namespace OpenRA
return false;
}
public IEnumerable<WPos> GetTargetablePositions()
{
if (staticTargetablePositions != null)
return staticTargetablePositions;
var enabledTargetablePositionTraits = targetablePositions.Where(Exts.IsTraitEnabled);
if (enabledTargetablePositionTraits.Any())
return enabledTargetablePositionTraits.SelectMany(tp => tp.TargetablePositions(this));
return new[] { this.CenterPosition };
}
#region Scripting interface
Lazy<ScriptActorInterface> luaInterface;

View File

@@ -157,14 +157,7 @@ namespace OpenRA.Traits
if (!actor.Targetables.Any(Exts.IsTraitEnabled))
return new[] { actor.CenterPosition };
var targetablePositions = actor.TraitsImplementing<ITargetablePositions>().Where(Exts.IsTraitEnabled);
if (targetablePositions.Any())
{
var target = this;
return targetablePositions.SelectMany(tp => tp.TargetablePositions(target.actor));
}
return new[] { actor.CenterPosition };
return actor.GetTargetablePositions();
case TargetType.FrozenActor:
return new[] { frozen.CenterPosition };
case TargetType.Terrain:

View File

@@ -387,8 +387,11 @@ namespace OpenRA.Traits
public interface ITargetablePositions
{
IEnumerable<WPos> TargetablePositions(Actor self);
bool AlwaysEnabled { get; }
}
public interface IMoveInfo : ITraitInfoInterface { }
[RequireExplicitImplementation]
public interface IGameOver { void GameOver(World world); }