From 4ff309811f889132bc97cbee393267848f88a828 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 23 May 2015 21:41:21 +0100 Subject: [PATCH] Dispose actors when tearing down the world. --- OpenRA.Game/Actor.cs | 2 +- OpenRA.Game/Graphics/WorldRenderer.cs | 9 +++++++++ OpenRA.Game/World.cs | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 308caa85b0..07bab5419e 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -22,7 +22,7 @@ using OpenRA.Traits; namespace OpenRA { - public class Actor : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding, IEquatable + public sealed class Actor : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding, IEquatable, IDisposable { public readonly ActorInfo Info; diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 0d3c496404..4663496448 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -123,6 +123,9 @@ namespace OpenRA.Graphics public void Draw() { + if (World.WorldActor.Disposed) + return; + RefreshPalette(); if (World.Type == WorldType.Shellmap && !Game.Settings.Game.ShowShellmap) @@ -273,6 +276,12 @@ namespace OpenRA.Graphics public void Dispose() { + // HACK: Disposing the world from here violates ownership + // but the WorldRenderer lifetime matches the disposal + // behavior we want for the world, and the root object setup + // is so horrible that doing it properly would be a giant mess. + World.Dispose(); + palette.Dispose(); Theater.Dispose(); terrainRenderer.Dispose(); diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index a53a2163d1..5d7c6ae601 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -24,7 +24,7 @@ namespace OpenRA { public enum WorldType { Regular, Shellmap, Editor } - public class World + public sealed class World : IDisposable { class ActorIDComparer : IComparer { @@ -369,6 +369,19 @@ namespace OpenRA pi.OutcomeTimestampUtc = DateTime.UtcNow; } } + + public void Dispose() + { + frameEndActions.Clear(); + + // Dispose newer actors first, and the world actor last + foreach (var a in actors.Reverse()) + a.Dispose(); + + // Actor disposals are done in a FrameEndTask + while (frameEndActions.Count != 0) + frameEndActions.Dequeue()(this); + } } public struct TraitPair