Cache TargetablePositions in Actor
To speed up Target.Positions.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user