Fix issues in ScriptTriggers' Clean method

* fixes a memory leak
* moves the cleanup into a FrameEndTask to avoid collisions with the
  trigger iterator (fixes #6747)
This commit is contained in:
Oliver Brakmann
2014-09-12 22:47:43 +02:00
parent 426f146905
commit a1ce37ddc5

View File

@@ -22,18 +22,25 @@ namespace OpenRA.Mods.RA.Scripting
OnObjectiveCompleted, OnObjectiveFailed, OnCapture, OnAddedToWorld, OnRemovedFromWorld }; OnObjectiveCompleted, OnObjectiveFailed, OnCapture, OnAddedToWorld, OnRemovedFromWorld };
[Desc("Allows map scripts to attach triggers to this actor via the Triggers global.")] [Desc("Allows map scripts to attach triggers to this actor via the Triggers global.")]
public class ScriptTriggersInfo : TraitInfo<ScriptTriggers> { } public class ScriptTriggersInfo : ITraitInfo
{
public object Create(ActorInitializer init) { return new ScriptTriggers(init.world); }
}
public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, INotifyObjectivesUpdated, INotifyCapture, INotifyAddedToWorld, INotifyRemovedFromWorld, IDisposable public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, INotifyObjectivesUpdated, INotifyCapture, INotifyAddedToWorld, INotifyRemovedFromWorld, IDisposable
{ {
readonly World world;
public event Action<Actor> OnKilledInternal = _ => { }; public event Action<Actor> OnKilledInternal = _ => { };
public event Action<Actor> OnRemovedInternal = _ => { }; public event Action<Actor> OnRemovedInternal = _ => { };
public Dictionary<Trigger, List<Pair<LuaFunction, ScriptContext>>> Triggers = new Dictionary<Trigger, List<Pair<LuaFunction, ScriptContext>>>(); public Dictionary<Trigger, List<Pair<LuaFunction, ScriptContext>>> Triggers = new Dictionary<Trigger, List<Pair<LuaFunction, ScriptContext>>>();
public ScriptTriggers() public ScriptTriggers(World world)
{ {
foreach (var t in Enum.GetValues(typeof(Trigger)).Cast<Trigger>()) this.world = world;
foreach (Trigger t in Enum.GetValues(typeof(Trigger)))
Triggers.Add(t, new List<Pair<LuaFunction, ScriptContext>>()); Triggers.Add(t, new List<Pair<LuaFunction, ScriptContext>>());
} }
@@ -265,20 +272,22 @@ namespace OpenRA.Mods.RA.Scripting
public void Clear(Trigger trigger) public void Clear(Trigger trigger)
{ {
Triggers[trigger].Clear(); world.AddFrameEndTask(w =>
{
Triggers[trigger].Select(p => p.First).Do(f => f.Dispose());
Triggers[trigger].Clear();
});
} }
public void ClearAll() public void ClearAll()
{ {
foreach (var trigger in Triggers) foreach (Trigger t in Enum.GetValues(typeof(Trigger)))
trigger.Value.Clear(); Clear(t);
} }
public void Dispose() public void Dispose()
{ {
var pairs = Triggers.Values; ClearAll();
pairs.SelectMany(l => l).Select(p => p.First).Do(f => f.Dispose());
pairs.Do(l => l.Clear());
} }
} }
} }