58 lines
2.2 KiB
C#
58 lines
2.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using PorygonSharp.EvalValues;
|
|
using PorygonSharp.Utilities;
|
|
|
|
namespace PorygonSharp.UserData
|
|
{
|
|
internal class UserDataFunctionField : UserDataField
|
|
{
|
|
public readonly IntPtr MethodPtr;
|
|
private readonly List<CallerDelegate> _callers;
|
|
public UserDataFunctionField(MethodInfo method, IntPtr methodPtr)
|
|
{
|
|
_getter = ptr =>
|
|
{
|
|
var funcPtr = Marshal.GetFunctionPointerForDelegate(_callers[0]);
|
|
var val = EvalValueCreator.FunctionEvalValue(funcPtr, ptr);
|
|
for (var i = 1; i < _callers.Count; i++)
|
|
{
|
|
funcPtr = Marshal.GetFunctionPointerForDelegate(_callers[i]);
|
|
RegisterFunctionEvalValueOption(val.GetPointer(), funcPtr, ptr);
|
|
}
|
|
return val.GetPointer();
|
|
};
|
|
MethodPtr = methodPtr;
|
|
_callers = new List<CallerDelegate>(){CreateCaller(method)};
|
|
}
|
|
|
|
private CallerDelegate CreateCaller(MethodInfo method)
|
|
{
|
|
var parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
|
|
return (parent, scriptOptions, parameters, size) =>
|
|
{
|
|
var evaluatedParameters = new object[size];
|
|
for (var i = 0; i < size; i++)
|
|
{
|
|
var eval = new EvalValue(parameters[i]);
|
|
evaluatedParameters[i] = Caster.Cast(eval, parameterTypes[i]);
|
|
}
|
|
|
|
var parentObj = GCHandle.FromIntPtr(parent).Target;
|
|
var result = method.Invoke(parentObj, evaluatedParameters);
|
|
return EvalValueCreator.CreateValue(result).GetPointer();
|
|
};
|
|
}
|
|
|
|
internal void RegisterOption(MethodInfo method)
|
|
{
|
|
_callers.Add(CreateCaller(method));
|
|
}
|
|
|
|
[DllImport("PorygonLang", EntryPoint = "RegisterFunctionEvalValueOption",CallingConvention = CallingConvention.Cdecl)]
|
|
internal static extern IntPtr RegisterFunctionEvalValueOption(IntPtr val, IntPtr func, IntPtr obj);
|
|
}
|
|
} |