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(); } } } }