From 8ae3afa3c5ab4d8f4dea97a782c26726582852a9 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 23 May 2015 22:09:50 +0100 Subject: [PATCH] Properly clean up traits that used to hook only death. --- OpenRA.Game/Actor.cs | 3 +++ OpenRA.Game/Traits/TraitsInterfaces.cs | 1 + OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 4 ++-- OpenRA.Mods.Common/Traits/Buildings/Refinery.cs | 5 +++-- OpenRA.Mods.Common/Traits/Buildings/Reservable.cs | 4 ++-- OpenRA.Mods.Common/Traits/Cargo.cs | 11 ++++++++++- OpenRA.Mods.Common/Traits/StoresResources.cs | 10 ++++++++-- OpenRA.Mods.D2k/Traits/Carryall.cs | 12 +++++++++++- OpenRA.Mods.D2k/Traits/Sandworm.cs | 9 +++++++-- 9 files changed, 47 insertions(+), 12 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 07bab5419e..3f8599470e 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -225,6 +225,9 @@ namespace OpenRA if (IsInWorld) World.Remove(this); + foreach (var t in TraitsImplementing()) + t.Disposing(this); + World.TraitDict.RemoveActor(this); Disposed = true; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index e5c7990c1a..2e82851707 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -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); } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index fbe23c3a0b..edc09adf86 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -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[] NoCells = { }; @@ -157,7 +157,7 @@ namespace OpenRA.Mods.Common.Traits } } - public void Killed(Actor self, AttackInfo e) + public void Disposing(Actor self) { UnReserve(); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs b/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs index 6f70acf409..f152a180c4 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Refinery.cs @@ -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()) diff --git a/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs b/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs index 33382e53ef..ef3726b20a 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Reservable.cs @@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits [Desc("Reserve landing places for aircraft.")] class ReservableInfo : TraitInfo { } - 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(); diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index e501df1acf..c8b430b097 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -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) { diff --git a/OpenRA.Mods.Common/Traits/StoresResources.cs b/OpenRA.Mods.Common/Traits/StoresResources.cs index 8f5cdb1525..d9fe185256 100644 --- a/OpenRA.Mods.Common/Traits/StoresResources.cs +++ b/OpenRA.Mods.Common/Traits/StoresResources.cs @@ -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().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 GetPips(Actor self) diff --git a/OpenRA.Mods.D2k/Traits/Carryall.cs b/OpenRA.Mods.D2k/Traits/Carryall.cs index 1e0f928059..4a13a8b56c 100644 --- a/OpenRA.Mods.D2k/Traits/Carryall.cs +++ b/OpenRA.Mods.D2k/Traits/Carryall.cs @@ -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) { diff --git a/OpenRA.Mods.D2k/Traits/Sandworm.cs b/OpenRA.Mods.D2k/Traits/Sandworm.cs index d40d1fcfbb..6e3270eb9f 100644 --- a/OpenRA.Mods.D2k/Traits/Sandworm.cs +++ b/OpenRA.Mods.D2k/Traits/Sandworm.cs @@ -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; } } } \ No newline at end of file