Merge pull request #5370 from pavlos256/lua-dispose-crash
Possible fix for lua crash #5269
This commit is contained in:
@@ -81,11 +81,12 @@ namespace OpenRA.Scripting
|
|||||||
public ScriptGlobalAttribute(string name) { Name = name; }
|
public ScriptGlobalAttribute(string name) { Name = name; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScriptContext
|
public class ScriptContext : IDisposable
|
||||||
{
|
{
|
||||||
public World World { get; private set; }
|
public World World { get; private set; }
|
||||||
public WorldRenderer WorldRenderer { get; private set; }
|
public WorldRenderer WorldRenderer { get; private set; }
|
||||||
|
|
||||||
|
bool disposed;
|
||||||
readonly MemoryConstrainedLuaRuntime runtime;
|
readonly MemoryConstrainedLuaRuntime runtime;
|
||||||
readonly LuaFunction tick;
|
readonly LuaFunction tick;
|
||||||
|
|
||||||
@@ -188,26 +189,34 @@ namespace OpenRA.Scripting
|
|||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error || disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (new PerfSample("tick_lua"))
|
using (new PerfSample("tick_lua"))
|
||||||
tick.Call().Dispose();
|
tick.Call().Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (runtime == null)
|
if (disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
runtime.Dispose();
|
||||||
|
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
runtime.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScriptContext()
|
~ScriptContext()
|
||||||
{
|
{
|
||||||
if (runtime != null)
|
// Dispose unmanaged resources only
|
||||||
Game.RunAfterTick(Dispose);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type[] ExtractRequiredTypes(Type t)
|
static Type[] ExtractRequiredTypes(Type t)
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.RA.Activities
|
namespace OpenRA.Mods.RA.Activities
|
||||||
{
|
{
|
||||||
public class CallLuaFunc : Activity
|
public class CallLuaFunc : Activity, IDisposable
|
||||||
{
|
{
|
||||||
LuaFunction function;
|
LuaFunction function;
|
||||||
|
|
||||||
public CallLuaFunc(LuaFunction func)
|
public CallLuaFunc(LuaFunction func)
|
||||||
{
|
{
|
||||||
function = func.CopyReference() as LuaFunction;
|
function = (LuaFunction)func.CopyReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
@@ -38,20 +39,28 @@ namespace OpenRA.Mods.RA.Activities
|
|||||||
base.Cancel(self);
|
base.Cancel(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (function == null)
|
if (function == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
function.Dispose();
|
||||||
|
function = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
function.Dispose();
|
|
||||||
function = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~CallLuaFunc()
|
~CallLuaFunc()
|
||||||
{
|
{
|
||||||
if (function != null)
|
// Dispose unmanaged resources only
|
||||||
Game.RunAfterTick(Dispose);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA.Scripting
|
|||||||
[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 : TraitInfo<ScriptTriggers> { }
|
||||||
|
|
||||||
public class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction
|
public class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, IDisposable
|
||||||
{
|
{
|
||||||
public event Action<Actor> OnKilledInternal = _ => {};
|
public event Action<Actor> OnKilledInternal = _ => {};
|
||||||
|
|
||||||
@@ -101,21 +101,36 @@ namespace OpenRA.Mods.RA.Scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool disposed;
|
bool disposed;
|
||||||
|
|
||||||
|
protected void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
var toDispose = new [] { onIdle, onDamaged, onKilled, onProduction };
|
||||||
|
|
||||||
|
foreach (var f in toDispose.SelectMany(f => f))
|
||||||
|
f.First.Dispose();
|
||||||
|
|
||||||
|
foreach (var l in toDispose)
|
||||||
|
l.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
disposed = true;
|
Dispose(true);
|
||||||
var toDispose = new [] { onIdle, onDamaged, onKilled, onProduction };
|
|
||||||
|
|
||||||
foreach (var f in toDispose.SelectMany(f => f))
|
|
||||||
f.First.Dispose();
|
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScriptTriggers()
|
~ScriptTriggers()
|
||||||
{
|
{
|
||||||
if (!disposed)
|
// Dispose unmanaged resources only
|
||||||
Game.RunAfterTick(Dispose);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user