Merge pull request #65 from Cintique/improve-require

Alter `LuaRequire`
This commit is contained in:
Evil Factory
2022-04-24 10:42:11 -03:00
committed by GitHub
2 changed files with 98 additions and 17 deletions
@@ -65,7 +65,10 @@ local function ExecutionQueue()
while queue[1] ~= nil do while queue[1] ~= nil do
RunFolder( RunFolder(
table.unpack( table.unpack(
table.remove(queue) table.remove(
queue,
1
)
) )
) )
end end
@@ -83,7 +86,7 @@ local function ExecutionQueue()
return queueExecutionFIFO, processQueueFIFO return queueExecutionFIFO, processQueueFIFO
end end
local queueAutorun, processAutorun = ExecutionQueue() local queueAutorun, processAutorun = ExecutionQueue()
local queueForcedAutorun, processForcedAutorun = ExecutionQueue() local queueForcedAutorun, processForcedAutorun = ExecutionQueue()
local function processPackages(packages, fn) local function processPackages(packages, fn)
@@ -2,40 +2,118 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using MoonSharp.Interpreter; using MoonSharp.Interpreter;
namespace Barotrauma namespace Barotrauma
{ {
class LuaRequire { class LuaRequire {
private Script lua { get; set; } private Script lua { get; set; }
private Dictionary<Tuple<string, Table>, DynValue> LoadedModules { get; set; } private Dictionary<string, DynValue> loadedModules { get; set; }
private bool GetExistingReturnValue(Tuple<string, Table> key, ref DynValue returnValue) { private bool getExistingReturnValue(string moduleName, ref DynValue returnValue)
return LoadedModules.TryGetValue(key, out returnValue); {
return loadedModules.TryGetValue(
moduleName,
out returnValue
);
} }
private void ExecuteModule(Tuple<string, Table> key, ref DynValue returnValue) { private string fixContentPackagePath(string contentPackagePath)
string moduleName = key.Item1; {
Table globalContext = key.Item2; contentPackagePath = Path.TrimEndingDirectorySeparator(
returnValue = lua.Call(lua.RequireModule(moduleName, globalContext)); new FileInfo(contentPackagePath) // filelist.xml
LoadedModules[key] = returnValue; .Directory
.FullName
.CleanUpPathCrossPlatform()
);
return contentPackagePath;
}
private string getContentPackagePath(string path)
{
IEnumerable<ContentPackage> allContentPackages = ContentPackageManager.AllPackages;
foreach (ContentPackage contentPackage in allContentPackages)
{
string contentPackagePath = fixContentPackagePath(contentPackage.Path);
if (path.StartsWith(contentPackagePath))
{
return contentPackagePath;
}
}
// Return null if we can't find a content package that
// this module belongs to.
return null;
}
private string getContentPackagePath(string moduleName, Table environment)
{
string filePath = lua.Options
.ScriptLoader
.ResolveModuleName(
moduleName,
environment
);
filePath = Path.TrimEndingDirectorySeparator(
new FileInfo(filePath)
.Directory
.FullName
.CleanUpPathCrossPlatform()
);
return getContentPackagePath(filePath);
}
private void saveReturnValue(string moduleName, DynValue returnValue)
{
loadedModules[moduleName] = returnValue;
}
private void executeModule(string moduleName, Table environment, ref DynValue returnValue)
{
DynValue loadFunc = lua.RequireModule(
moduleName,
environment
);
string packagePath = getContentPackagePath(
moduleName,
environment
);
returnValue = lua.Call(
loadFunc,
packagePath
);
} }
// Lua modules that have been previously loaded by require() will // Lua modules that have been previously loaded by require() will
// not be loaded again; instead, their initial return value is // not be loaded again; instead, their initial return value is
// preserved and returned again on subsequent attempts. // preserved and returned again on subsequent attempts.
public DynValue Require(string moduleName, Table globalContext) { public DynValue Require(string moduleName, Table globalContext)
DynValue returnValue = DynValue.Nil; {
var key = new Tuple<string, Table>(moduleName, globalContext); DynValue returnValue = null;
Table environment = globalContext ?? lua.Globals;
if (GetExistingReturnValue(key, ref returnValue)) return returnValue; if (getExistingReturnValue(moduleName, ref returnValue))
ExecuteModule(key, ref returnValue); return returnValue;
executeModule(moduleName, environment, ref returnValue);
if (
returnValue == null
|| returnValue.IsNil()
|| returnValue.IsVoid()
)
returnValue = DynValue.NewBoolean(true);
saveReturnValue(moduleName, returnValue);
return returnValue; return returnValue;
} }
public LuaRequire(Script lua) { public LuaRequire(Script lua)
{
this.lua = lua; this.lua = lua;
LoadedModules = new Dictionary<Tuple<string, Table>, DynValue>(); loadedModules = new Dictionary<string, DynValue>();
} }
} }
} }