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)
World.Remove(this);
foreach (var t in TraitsImplementing<INotifyActorDisposing>())
t.Disposing(this);
World.TraitDict.RemoveActor(this);
Disposed = true;

View File

@@ -94,6 +94,7 @@ namespace OpenRA.Traits
public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); }
public interface INotifyRepair { void Repairing(Actor self, Actor host); }
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 INotifyBuildComplete { void BuildingComplete(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; } }
}
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 = { };
@@ -157,7 +157,7 @@ namespace OpenRA.Mods.Common.Traits
}
}
public void Killed(Actor self, AttackInfo e)
public void Disposing(Actor self)
{
UnReserve();
}

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
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 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 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);
foreach (var harv in GetLinkedHarvesters())

View File

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

View File

@@ -54,7 +54,8 @@ namespace OpenRA.Mods.Common.Traits
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;
readonly Actor self;
@@ -305,6 +306,14 @@ namespace OpenRA.Mods.Common.Traits
cargo.Clear();
}
public void Disposing(Actor self)
{
foreach (var c in cargo)
c.Dispose();
cargo.Clear();
}
public void Selling(Actor self) { }
public void Sold(Actor self)
{

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
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;
@@ -51,9 +52,14 @@ namespace OpenRA.Mods.Common.Traits
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
disposed = true;
}
public IEnumerable<PipType> GetPips(Actor self)

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
@@ -27,7 +28,7 @@ namespace OpenRA.Mods.D2k.Traits
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 WRange carryHeight;
@@ -166,6 +167,15 @@ namespace OpenRA.Mods.D2k.Traits
UnreserveCarryable();
}
public void Disposing(Actor self)
{
if (Carrying != null && IsCarrying)
{
Carrying.Dispose();
Carrying = null;
}
}
// Called when carryable is inside.
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); }
}
class Sandworm : Wanders, ITick, INotifyKilled
class Sandworm : Wanders, ITick, INotifyActorDisposing
{
public readonly SandwormInfo Info;
@@ -151,9 +151,14 @@ namespace OpenRA.Mods.D2k.Traits
IsMovingTowardTarget = true;
}
public void Killed(Actor self, AttackInfo e)
bool disposed;
public void Disposing(Actor self)
{
if (disposed)
return;
manager.DecreaseWormCount();
disposed = true;
}
}
}