Merge pull request #9313 from RoosterDragon/actor-eager

Eagerly cache traits in Actor
This commit is contained in:
Matthias Mailänder
2015-09-26 13:18:05 +02:00

View File

@@ -40,34 +40,38 @@ namespace OpenRA
public Group Group; public Group Group;
public int Generation; public int Generation;
Lazy<Rectangle> bounds; public Rectangle Bounds { get; private set; }
Lazy<Rectangle> visualBounds; public Rectangle VisualBounds { get; private set; }
Lazy<IFacing> facing; public IEffectiveOwner EffectiveOwner { get; private set; }
Lazy<Health> health; public IOccupySpace OccupiesSpace
Lazy<IOccupySpace> occupySpace; {
Lazy<IEffectiveOwner> effectiveOwner; get
{
public Rectangle Bounds { get { return bounds.Value; } } if (occupySpace == null)
public Rectangle VisualBounds { get { return visualBounds.Value; } } occupySpace = Trait<IOccupySpace>();
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } } return occupySpace;
public IEffectiveOwner EffectiveOwner { get { return effectiveOwner.Value; } } }
}
public bool IsIdle { get { return currentActivity == null; } } public bool IsIdle { get { return currentActivity == null; } }
public bool IsDead { get { return Disposed || (health.Value == null ? false : health.Value.IsDead); } } public bool IsDead { get { return Disposed || (health != null && health.IsDead); } }
public CPos Location { get { return occupySpace.Value.TopLeft; } } public CPos Location { get { return OccupiesSpace.TopLeft; } }
public WPos CenterPosition { get { return occupySpace.Value.CenterPosition; } } public WPos CenterPosition { get { return OccupiesSpace.CenterPosition; } }
public WRot Orientation public WRot Orientation
{ {
get get
{ {
// TODO: Support non-zero pitch/roll in IFacing (IOrientation?) // TODO: Support non-zero pitch/roll in IFacing (IOrientation?)
var facingValue = facing.Value != null ? facing.Value.Facing : 0; var facingValue = facing != null ? facing.Facing : 0;
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facingValue)); return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facingValue));
} }
} }
IOccupySpace occupySpace;
readonly IFacing facing;
readonly Health health;
readonly IRenderModifier[] renderModifiers; readonly IRenderModifier[] renderModifiers;
readonly IRender[] renders; readonly IRender[] renders;
readonly IDisable[] disables; readonly IDisable[] disables;
@@ -83,8 +87,6 @@ namespace OpenRA
if (initDict.Contains<OwnerInit>()) if (initDict.Contains<OwnerInit>())
Owner = init.Get<OwnerInit, Player>(); Owner = init.Get<OwnerInit, Player>();
occupySpace = Exts.Lazy(() => TraitOrDefault<IOccupySpace>());
if (name != null) if (name != null)
{ {
name = name.ToLowerInvariant(); name = name.ToLowerInvariant();
@@ -97,11 +99,19 @@ namespace OpenRA
AddTrait(trait.Create(init)); AddTrait(trait.Create(init));
} }
facing = Exts.Lazy(() => TraitOrDefault<IFacing>()); Bounds = DetermineBounds();
health = Exts.Lazy(() => TraitOrDefault<Health>()); VisualBounds = DetermineVisualBounds();
effectiveOwner = Exts.Lazy(() => TraitOrDefault<IEffectiveOwner>()); EffectiveOwner = TraitOrDefault<IEffectiveOwner>();
facing = TraitOrDefault<IFacing>();
health = TraitOrDefault<Health>();
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
renders = TraitsImplementing<IRender>().ToArray();
disables = TraitsImplementing<IDisable>().ToArray();
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
defaultVisibility = Trait<IDefaultVisibility>();
}
bounds = Exts.Lazy(() => Rectangle DetermineBounds()
{ {
var si = Info.TraitInfoOrDefault<SelectableInfo>(); var si = Info.TraitInfoOrDefault<SelectableInfo>();
var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) : var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
@@ -112,13 +122,13 @@ namespace OpenRA
offset += new int2(si.Bounds[2], si.Bounds[3]); offset += new int2(si.Bounds[2], si.Bounds[3]);
return new Rectangle(offset.X, offset.Y, size.X, size.Y); return new Rectangle(offset.X, offset.Y, size.X, size.Y);
}); }
visualBounds = Exts.Lazy(() => Rectangle DetermineVisualBounds()
{ {
var sd = Info.TraitInfoOrDefault<ISelectionDecorationsInfo>(); var sd = Info.TraitInfoOrDefault<ISelectionDecorationsInfo>();
if (sd == null || sd.SelectionBoxBounds == null) if (sd == null || sd.SelectionBoxBounds == null)
return bounds.Value; return Bounds;
var size = new int2(sd.SelectionBoxBounds[0], sd.SelectionBoxBounds[1]); var size = new int2(sd.SelectionBoxBounds[0], sd.SelectionBoxBounds[1]);
@@ -127,13 +137,6 @@ namespace OpenRA
offset += new int2(sd.SelectionBoxBounds[2], sd.SelectionBoxBounds[3]); offset += new int2(sd.SelectionBoxBounds[2], sd.SelectionBoxBounds[3]);
return new Rectangle(offset.X, offset.Y, size.X, size.Y); return new Rectangle(offset.X, offset.Y, size.X, size.Y);
});
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
renders = TraitsImplementing<IRender>().ToArray();
disables = TraitsImplementing<IDisable>().ToArray();
visibilityModifiers = TraitsImplementing<IVisibilityModifier>().ToArray();
defaultVisibility = Trait<IDefaultVisibility>();
} }
public void Tick() public void Tick()
@@ -280,10 +283,10 @@ namespace OpenRA
public void Kill(Actor attacker) public void Kill(Actor attacker)
{ {
if (health.Value == null) if (health == null)
return; return;
health.Value.InflictDamage(this, attacker, health.Value.MaxHP, null, true); health.InflictDamage(this, attacker, health.MaxHP, null, true);
} }
public bool IsDisabled() public bool IsDisabled()