diff --git a/Capy64/Runtime/Libraries/GPU.cs b/Capy64/Runtime/Libraries/GPU.cs index 97a5524..9806a86 100644 --- a/Capy64/Runtime/Libraries/GPU.cs +++ b/Capy64/Runtime/Libraries/GPU.cs @@ -397,7 +397,8 @@ public class GPU : IPlugin var buffer = new uint[_game.Width * _game.Height]; _game.Drawing.Canvas.GetData(buffer); - GPUBuffer.Push(L, buffer); + L.PushObject(buffer); + L.SetMetaTable(GPUBuffer.ObjectType); return 1; } @@ -406,11 +407,7 @@ public class GPU : IPlugin { var L = Lua.FromIntPtr(state); - var buffer = L.CheckObject(1, GPUBuffer.ObjectType, false); - if (buffer is null) - { - L.ArgumentError(1, GPUBuffer.ObjectType + " expected, got " + L.TypeName(L.Type(1))); - } + var buffer = GPUBuffer.CheckBuffer(L, false); _game.Drawing.Canvas.SetData(buffer); @@ -426,7 +423,8 @@ public class GPU : IPlugin var buffer = new uint[width * height]; - GPUBuffer.Push(L, buffer); + L.PushObject(buffer); + L.SetMetaTable(GPUBuffer.ObjectType); return 1; } @@ -435,11 +433,7 @@ public class GPU : IPlugin { var L = Lua.FromIntPtr(state); - var buffer = L.CheckObject(1, GPUBuffer.ObjectType, false); - if (buffer is null) - { - L.ArgumentError(1, GPUBuffer.ObjectType + " expected, got " + L.TypeName(L.Type(1))); - } + var buffer = GPUBuffer.CheckBuffer(L, false); var x = (int)L.CheckInteger(2) - 1; var y = (int)L.CheckInteger(3) - 1; @@ -490,7 +484,8 @@ public class GPU : IPlugin var data = new uint[texture.Width * texture.Height]; texture.GetData(data); - GPUBuffer.Push(L, data); + L.PushObject(data); + L.SetMetaTable(GPUBuffer.ObjectType); L.PushInteger(texture.Width); L.PushInteger(texture.Height); diff --git a/Capy64/Runtime/Objects/GPUBuffer.cs b/Capy64/Runtime/Objects/GPUBuffer.cs index 426c783..5995577 100644 --- a/Capy64/Runtime/Objects/GPUBuffer.cs +++ b/Capy64/Runtime/Objects/GPUBuffer.cs @@ -1,47 +1,82 @@ -using KeraLua; +using Capy64.API; +using KeraLua; using System; +using System.IO; namespace Capy64.Runtime.Objects; -public class GPUBuffer +public class GPUBuffer : IPlugin { public const string ObjectType = "GPUBuffer"; - public static void Push(Lua L, uint[] buffer) + private static LuaRegister[] MetaMethods = new LuaRegister[] { - L.PushObject(buffer); - - if (L.NewMetaTable(ObjectType)) + new() { - L.PushString("__index"); - L.PushCFunction(LM_Index); - L.SetTable(-3); + name = "__index", + function = LM_Index, + }, + new() + { + name = "__newindex", + function = LM_NewIndex, + }, + new() + { + name = "__len", + function = LM_Length, + }, + new() + { + name = "__gc", + function = LM_GC, + }, + new() + { + name = "__close", + function = LM_GC, + }, + new() + { + name = "__tostring", + function = LM_ToString, + }, - L.PushString("__newindex"); - L.PushCFunction(LM_NewIndex); - L.SetTable(-3); + new(), + }; - L.PushString("__len"); - L.PushCFunction(LM_Length); - L.SetTable(-3); + public void LuaInit(Lua L) + { + CreateMeta(L); + } - L.PushString("__gc"); - L.PushCFunction(LM_GC); - L.SetTable(-3); + public static void CreateMeta(Lua L) + { + L.NewMetaTable(ObjectType); + L.SetFuncs(MetaMethods, 0); + } - L.PushString("__close"); - L.PushCFunction(LM_GC); - L.SetTable(-3); + public static uint[] ToBuffer(Lua L, bool gc = false) + { + return L.CheckObject(1, ObjectType, gc); + } + + public static uint[] CheckBuffer(Lua L, bool gc = false) + { + var obj = L.CheckObject(1, ObjectType, gc); + if (obj is null) + { + L.Error("attempt to use a closed buffer"); + return null; } - - L.SetMetaTable(-2); + return (uint[])obj; } private static int LM_Index(IntPtr state) { var L = Lua.FromIntPtr(state); - var buffer = L.CheckObject(1, ObjectType, false); + var buffer = CheckBuffer(L, false); if (!L.IsInteger(2)) { @@ -74,7 +109,7 @@ public class GPUBuffer { var L = Lua.FromIntPtr(state); - var buffer = L.CheckObject(1, ObjectType, false); + var buffer = CheckBuffer(L, false); if (!L.IsInteger(2)) { return 0; @@ -111,7 +146,7 @@ public class GPUBuffer { var L = Lua.FromIntPtr(state); - L.CheckObject(1, ObjectType, true); + CheckBuffer(L, true); return 0; } @@ -120,10 +155,21 @@ public class GPUBuffer { var L = Lua.FromIntPtr(state); - var buffer = L.CheckObject(1, ObjectType, false); + var buffer = CheckBuffer(L, false); L.PushInteger(buffer.LongLength); return 1; } + + private static int LM_ToString(IntPtr state) + { + var L = Lua.FromIntPtr(state); + + var buffer = CheckBuffer(L, false); + + L.PushString(ObjectType); + + return 1; + } }