Speed up Player.CanViewActor.

Create Actor.CanBeViewedByPlayer and simply call this instead. The actor can cache all trait lookups on construction to avoid them being repeated for every visibility check.
This commit is contained in:
RoosterDragon
2015-09-06 21:35:20 +01:00
parent aae3c8ef7d
commit d1960258db
2 changed files with 15 additions and 8 deletions

View File

@@ -71,6 +71,8 @@ namespace OpenRA
readonly IRenderModifier[] renderModifiers;
readonly IRender[] renders;
readonly IDisable[] disables;
readonly IVisibilityModifier[] visibilityModifiers;
readonly IDefaultVisibility defaultVisibility;
internal Actor(World world, string name, TypeDictionary initDict)
{
@@ -130,6 +132,8 @@ namespace OpenRA
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
renders = TraitsImplementing<IRender>().ToArray();
disables = TraitsImplementing<IDisable>().ToArray();
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
defaultVisibility = Trait<IDefaultVisibility>();
}
public void Tick()
@@ -295,6 +299,15 @@ namespace OpenRA
return false;
}
public bool CanBeViewedByPlayer(Player player)
{
foreach (var visibilityModifier in visibilityModifiers)
if (!visibilityModifier.IsVisible(this, player))
return false;
return defaultVisibility.IsVisible(this, player);
}
#region Scripting interface
Lazy<ScriptActorInterface> luaInterface;

View File

@@ -154,10 +154,7 @@ namespace OpenRA
public bool CanViewActor(Actor a)
{
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
return a.CanBeViewedByPlayer(this);
}
public bool CanTargetActor(Actor a)
@@ -165,10 +162,7 @@ namespace OpenRA
if (HasFogVisibility)
return true;
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
return CanViewActor(a);
}
public bool HasFogVisibility { get { return fogVisibilities.Any(f => f.HasFogVisibility(this)); } }