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:
@@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user