From 1ca007b8d5e4a70a4e2b60839ff7cb44d802151b Mon Sep 17 00:00:00 2001 From: Alessandro Proto Date: Sun, 12 Feb 2023 20:03:31 +0100 Subject: [PATCH] Pointers are headache --- Capy64/Runtime/ObjectManager.cs | 79 +++++++++++++++++++---------- Capy64/Runtime/Objects/GPUBuffer.cs | 2 +- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/Capy64/Runtime/ObjectManager.cs b/Capy64/Runtime/ObjectManager.cs index bd80b3c..bfd34f3 100644 --- a/Capy64/Runtime/ObjectManager.cs +++ b/Capy64/Runtime/ObjectManager.cs @@ -1,4 +1,5 @@ using Capy64.API; +using Capy64.Runtime.Libraries; using KeraLua; using System; using System.Collections.Concurrent; @@ -13,16 +14,13 @@ namespace Capy64.Runtime; public class ObjectManager : IPlugin { - private static ConcurrentDictionary _objects = new(); - private static IGame _game; public ObjectManager(IGame game) { _game = game; - _game.EventEmitter.OnClose += OnClose; } - public static void PushObject(Lua L, T obj) + public static unsafe void PushObject(Lua L, T obj) { if (obj == null) { @@ -30,52 +28,79 @@ public class ObjectManager : IPlugin return; } - var p = L.NewUserData(1); - _objects[p] = obj; + var p = (nint*)L.NewUserData(sizeof(nint)); + var handle = GCHandle.Alloc(obj); + var op = GCHandle.ToIntPtr(handle); + *p = op; + //_objects[p] = obj; } - public static T ToObject(Lua L, int index, bool freeGCHandle = true) + public static unsafe T ToObject(Lua L, int index, bool freeGCHandle = true) { if (L.IsNil(index) || !L.IsUserData(index)) return default(T); - var data = L.ToUserData(index); - if (data == IntPtr.Zero) + /*if (p == IntPtr.Zero) return default(T); - if (!_objects.ContainsKey(data)) + /*if (!_objects.ContainsKey(data)) return default(T); - var reference = (T)_objects[data]; + var reference = (T)_objects[data];*/ + + var p = (nint*)L.ToUserData(index); + var op = *p; + var handle = GCHandle.FromIntPtr(op); + + var reference = handle.Target; + if (reference == null) + return default(T); + + T value; + try + { + value = (T)reference; + } + catch (Exception ex) + { + value = default; + } if (freeGCHandle) - _objects.Remove(data, out _); + handle.Free(); - return reference; + return value; } - public static T CheckObject(Lua L, int argument, string typeName, bool freeGCHandle = true) + public static unsafe T CheckObject(Lua L, int argument, string typeName, bool freeGCHandle = true) { if (L.IsNil(argument) || !L.IsUserData(argument)) return default(T); - IntPtr data = L.CheckUserData(argument, typeName); - if (data == IntPtr.Zero) + var p = (nint*)L.CheckUserData(argument, typeName); + var op = *p; + var handle = GCHandle.FromIntPtr(op); + + if (!handle.IsAllocated) + return default; + + var reference = handle.Target; + if (reference == null) return default(T); - if (!_objects.ContainsKey(data)) - return default(T); - - var reference = (T)_objects[data]; + T value; + try + { + value = (T)reference; + } + catch (Exception ex) + { + value = default; + } if (freeGCHandle) - _objects.Remove(data, out _); + handle.Free(); - return reference; - } - - private void OnClose(object sender, EventArgs e) - { - _objects.Clear(); + return value; } } diff --git a/Capy64/Runtime/Objects/GPUBuffer.cs b/Capy64/Runtime/Objects/GPUBuffer.cs index 07f95a3..a481b8a 100644 --- a/Capy64/Runtime/Objects/GPUBuffer.cs +++ b/Capy64/Runtime/Objects/GPUBuffer.cs @@ -165,7 +165,7 @@ public class GPUBuffer : IPlugin private static unsafe int LM_ToString(IntPtr state) { var L = Lua.FromIntPtr(state); - var buffer = ToBuffer(L); + var buffer = ToBuffer(L, false); if (buffer is not null) { L.PushString("GPUBuffer ({0:X})", (ulong)&buffer);