diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs new file mode 100644 index 000000000..0509bc0a6 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs @@ -0,0 +1,41 @@ + + +using System; +using System.Collections.Generic; +using MoonSharp.Interpreter; + +namespace Barotrauma +{ + class LuaRequire { + private Script lua { get; set; } + private Dictionary, DynValue> LoadedModules { get; set; } + + private bool GetExistingReturnValue(Tuple key, ref DynValue returnValue) { + return LoadedModules.TryGetValue(key, out returnValue); + } + + private void ExecuteModule(Tuple 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(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, DynValue>(); + } + } +} \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs index 6f49c109a..364579d6b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs @@ -29,6 +29,7 @@ namespace Barotrauma public LuaCsHook Hook { get; private set; } public LuaCsNetworking Networking { get; private set; } public LuaCsModStore ModStore { get; private set; } + private LuaRequire require { get; set; } public CsScriptLoader NetScriptLoader { get; private set; } public CsLua Lua { get; private set; } @@ -236,22 +237,18 @@ namespace Barotrauma return null; } - - private DynValue Require(string modname, Table globalContext) + public DynValue Require(string moduleName, Table globalContexts) { try { - return lua.Call(lua.RequireModule(modname, globalContext)); - + return require.Require(moduleName, globalContexts); } catch (Exception e) { HandleException(e); } - return null; } - public object CallLuaFunction(object function, params object[] arguments) { try @@ -310,6 +307,8 @@ namespace Barotrauma Lua = new CsLua(this); CsScript = new CsScriptRunner(this); + require = new LuaRequire(lua); + Game = new LuaGame(); Networking = new LuaCsNetworking(); Hook.Initialize();