Update require() behaviour

The behaviour of `require()` has been changed to align more closely with standard Lua (caching return results).
This commit is contained in:
Jacobin
2022-04-19 15:20:52 +10:00
parent bab2a88533
commit 72063cdf93
2 changed files with 46 additions and 6 deletions
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using MoonSharp.Interpreter;
namespace Barotrauma
{
class LuaRequire {
private Script lua { get; set; }
private Dictionary<Tuple<string, Table>, DynValue> LoadedModules { get; set; }
private bool GetExistingReturnValue(Tuple<string, Table> key, ref DynValue returnValue) {
return LoadedModules.TryGetValue(key, out returnValue);
}
private void ExecuteModule(Tuple<string, Table> key, ref DynValue returnValue) {
string moduleName = key.Item1;
Table globalContext = key.Item2;
returnValue = lua.Call(lua.RequireModule(moduleName, globalContext));
LoadedModules[key] = returnValue;
}
// Lua modules that have been previously loaded by require() will
// not be loaded again; instead, their initial return value is
// preserved and returned again on subsequent attempts.
public DynValue Require(string moduleName, Table globalContext) {
DynValue returnValue = DynValue.Nil;
var key = new Tuple<string, Table>(moduleName, globalContext);
if (GetExistingReturnValue(key, ref returnValue)) return returnValue;
ExecuteModule(key, ref returnValue);
return returnValue;
}
public LuaRequire(Script lua) {
this.lua = lua;
LoadedModules = new Dictionary<Tuple<string, Table>, DynValue>();
}
}
}
@@ -29,6 +29,7 @@ namespace Barotrauma
public LuaCsHook Hook { get; private set; } public LuaCsHook Hook { get; private set; }
public LuaCsNetworking Networking { get; private set; } public LuaCsNetworking Networking { get; private set; }
public LuaCsModStore ModStore { get; private set; } public LuaCsModStore ModStore { get; private set; }
private LuaRequire require { get; set; }
public CsScriptLoader NetScriptLoader { get; private set; } public CsScriptLoader NetScriptLoader { get; private set; }
public CsLua Lua { get; private set; } public CsLua Lua { get; private set; }
@@ -236,22 +237,18 @@ namespace Barotrauma
return null; return null;
} }
public DynValue Require(string moduleName, Table globalContexts)
private DynValue Require(string modname, Table globalContext)
{ {
try try
{ {
return lua.Call(lua.RequireModule(modname, globalContext)); return require.Require(moduleName, globalContexts);
} }
catch (Exception e) catch (Exception e)
{ {
HandleException(e); HandleException(e);
} }
return null; return null;
} }
public object CallLuaFunction(object function, params object[] arguments) public object CallLuaFunction(object function, params object[] arguments)
{ {
try try
@@ -310,6 +307,8 @@ namespace Barotrauma
Lua = new CsLua(this); Lua = new CsLua(this);
CsScript = new CsScriptRunner(this); CsScript = new CsScriptRunner(this);
require = new LuaRequire(lua);
Game = new LuaGame(); Game = new LuaGame();
Networking = new LuaCsNetworking(); Networking = new LuaCsNetworking();
Hook.Initialize(); Hook.Initialize();