Browse Source

Flexible LuaModule

Akeit0 7 months ago
parent
commit
d976dd2661
3 changed files with 61 additions and 6 deletions
  1. 1 1
      src/Lua/Loaders/FileModuleLoader.cs
  2. 51 3
      src/Lua/LuaModule.cs
  3. 9 2
      src/Lua/Standard/ModuleLibrary.cs

+ 1 - 1
src/Lua/Loaders/FileModuleLoader.cs

@@ -13,7 +13,7 @@ public sealed class FileModuleLoader : ILuaModuleLoader
     {
         var path = moduleName;
         if (!Path.HasExtension(path)) path += ".lua";
-        var text = await File.ReadAllTextAsync(path, cancellationToken);
+        var text = await File.ReadAllBytesAsync(path, cancellationToken);
         return new LuaModule(moduleName, text);
     }
 }

+ 51 - 3
src/Lua/LuaModule.cs

@@ -1,11 +1,14 @@
+using System.Buffers;
+
 namespace Lua;
 
 public enum LuaModuleType
 {
     Text,
+    Bytes
 }
 
-public readonly struct LuaModule
+public readonly struct LuaModule : IDisposable
 {
     public string Name => name;
     public LuaModuleType Type => type;
@@ -21,9 +24,54 @@ public readonly struct LuaModule
         referenceValue = text;
     }
 
-    public string ReadText()
+    public LuaModule(string name, byte[] bytes)
+    {
+        this.name = name;
+        type = LuaModuleType.Bytes;
+        referenceValue = bytes;
+    }
+
+    public LuaModule(string name, IMemoryOwner<char> bytes)
+    {
+        this.name = name;
+        type = LuaModuleType.Text;
+        referenceValue = bytes;
+    }
+
+    public LuaModule(string name, IMemoryOwner<byte> bytes)
+    {
+        this.name = name;
+        type = LuaModuleType.Bytes;
+        referenceValue = bytes;
+    }
+
+    public ReadOnlySpan<char> ReadText()
     {
         if (type != LuaModuleType.Text) throw new Exception(); // TODO: add message
-        return (string)referenceValue;
+        if (referenceValue is IMemoryOwner<char> mem)
+        {
+            return mem.Memory.Span;
+        }
+
+        return ((string)referenceValue);
+    }
+
+    public ReadOnlySpan<byte> ReadBytes()
+    {
+        if (type != LuaModuleType.Bytes) throw new Exception(); // TODO: add message
+        if (referenceValue is IMemoryOwner<byte> mem)
+        {
+            return mem.Memory.Span;
+        }
+
+        return (byte[])referenceValue;
+    }
+
+    public void Dispose()
+    {
+        if (referenceValue is IDisposable memoryOwner)
+        {
+            memoryOwner.Dispose();
+        }
     }
 }

+ 9 - 2
src/Lua/Standard/ModuleLibrary.cs

@@ -18,8 +18,15 @@ public sealed class ModuleLibrary
 
         if (!loaded.TryGetValue(arg0, out var loadedTable))
         {
-            var module = await context.State.ModuleLoader.LoadAsync(arg0, cancellationToken);
-            await context.State.Load(module.ReadText(), module.Name).InvokeAsync(context, cancellationToken);
+            using var module = await context.State.ModuleLoader.LoadAsync(arg0, cancellationToken);
+            if (module.Type == LuaModuleType.Bytes)
+            {
+                await context.State.Load(module.ReadBytes(), module.Name).InvokeAsync(context, cancellationToken);
+            }
+            else
+            {
+                await context.State.Load(module.ReadText(), module.Name).InvokeAsync(context, cancellationToken);
+            }
 
             loadedTable = context.Thread.Stack.Get(context.ReturnFrameBase);
             loaded[arg0] = loadedTable;