Browse Source

change: simplify platform access api

Akeit0 4 months ago
parent
commit
b9821f4b8a

+ 1 - 9
src/Lua/LuaGlobalState.cs

@@ -39,18 +39,10 @@ public sealed class LuaGlobalState
 
 
     public LuaState MainThread => mainState;
     public LuaState MainThread => mainState;
 
 
-    public LuaPlatform Platform { get; }
+    public LuaPlatform Platform { get; set; }
 
 
     public ILuaModuleLoader? ModuleLoader { get; set; }
     public ILuaModuleLoader? ModuleLoader { get; set; }
 
 
-    public ILuaFileSystem FileSystem => Platform.FileSystem ?? throw new InvalidOperationException("FileSystem is not set. Please set it before access.");
-
-    public ILuaOsEnvironment OsEnvironment => Platform.OsEnvironment ?? throw new InvalidOperationException("OperatingSystem is not set. Please set it before access.");
-
-    public TimeProvider TimeProvider => Platform.TimeProvider ?? throw new InvalidOperationException("TimeProvider is not set. Please set it before access.");
-
-    public ILuaStandardIO StandardIO => Platform.StandardIO;
-
     // metatables
     // metatables
     LuaTable? nilMetatable;
     LuaTable? nilMetatable;
     LuaTable? numberMetatable;
     LuaTable? numberMetatable;

+ 5 - 1
src/Lua/LuaState.cs

@@ -182,7 +182,11 @@ public class LuaState : IDisposable
 
 
     public LuaTable Environment => GlobalState.Environment;
     public LuaTable Environment => GlobalState.Environment;
 
 
-    public LuaPlatform Platform => GlobalState.Platform;
+    public LuaPlatform Platform
+    {
+        get => GlobalState.Platform;
+        set => GlobalState.Platform = value;
+    }
 
 
     internal bool IsCallHookEnabled
     internal bool IsCallHookEnabled
     {
     {

+ 1 - 1
src/Lua/LuaStateExtensions.cs

@@ -11,7 +11,7 @@ public static class LuaStateExtensions
     public static async ValueTask<LuaClosure> LoadFileAsync(this LuaState state, string fileName, string mode, LuaTable? environment, CancellationToken cancellationToken)
     public static async ValueTask<LuaClosure> LoadFileAsync(this LuaState state, string fileName, string mode, LuaTable? environment, CancellationToken cancellationToken)
     {
     {
         var name = "@" + fileName;
         var name = "@" + fileName;
-        using var stream = await state.GlobalState.FileSystem.Open(fileName, LuaFileOpenMode.Read, cancellationToken);
+        using var stream = await state.GlobalState.Platform.FileSystem.Open(fileName, LuaFileOpenMode.Read, cancellationToken);
         var source = await stream.ReadAllAsync(cancellationToken);
         var source = await stream.ReadAllAsync(cancellationToken);
         var closure = state.Load(source, name, environment);
         var closure = state.Load(source, name, environment);
 
 

+ 8 - 12
src/Lua/Platforms/LuaPlatform.cs

@@ -6,23 +6,19 @@ namespace Lua.Platforms;
 /// <summary>
 /// <summary>
 ///  Platform abstraction for Lua.
 ///  Platform abstraction for Lua.
 /// </summary>
 /// </summary>
-/// <param name="fileSystem"></param>
-/// <param name="osEnvironment"></param>
-/// <param name="standardIO"></param>
-public sealed class LuaPlatform(ILuaFileSystem fileSystem, ILuaOsEnvironment osEnvironment, ILuaStandardIO standardIO, TimeProvider timeProvider)
+/// <param name="FileSystem"></param>
+/// <param name="OsEnvironment"></param>
+/// <param name="StandardIO"></param>
+public record LuaPlatform(ILuaFileSystem FileSystem, ILuaOsEnvironment OsEnvironment, ILuaStandardIO StandardIO, TimeProvider TimeProvider)
 {
 {
     /// <summary>
     /// <summary>
     /// Standard console platform implementation.
     /// Standard console platform implementation.
     /// Uses real file system, console I/O, and system operations.
     /// Uses real file system, console I/O, and system operations.
     /// </summary>
     /// </summary>
     public static LuaPlatform Default =>
     public static LuaPlatform Default =>
-        new(fileSystem: new FileSystem(),
-            osEnvironment: new SystemOsEnvironment(),
-            standardIO: new ConsoleStandardIO(),
-            timeProvider: TimeProvider.System);
+        new(FileSystem: new FileSystem(),
+            OsEnvironment: new SystemOsEnvironment(),
+            StandardIO: new ConsoleStandardIO(),
+            TimeProvider: TimeProvider.System);
 
 
-    public ILuaFileSystem FileSystem { get; set; } = fileSystem;
-    public ILuaOsEnvironment OsEnvironment { get; set; } = osEnvironment;
-    public ILuaStandardIO StandardIO { get; set; } = standardIO;
-    public TimeProvider TimeProvider { get; set; } = timeProvider;
 }
 }

+ 1 - 1
src/Lua/Standard/BasicLibrary.cs

@@ -290,7 +290,7 @@ public sealed class BasicLibrary
 
 
     public async ValueTask<int> Print(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> Print(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        var stdout = context.GlobalState.StandardIO.Output;
+        var stdout = context.GlobalState.Platform.StandardIO.Output;
 
 
         for (var i = 0; i < context.ArgumentCount; i++)
         for (var i = 0; i < context.ArgumentCount; i++)
         {
         {

+ 3 - 3
src/Lua/Standard/IOLibrary.cs

@@ -77,7 +77,7 @@ public sealed class IOLibrary
         }
         }
         else
         else
         {
         {
-            var stream = await context.GlobalState.FileSystem.Open(arg.ToString(), LuaFileOpenMode.Read, cancellationToken);
+            var stream = await context.GlobalState.Platform.FileSystem.Open(arg.ToString(), LuaFileOpenMode.Read, cancellationToken);
             FileHandle handle = new(stream);
             FileHandle handle = new(stream);
             registry["_IO_input"] = new(handle);
             registry["_IO_input"] = new(handle);
             return context.Return(new LuaValue(handle));
             return context.Return(new LuaValue(handle));
@@ -168,7 +168,7 @@ public sealed class IOLibrary
         }
         }
         else
         else
         {
         {
-            var stream = await context.GlobalState.FileSystem.Open(arg.ToString(), LuaFileOpenMode.WriteUpdate, cancellationToken);
+            var stream = await context.GlobalState.Platform.FileSystem.Open(arg.ToString(), LuaFileOpenMode.WriteUpdate, cancellationToken);
             FileHandle handle = new(stream);
             FileHandle handle = new(stream);
             io["_IO_output"] = new(handle);
             io["_IO_output"] = new(handle);
             return context.Return(new LuaValue(handle));
             return context.Return(new LuaValue(handle));
@@ -208,6 +208,6 @@ public sealed class IOLibrary
 
 
     public async ValueTask<int> TmpFile(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> TmpFile(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        return context.Return(LuaValue.FromUserData(new FileHandle(await context.GlobalState.FileSystem.OpenTempFileStream(cancellationToken))));
+        return context.Return(LuaValue.FromUserData(new FileHandle(await context.GlobalState.Platform.FileSystem.OpenTempFileStream(cancellationToken))));
     }
     }
 }
 }

+ 1 - 1
src/Lua/Standard/Internal/IOHelper.cs

@@ -17,7 +17,7 @@ static class IOHelper
 
 
         try
         try
         {
         {
-            var stream = await state.GlobalState.FileSystem.Open(fileName, fileMode, cancellationToken);
+            var stream = await state.GlobalState.Platform.FileSystem.Open(fileName, fileMode, cancellationToken);
 
 
             state.Stack.Push(new(new FileHandle(stream)));
             state.Stack.Push(new(new FileHandle(stream)));
             return 1;
             return 1;

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

@@ -87,7 +87,7 @@ public sealed class ModuleLibrary
         {
         {
             path = pathSpan[..nextIndex].ToString();
             path = pathSpan[..nextIndex].ToString();
             var fileName = path.Replace("?", name);
             var fileName = path.Replace("?", name);
-            if (state.GlobalState.FileSystem.IsReadable(fileName))
+            if (state.GlobalState.Platform.FileSystem.IsReadable(fileName))
             {
             {
                 return fileName;
                 return fileName;
             }
             }
@@ -156,7 +156,7 @@ public sealed class ModuleLibrary
     public async ValueTask<int> SearcherLua(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> SearcherLua(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
         var name = context.GetArgument<string>(0);
         var name = context.GetArgument<string>(0);
-        var fileName = await FindFile(context.State, name, "path", context.GlobalState.FileSystem.DirectorySeparator);
+        var fileName = await FindFile(context.State, name, "path", context.GlobalState.Platform.FileSystem.DirectorySeparator);
         if (fileName == null)
         if (fileName == null)
         {
         {
             return context.Return(LuaValue.Nil);
             return context.Return(LuaValue.Nil);

+ 1 - 1
src/Lua/Standard/OpenLibsExtensions.cs

@@ -47,7 +47,7 @@ public static class OpenLibsExtensions
         }
         }
 
 
         var registry = globalState.Registry;
         var registry = globalState.Registry;
-        var standardIO = globalState.StandardIO;
+        var standardIO = globalState.Platform.StandardIO;
         LuaValue stdin = new(new FileHandle(standardIO.Input));
         LuaValue stdin = new(new FileHandle(standardIO.Input));
         LuaValue stdout = new(new FileHandle(standardIO.Output));
         LuaValue stdout = new(new FileHandle(standardIO.Output));
         LuaValue stderr = new(new FileHandle(standardIO.Error));
         LuaValue stderr = new(new FileHandle(standardIO.Error));

+ 9 - 9
src/Lua/Standard/OperatingSystemLibrary.cs

@@ -28,7 +28,7 @@ public sealed class OperatingSystemLibrary
 
 
     public ValueTask<int> Clock(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public ValueTask<int> Clock(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        return new(context.Return(context.GlobalState.OsEnvironment.GetTotalProcessorTime()));
+        return new(context.Return(context.GlobalState.Platform.OsEnvironment.GetTotalProcessorTime()));
     }
     }
 
 
     public ValueTask<int> Date(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public ValueTask<int> Date(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
@@ -45,7 +45,7 @@ public sealed class OperatingSystemLibrary
         }
         }
         else
         else
         {
         {
-            now = context.GlobalState.TimeProvider.GetUtcNow().DateTime;
+            now = context.GlobalState.Platform.TimeProvider.GetUtcNow().DateTime;
         }
         }
 
 
         var isDst = false;
         var isDst = false;
@@ -55,7 +55,7 @@ public sealed class OperatingSystemLibrary
         }
         }
         else
         else
         {
         {
-            now = context.GlobalState.TimeProvider.GetLocalNow().DateTime;
+            now = context.GlobalState.Platform.TimeProvider.GetLocalNow().DateTime;
             isDst = now.IsDaylightSavingTime();
             isDst = now.IsDaylightSavingTime();
         }
         }
 
 
@@ -125,14 +125,14 @@ public sealed class OperatingSystemLibrary
             }
             }
         }
         }
 
 
-        await context.GlobalState.OsEnvironment.Exit(exitCode, cancellationToken);
+        await context.GlobalState.Platform.OsEnvironment.Exit(exitCode, cancellationToken);
         throw new InvalidOperationException("Unreachable code.. reached.");
         throw new InvalidOperationException("Unreachable code.. reached.");
     }
     }
 
 
     public ValueTask<int> GetEnv(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public ValueTask<int> GetEnv(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
         var variable = context.GetArgument<string>(0);
         var variable = context.GetArgument<string>(0);
-        return new(context.Return(context.GlobalState.OsEnvironment.GetEnvironmentVariable(variable) ?? LuaValue.Nil));
+        return new(context.Return(context.GlobalState.Platform.OsEnvironment.GetEnvironmentVariable(variable) ?? LuaValue.Nil));
     }
     }
 
 
     public async ValueTask<int> Remove(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> Remove(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
@@ -140,7 +140,7 @@ public sealed class OperatingSystemLibrary
         var fileName = context.GetArgument<string>(0);
         var fileName = context.GetArgument<string>(0);
         try
         try
         {
         {
-            await context.GlobalState.FileSystem.Remove(fileName, cancellationToken);
+            await context.GlobalState.Platform.FileSystem.Remove(fileName, cancellationToken);
             return context.Return(true);
             return context.Return(true);
         }
         }
         catch (IOException ex)
         catch (IOException ex)
@@ -155,7 +155,7 @@ public sealed class OperatingSystemLibrary
         var newName = context.GetArgument<string>(1);
         var newName = context.GetArgument<string>(1);
         try
         try
         {
         {
-            await context.GlobalState.FileSystem.Rename(oldName, newName, cancellationToken);
+            await context.GlobalState.Platform.FileSystem.Rename(oldName, newName, cancellationToken);
             return context.Return(true);
             return context.Return(true);
         }
         }
         catch (IOException ex)
         catch (IOException ex)
@@ -180,12 +180,12 @@ public sealed class OperatingSystemLibrary
         }
         }
         else
         else
         {
         {
-            return new(context.Return(DateTimeHelper.GetUnixTime(context.GlobalState.TimeProvider.GetUtcNow().DateTime)));
+            return new(context.Return(DateTimeHelper.GetUnixTime(context.GlobalState.Platform.TimeProvider.GetUtcNow().DateTime)));
         }
         }
     }
     }
 
 
     public ValueTask<int> TmpName(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public ValueTask<int> TmpName(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        return new(context.Return(context.GlobalState.FileSystem.GetTempFileName()));
+        return new(context.Return(context.GlobalState.Platform.FileSystem.GetTempFileName()));
     }
     }
 }
 }

