Merge pull request #61 from Cintique/unstable-tests

Alter logic related to `require()`
This commit is contained in:
Evil Factory
2022-04-19 06:12:28 -03:00
committed by GitHub
3 changed files with 140 additions and 37 deletions
+94 -31
View File
@@ -1,5 +1,9 @@
local allPackages = ContentPackageManager.AllPackages
local localPackages = ContentPackageManager.LocalPackages
local LUA_MOD_REQUIRE_PATH = "/Lua/?.lua"
local LUA_MOD_AUTORUN_PATH = "/Lua/Autorun"
local LUA_MOD_FORCEDAUTORUN_PATH = "/Lua/ForcedAutorun"
local allPackages = ContentPackageManager.AllPackages
local localPackages = ContentPackageManager.LocalPackages
local enabledPackages = ContentPackageManager.EnabledPackages.All
local function EndsWith(str, suffix)
@@ -30,52 +34,111 @@ local function RunFolder(folder, rootFolder, package)
end
end
local function assertTypes(expectedTypes, ...)
local args = table.pack(...)
assert(
#args == #expectedTypes,
string.format(
"Assertion failed: incorrect number of args\n\texpected = %s\n\tgot = %s",
#expectedTypes,
#args
)
)
for i = 1, #args do
local arg = args[i]
local expectedType = expectedTypes[i]
assert(
type(arg) == expectedType,
string.format(
"Assertion failed: incorrect argument type (arg #%d)\n\texpected = %s\n\tgot = %s",
i,
expectedType,
type(arg)
)
)
end
end
for contentPackage in enabledPackages do
if contentPackage then
local d = contentPackage.Path:gsub("\\", "/")
d = d:gsub("/filelist.xml", "")
local function ExecutionQueue()
local queue = {}
local function processQueueFIFO()
while queue[1] ~= nil do
RunFolder(
table.unpack(
table.remove(queue)
)
)
end
end
local function queueExecutionFIFO(...)
assertTypes(
{ 'string', 'string', 'userdata' },
...
)
table.insert(
queue,
table.pack(...)
)
end
return queueExecutionFIFO, processQueueFIFO
end
table.insert(package.path, (d .. "/Lua/?.lua"))
local queueAutorun, processAutorun = ExecutionQueue()
local queueForcedAutorun, processForcedAutorun = ExecutionQueue()
if File.DirectoryExists(d .. "/Lua/Autorun") then
RunFolder(d .. "/Lua/Autorun", d, contentPackage)
local function processPackages(packages, fn)
for pkg in packages do
if pkg then
local pkgPath = pkg.Path
:gsub("\\", "/")
:gsub("/filelist.xml", "")
fn(pkg, pkgPath)
end
end
end
processPackages(
enabledPackages,
function(pkg, pkgPath)
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local autorunPath = pkgPath .. LUA_MOD_AUTORUN_PATH
if File.DirectoryExists(autorunPath) then
queueAutorun(autorunPath, pkgPath, pkg)
end
end
)
-- we don't want to execute workshop ForcedAutorun if we have a local Package
local executedLocalPackages = {}
for contentPackage in localPackages do
if contentPackage then
local d = contentPackage.Path:gsub("\\", "/")
d = d:gsub("/filelist.xml", "")
table.insert(package.path, (d .. "/Lua/?.lua"))
if File.DirectoryExists(d .. "/Lua/ForcedAutorun") then
RunFolder(d .. "/Lua/ForcedAutorun", d, contentPackage)
executedLocalPackages[contentPackage.Name] = true
processPackages(
localPackages,
function(pkg, pkgPath)
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH
if File.DirectoryExists(forcedAutorunPath) then
queueForcedAutorun(forcedAutorunPath, pkgPath, pkg)
executedLocalPackages[pkg.Name] = true
end
end
end
)
for contentPackage in allPackages do
if contentPackage and executedLocalPackages[contentPackage.Name] == nil then
local d = contentPackage.Path:gsub("\\", "/")
d = d:gsub("/filelist.xml", "")
table.insert(package.path, (d .. "/Lua/?.lua"))
if File.DirectoryExists(d .. "/Lua/ForcedAutorun") then
RunFolder(d .. "/Lua/ForcedAutorun", d, contentPackage)
processPackages(
allPackages,
function(pkg, pkgPath)
if not executedLocalPackages[pkg.Name] then
table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH)
local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH
if File.DirectoryExists(forcedAutorunPath) then
queueForcedAutorun(forcedAutorunPath, pkgPath, pkg)
end
end
end
end
)
setmodulepaths(package.path)
processAutorun()
processForcedAutorun()
Hook.Add("stop", "luaSetup.stop", function ()
print("Stopping Lua...")
@@ -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 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();