Browse Source

Add: LuaUserData

AnnulusGames 1 year ago
parent
commit
abbd15e58e

+ 11 - 0
src/Lua/LuaUserData.cs

@@ -0,0 +1,11 @@
+namespace Lua;
+
+public abstract class LuaUserData
+{
+    public LuaTable? Metatable { get; set; }
+}
+
+public class LuaUserData<T>(T value) : LuaUserData
+{
+    public T Value { get; } = value;
+}

+ 25 - 8
src/Lua/LuaValue.cs

@@ -132,12 +132,27 @@ public readonly struct LuaValue : IEquatable<LuaValue>
                     break;
                 }
             case LuaValueType.UserData:
-                if (referenceValue is T userData)
+                if (t == typeof(LuaUserData))
                 {
-                    result = userData;
+                    var v = (LuaUserData)referenceValue!;
+                    result = Unsafe.As<LuaUserData, T>(ref v);
                     return true;
                 }
-                break;
+                else if (t == typeof(LuaUserData<T>))
+                {
+                    var v = (LuaUserData<T>)referenceValue!;
+                    result = Unsafe.As<LuaUserData<T>, T>(ref v);
+                    return true;
+                }
+                else if (t == typeof(object))
+                {
+                    result = (T)referenceValue!;
+                    return true;
+                }
+                else
+                {
+                    break;
+                }
             case LuaValueType.Table:
                 if (t == typeof(LuaTable))
                 {
@@ -210,7 +225,7 @@ public readonly struct LuaValue : IEquatable<LuaValue>
         referenceValue = value;
     }
 
-    public LuaValue(object? value)
+    public LuaValue(LuaUserData value)
     {
         type = LuaValueType.UserData;
         referenceValue = value;
@@ -246,6 +261,11 @@ public readonly struct LuaValue : IEquatable<LuaValue>
         return new(value);
     }
 
+    public static implicit operator LuaValue(LuaUserData value)
+    {
+        return new(value);
+    }
+
     public override int GetHashCode()
     {
         var valueHash = type switch
@@ -254,10 +274,7 @@ public readonly struct LuaValue : IEquatable<LuaValue>
             LuaValueType.Boolean => Read<bool>().GetHashCode(),
             LuaValueType.String => Read<string>().GetHashCode(),
             LuaValueType.Number => Read<double>().GetHashCode(),
-            LuaValueType.Function => Read<LuaFunction>().GetHashCode(),
-            LuaValueType.Thread => Read<LuaThread>().GetHashCode(),
-            LuaValueType.Table => Read<LuaTable>().GetHashCode(),
-            LuaValueType.UserData => referenceValue == null ? 0 : referenceValue.GetHashCode(),
+            LuaValueType.Function or LuaValueType.Thread or LuaValueType.Table or LuaValueType.UserData => referenceValue!.GetHashCode(),
             _ => 0,
         };
 

+ 1 - 1
src/Lua/Standard/Mathematics/RandomFunction.cs

@@ -10,7 +10,7 @@ public sealed class RandomFunction : LuaFunction
 
     protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
     {
-        var rand = context.State.Environment[RandomInstanceKey].Read<Random>();
+        var rand = context.State.Environment[RandomInstanceKey].Read<LuaUserData<Random>>().Value;
 
         if (context.ArgumentCount == 0)
         {

+ 1 - 1
src/Lua/Standard/Mathematics/RandomSeedFunction.cs

@@ -10,7 +10,7 @@ public sealed class RandomSeedFunction : LuaFunction
     protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
     {
         var arg0 = context.ReadArgument<double>(0);
-        context.State.Environment[RandomFunction.RandomInstanceKey] = new(new Random((int)BitConverter.DoubleToInt64Bits(arg0)));
+        context.State.Environment[RandomFunction.RandomInstanceKey] = new LuaUserData<Random>(new Random((int)BitConverter.DoubleToInt64Bits(arg0)));
         return new(0);
     }
 }

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

@@ -96,7 +96,7 @@ public static class OpenLibExtensions
 
     public static void OpenMathLibrary(this LuaState state)
     {
-        state.Environment[RandomFunction.RandomInstanceKey] = new(new Random());
+        state.Environment[RandomFunction.RandomInstanceKey] = new LuaUserData<Random>(new Random());
         state.Environment["pi"] = Math.PI;
         state.Environment["huge"] = double.PositiveInfinity;