47 lines
1.6 KiB
C#
47 lines
1.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using PorygonSharp.UserData;
|
|
using PorygonSharp.Utilities;
|
|
|
|
namespace PorygonSharp.EvalValues
|
|
{
|
|
public class DelegateEvalValue : EvalValue
|
|
{
|
|
private delegate IntPtr InvokeDelegate(IntPtr _, IntPtr options,
|
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int parameterCount);
|
|
|
|
private readonly Delegate _delegate;
|
|
private readonly InvokeDelegate _handler;
|
|
private readonly IntPtr _funcPtr;
|
|
|
|
public DelegateEvalValue(Delegate del)
|
|
{
|
|
_delegate = del;
|
|
_handler = Invoke;
|
|
_funcPtr = Marshal.GetFunctionPointerForDelegate(_handler);
|
|
Handle = EvalValueCreator.CreateFunctionEvalValue(_funcPtr, IntPtr.Zero);
|
|
}
|
|
|
|
private IntPtr Invoke(IntPtr _, IntPtr options, IntPtr[] parPtrs, int parameterCount)
|
|
{
|
|
var parameters = new object[parameterCount];
|
|
var parametersTypes = _delegate.Method.GetParameters().Select(x => x.ParameterType).ToArray();
|
|
for (var i = 0; i < parameterCount; i++)
|
|
{
|
|
var val = new EvalValue(parPtrs[i]);
|
|
parameters[i] = Caster.Cast(val, parametersTypes[i]);
|
|
}
|
|
|
|
try
|
|
{
|
|
var result = _delegate.DynamicInvoke(parameters);
|
|
return new UserDataReturnValue(EvalValueCreator.CreateValue(result)).GetPointer();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new UserDataReturnValue(e.ToString()).GetPointer();
|
|
}
|
|
}
|
|
}
|
|
} |