PorygonSharp/PorygonSharp/EvalValues/ObjectEvalValueHandler.cs

44 lines
1.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace PorygonSharp.EvalValues
{
internal static class ObjectEvalValueHandler
{
private struct PtrObject
{
public readonly IntPtr Pointer;
public readonly WeakReference<object> WeakReference;
public PtrObject(IntPtr pointer, WeakReference<object> weakReference)
{
Pointer = pointer;
WeakReference = weakReference;
}
}
private static readonly Dictionary<int, PtrObject> CreatedPointers = new Dictionary<int, PtrObject>();
public static IntPtr GetObjectPtr(object o)
{
var hash = o.GetHashCode();
if (CreatedPointers.TryGetValue(hash, out var ptrObject))
{
if (ptrObject.WeakReference.TryGetTarget(out _))
{
return ptrObject.Pointer;
}
else
{
CreatedPointers.Remove(hash);
}
}
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
var ptr = GCHandle.ToIntPtr(handle);
ptrObject = new PtrObject(ptr, new WeakReference<object>(o));
CreatedPointers.Add(o.GetHashCode(), ptrObject);
return ptrObject.Pointer;
}
}
}