+ 8 - 8
tests/Lua.Tests/AbstractFileTests.cs

@@ -31,10 +31,10 @@ public class AbstractFileTests
         var fileContent = "line1\nline2\r\nline3";
         var fileContent = "line1\nline2\r\nline3";
         var fileSystem = new ReadOnlyFileSystem(new() { { "test.txt", fileContent } });
         var fileSystem = new ReadOnlyFileSystem(new() { { "test.txt", fileContent } });
         var state = LuaState.Create(new LuaPlatform(
         var state = LuaState.Create(new LuaPlatform(
-            fileSystem: fileSystem,
-            osEnvironment: null!,
-            standardIO: new ConsoleStandardIO(),
-            timeProvider: TimeProvider.System
+            FileSystem: fileSystem,
+            OsEnvironment: null!,
+            StandardIO: new ConsoleStandardIO(),
+            TimeProvider: TimeProvider.System
         ));
         ));
         state.OpenStandardLibraries();
         state.OpenStandardLibraries();
         try
         try
@@ -65,10 +65,10 @@ public class AbstractFileTests
         var fileContent = "Hello, World!";
         var fileContent = "Hello, World!";
         var fileSystem = new ReadOnlyFileSystem(new() { { "test.txt", fileContent } });
         var fileSystem = new ReadOnlyFileSystem(new() { { "test.txt", fileContent } });
         var state = LuaState.Create(new LuaPlatform(
         var state = LuaState.Create(new LuaPlatform(
-            fileSystem: fileSystem,
-            osEnvironment: null!,
-            standardIO: new ConsoleStandardIO(),
-            timeProvider: TimeProvider.System));
+            FileSystem: fileSystem,
+            OsEnvironment: null!,
+            StandardIO: new ConsoleStandardIO(),
+            TimeProvider: TimeProvider.System));
         state.OpenStandardLibraries();
         state.OpenStandardLibraries();
 
 
         await state.DoStringAsync(
         await state.DoStringAsync(

+ 1 - 1
tests/Lua.Tests/LuaTests.cs

@@ -30,7 +30,7 @@ public class LuaTests
     public async Task Test_Lua(string file)
     public async Task Test_Lua(string file)
     {
     {
         var state = LuaState.Create();
         var state = LuaState.Create();
-        state.Platform.StandardIO = new TestStandardIO();
+        state.Platform = state.Platform with { StandardIO = new TestStandardIO() };
         state.OpenStandardLibraries();
         state.OpenStandardLibraries();
         var path = FileHelper.GetAbsolutePath(file);
         var path = FileHelper.GetAbsolutePath(file);
         Directory.SetCurrentDirectory(Path.GetDirectoryName(path)!);
         Directory.SetCurrentDirectory(Path.GetDirectoryName(path)!);