Cache TargetablePositions in Actor
To speed up Target.Positions.
This commit is contained in:
@@ -77,6 +77,8 @@ namespace OpenRA
|
|||||||
readonly IMouseBounds[] mouseBounds;
|
readonly IMouseBounds[] mouseBounds;
|
||||||
readonly IVisibilityModifier[] visibilityModifiers;
|
readonly IVisibilityModifier[] visibilityModifiers;
|
||||||
readonly IDefaultVisibility defaultVisibility;
|
readonly IDefaultVisibility defaultVisibility;
|
||||||
|
readonly ITargetablePositions[] targetablePositions;
|
||||||
|
WPos[] staticTargetablePositions;
|
||||||
|
|
||||||
internal Actor(World world, string name, TypeDictionary initDict)
|
internal Actor(World world, string name, TypeDictionary initDict)
|
||||||
{
|
{
|
||||||
@@ -118,6 +120,15 @@ namespace OpenRA
|
|||||||
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
|
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
|
||||||
defaultVisibility = Trait<IDefaultVisibility>();
|
defaultVisibility = Trait<IDefaultVisibility>();
|
||||||
Targetables = TraitsImplementing<ITargetable>().ToArray();
|
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();
|
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
|
||||||
}
|
}
|
||||||
@@ -368,6 +379,18 @@ namespace OpenRA
|
|||||||
return false;
|
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
|
#region Scripting interface
|
||||||
|
|
||||||
Lazy<ScriptActorInterface> luaInterface;
|
Lazy<ScriptActorInterface> luaInterface;
|
||||||
|
|||||||
@@ -157,14 +157,7 @@ namespace OpenRA.Traits
|
|||||||
if (!actor.Targetables.Any(Exts.IsTraitEnabled))
|
if (!actor.Targetables.Any(Exts.IsTraitEnabled))
|
||||||
return new[] { actor.CenterPosition };
|
return new[] { actor.CenterPosition };
|
||||||
|
|
||||||
var targetablePositions = actor.TraitsImplementing<ITargetablePositions>().Where(Exts.IsTraitEnabled);
|
return actor.GetTargetablePositions();
|
||||||
if (targetablePositions.Any())
|
|
||||||
{
|
|
||||||
var target = this;
|
|
||||||
return targetablePositions.SelectMany(tp => tp.TargetablePositions(target.actor));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new[] { actor.CenterPosition };
|
|
||||||
case TargetType.FrozenActor:
|
case TargetType.FrozenActor:
|
||||||
return new[] { frozen.CenterPosition };
|
return new[] { frozen.CenterPosition };
|
||||||
case TargetType.Terrain:
|
case TargetType.Terrain:
|
||||||
|
|||||||
@@ -387,8 +387,11 @@ namespace OpenRA.Traits
|
|||||||
public interface ITargetablePositions
|
public interface ITargetablePositions
|
||||||
{
|
{
|
||||||
IEnumerable<WPos> TargetablePositions(Actor self);
|
IEnumerable<WPos> TargetablePositions(Actor self);
|
||||||
|
bool AlwaysEnabled { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IMoveInfo : ITraitInfoInterface { }
|
||||||
|
|
||||||
[RequireExplicitImplementation]
|
[RequireExplicitImplementation]
|
||||||
public interface IGameOver { void GameOver(World world); }
|
public interface IGameOver { void GameOver(World world); }
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
base.Created(self);
|
base.Created(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ITargetablePositions.AlwaysEnabled { get { return Info.RequiresCondition == null; } }
|
||||||
|
|
||||||
IEnumerable<WPos> ITargetablePositions.TargetablePositions(Actor self)
|
IEnumerable<WPos> ITargetablePositions.TargetablePositions(Actor self)
|
||||||
{
|
{
|
||||||
if (IsTraitDisabled)
|
if (IsTraitDisabled)
|
||||||
|
|||||||
@@ -334,8 +334,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
IEnumerable<object> ActorPreviewInits(ActorInfo ai, ActorPreviewType type);
|
IEnumerable<object> ActorPreviewInits(ActorInfo ai, ActorPreviewType type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IMoveInfo : ITraitInfoInterface { }
|
|
||||||
|
|
||||||
public interface IMove
|
public interface IMove
|
||||||
{
|
{
|
||||||
Activity MoveTo(CPos cell, int nearEnough);
|
Activity MoveTo(CPos cell, int nearEnough);
|
||||||
|
|||||||
Reference in New Issue
Block a user