Handling for caching pointers to userdata objects
This commit is contained in:
parent
ae2080f145
commit
e44432c068
|
@ -16,8 +16,8 @@ namespace PorygonSharp.EvalValues
|
|||
if (type.IsEnum && !type.IsGenericParameter)
|
||||
{
|
||||
var typeHash = UserDataHandler.GetTypeId(type);
|
||||
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
|
||||
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
|
||||
var ptr = ObjectEvalValueHandler.GetObjectPtr(o);
|
||||
return new EvalValue(CreateUserDataEvalValue(typeHash, ptr));
|
||||
}
|
||||
var typeCode = Type.GetTypeCode(type);
|
||||
switch (typeCode)
|
||||
|
@ -48,8 +48,8 @@ namespace PorygonSharp.EvalValues
|
|||
throw new Exception($"Type is not registered for use: {type.FullName}");
|
||||
}
|
||||
var typeHash = UserDataHandler.GetTypeId(type);
|
||||
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
|
||||
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
|
||||
var ptr = ObjectEvalValueHandler.GetObjectPtr(o);
|
||||
return new EvalValue(CreateUserDataEvalValue(typeHash, ptr));
|
||||
default:
|
||||
throw new Exception($"Type {type} is not currently available as EvalValue");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PorygonSharp.EvalValues
|
||||
|
@ -21,9 +20,8 @@ namespace PorygonSharp.EvalValues
|
|||
var valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
|
||||
if (valueType == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
var parentHandle = GCHandle.Alloc(list, GCHandleType.WeakTrackResurrection);
|
||||
ParentCollection = GCHandle.ToIntPtr(parentHandle);
|
||||
|
||||
ParentCollection = ObjectEvalValueHandler.GetObjectPtr(list);
|
||||
Getter = Marshal.GetFunctionPointerForDelegate(new GetterDelegate((parent, index) =>
|
||||
{
|
||||
var val = new EvalValue(index).EvaluateInteger();
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -160,14 +160,12 @@ namespace PorygonSharp.UserData
|
|||
if (_implicitCasts.TryGetValue(expectedType, out var func))
|
||||
{
|
||||
var castVal = func.Invoke(null, new[] {obj});
|
||||
var handle = GCHandle.Alloc(castVal, GCHandleType.WeakTrackResurrection);
|
||||
return GCHandle.ToIntPtr(handle);
|
||||
return EvalValueCreator.CreateValue(castVal).GetPointer();
|
||||
}
|
||||
if (_explicitCasts.TryGetValue(expectedType, out func))
|
||||
{
|
||||
var castVal = func.Invoke(null, new[] {obj});
|
||||
var handle = GCHandle.Alloc(castVal, GCHandleType.WeakTrackResurrection);
|
||||
return GCHandle.ToIntPtr(handle);
|
||||
return EvalValueCreator.CreateValue(castVal).GetPointer();
|
||||
}
|
||||
throw new Exception("Invalid cast kind");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue