Pointers are headache

This commit is contained in:
Alessandro Proto 2023-02-12 20:03:31 +01:00
parent 33037a40fc
commit 1ca007b8d5
2 changed files with 53 additions and 28 deletions

View file

@ -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<nint, object> _objects = new();
private static IGame _game;
public ObjectManager(IGame game)
{
_game = game;
_game.EventEmitter.OnClose += OnClose;
}
public static void PushObject<T>(Lua L, T obj)
public static unsafe void PushObject<T>(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<T>(Lua L, int index, bool freeGCHandle = true)
public static unsafe T ToObject<T>(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];*/
if (freeGCHandle)
_objects.Remove(data, out _);
var p = (nint*)L.ToUserData(index);
var op = *p;
var handle = GCHandle.FromIntPtr(op);
return reference;
var reference = handle.Target;
if (reference == null)
return default(T);
T value;
try
{
value = (T)reference;
}
catch (Exception ex)
{
value = default;
}
public static T CheckObject<T>(Lua L, int argument, string typeName, bool freeGCHandle = true)
if (freeGCHandle)
handle.Free();
return value;
}
public static unsafe T CheckObject<T>(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;
}
}

View file

@ -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);