Properly clean up traits that used to hook only death.

This commit is contained in:
Paul Chote
2015-05-23 22:09:50 +01:00
parent 4ff309811f
commit 8ae3afa3c5
9 changed files with 47 additions and 12 deletions

View File

@@ -225,6 +225,9 @@ namespace OpenRA
if (IsInWorld) if (IsInWorld)
World.Remove(this); World.Remove(this);
foreach (var t in TraitsImplementing<INotifyActorDisposing>())
t.Disposing(this);
World.TraitDict.RemoveActor(this); World.TraitDict.RemoveActor(this);
Disposed = true; Disposed = true;

View File

@@ -94,6 +94,7 @@ namespace OpenRA.Traits
public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); } public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); }
public interface INotifyRepair { void Repairing(Actor self, Actor host); } public interface INotifyRepair { void Repairing(Actor self, Actor host); }
public interface INotifyKilled { void Killed(Actor self, AttackInfo e); } public interface INotifyKilled { void Killed(Actor self, AttackInfo e); }
public interface INotifyActorDisposing { void Disposing(Actor self); }
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); } public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
public interface INotifyBuildComplete { void BuildingComplete(Actor self); } public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
public interface INotifyBuildingPlaced { void BuildingPlaced(Actor self); } public interface INotifyBuildingPlaced { void BuildingPlaced(Actor self); }

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
bool IOccupySpaceInfo.SharesCell { get { return false; } } bool IOccupySpaceInfo.SharesCell { get { return false; } }
} }
public class Aircraft : IFacing, IPositionable, ISync, INotifyKilled, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld public class Aircraft : IFacing, IPositionable, ISync, IIssueOrder, IOrderVoice, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing
{ {
static readonly Pair<CPos, SubCell>[] NoCells = { }; static readonly Pair<CPos, SubCell>[] NoCells = { };
@@ -157,7 +157,7 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public void Killed(Actor self, AttackInfo e) public void Disposing(Actor self)
{ {
UnReserve(); UnReserve();
} }

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Activities; using OpenRA.Activities;
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
public virtual object Create(ActorInitializer init) { return new Refinery(init.Self, this); } public virtual object Create(ActorInitializer init) { return new Refinery(init.Self, this); }
} }
public class Refinery : ITick, IAcceptResources, INotifyKilled, INotifySold, INotifyCapture, INotifyOwnerChanged, IExplodeModifier, ISync public class Refinery : ITick, IAcceptResources, INotifySold, INotifyCapture, INotifyOwnerChanged, IExplodeModifier, ISync, INotifyActorDisposing
{ {
readonly Actor self; readonly Actor self;
readonly RefineryInfo info; readonly RefineryInfo info;
@@ -118,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public void Killed(Actor self, AttackInfo e) public void Disposing(Actor self)
{ {
CancelDock(self); CancelDock(self);
foreach (var harv in GetLinkedHarvesters()) foreach (var harv in GetLinkedHarvesters())

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Reserve landing places for aircraft.")] [Desc("Reserve landing places for aircraft.")]
class ReservableInfo : TraitInfo<Reservable> { } class ReservableInfo : TraitInfo<Reservable> { }
public class Reservable : ITick, INotifyKilled, INotifyOwnerChanged, INotifySold public class Reservable : ITick, INotifyOwnerChanged, INotifySold, INotifyActorDisposing
{ {
Actor reservedFor; Actor reservedFor;
Aircraft reservedForAircraft; Aircraft reservedForAircraft;
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits
return res != null && res.reservedFor != null; return res != null && res.reservedFor != null;
} }
public void Killed(Actor self, AttackInfo e) public void Disposing(Actor self)
{ {
if (reservedForAircraft != null) if (reservedForAircraft != null)
reservedForAircraft.UnReserve(); reservedForAircraft.UnReserve();

View File

@@ -54,7 +54,8 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new Cargo(init, this); } public object Create(ActorInitializer init) { return new Cargo(init, this); }
} }
public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyCreated, INotifyKilled, INotifyOwnerChanged, INotifyAddedToWorld, ITick, INotifySold, IDisableMove public class Cargo : IPips, IIssueOrder, IResolveOrder, IOrderVoice, INotifyCreated, INotifyKilled,
INotifyOwnerChanged, INotifyAddedToWorld, ITick, INotifySold, IDisableMove, INotifyActorDisposing
{ {
public readonly CargoInfo Info; public readonly CargoInfo Info;
readonly Actor self; readonly Actor self;
@@ -305,6 +306,14 @@ namespace OpenRA.Mods.Common.Traits
cargo.Clear(); cargo.Clear();
} }
public void Disposing(Actor self)
{
foreach (var c in cargo)
c.Dispose();
cargo.Clear();
}
public void Selling(Actor self) { } public void Selling(Actor self) { }
public void Sold(Actor self) public void Sold(Actor self)
{ {

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Traits; using OpenRA.Traits;
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new StoresResources(init.Self, this); } public object Create(ActorInitializer init) { return new StoresResources(init.Self, this); }
} }
class StoresResources : IPips, INotifyOwnerChanged, INotifyCapture, INotifyKilled, IExplodeModifier, IStoreResources, ISync class StoresResources : IPips, INotifyOwnerChanged, INotifyCapture, IExplodeModifier, IStoreResources, ISync, INotifyActorDisposing
{ {
readonly StoresResourcesInfo info; readonly StoresResourcesInfo info;
@@ -51,9 +52,14 @@ namespace OpenRA.Mods.Common.Traits
newOwner.PlayerActor.Trait<PlayerResources>().GiveResources(resources); newOwner.PlayerActor.Trait<PlayerResources>().GiveResources(resources);
} }
public void Killed(Actor self, AttackInfo e) bool disposed;
public void Disposing(Actor self)
{ {
if (disposed)
return;
player.TakeResources(Stored); // lose the stored resources player.TakeResources(Stored); // lose the stored resources
disposed = true;
} }
public IEnumerable<PipType> GetPips(Actor self) public IEnumerable<PipType> GetPips(Actor self)

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
@@ -27,7 +28,7 @@ namespace OpenRA.Mods.D2k.Traits
public object Create(ActorInitializer init) { return new Carryall(init.Self, this); } public object Create(ActorInitializer init) { return new Carryall(init.Self, this); }
} }
public class Carryall : INotifyBecomingIdle, INotifyKilled, ISync, IRender public class Carryall : INotifyBecomingIdle, INotifyKilled, ISync, IRender, INotifyActorDisposing
{ {
readonly Actor self; readonly Actor self;
readonly WRange carryHeight; readonly WRange carryHeight;
@@ -166,6 +167,15 @@ namespace OpenRA.Mods.D2k.Traits
UnreserveCarryable(); UnreserveCarryable();
} }
public void Disposing(Actor self)
{
if (Carrying != null && IsCarrying)
{
Carrying.Dispose();
Carrying = null;
}
}
// Called when carryable is inside. // Called when carryable is inside.
public void AttachCarryable(Actor carryable) public void AttachCarryable(Actor carryable)
{ {

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.D2k.Traits
public override object Create(ActorInitializer init) { return new Sandworm(init.Self, this); } public override object Create(ActorInitializer init) { return new Sandworm(init.Self, this); }
} }
class Sandworm : Wanders, ITick, INotifyKilled class Sandworm : Wanders, ITick, INotifyActorDisposing
{ {
public readonly SandwormInfo Info; public readonly SandwormInfo Info;
@@ -151,9 +151,14 @@ namespace OpenRA.Mods.D2k.Traits
IsMovingTowardTarget = true; IsMovingTowardTarget = true;
} }
public void Killed(Actor self, AttackInfo e) bool disposed;
public void Disposing(Actor self)
{ {
if (disposed)
return;
manager.DecreaseWormCount(); manager.DecreaseWormCount();
disposed = true;
} }
} }
} }