using System; using System.Reflection; using System.Runtime.InteropServices; using PorygonSharp.EvalValues; using PorygonSharp.Utilities; namespace PorygonSharp.UserData { internal class UserDataField { internal delegate IntPtr GetterDelegate(IntPtr ptr); internal delegate void SetterDelegate(IntPtr ptr, IntPtr val); protected delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size); protected GetterDelegate _getter; protected readonly SetterDelegate _setter; public UserDataField(FieldInfo field) { _getter = ptr => { var obj = GCHandle.FromIntPtr(ptr).Target; var value = field.GetValue(obj); return EvalValueCreator.CreateValue(value).GetPointer(); }; if (!field.IsInitOnly) { _setter = (ptr, val) => { var obj = GCHandle.FromIntPtr(ptr).Target; var evalValue = Caster.Cast(new EvalValue(val), field.FieldType); field.SetValue(obj, evalValue); }; } } public UserDataField(PropertyInfo property) { if (property.GetGetMethod(false) != null) { _getter = ptr => { var obj = GCHandle.FromIntPtr(ptr).Target; var value = property.GetValue(obj); return EvalValueCreator.CreateValue(value).GetPointer(); }; } if (property.GetSetMethod(false) != null) { _setter = (ptr, val) => { var obj = GCHandle.FromIntPtr(ptr).Target; var evalValue = Caster.Cast(new EvalValue(val), property.PropertyType); property.SetValue(obj, evalValue); }; } } protected UserDataField(){} public UserDataField(GetterDelegate getter, SetterDelegate setter) { _getter = getter; _setter = setter; } internal IntPtr GetGetterPointer() { return _getter == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(_getter); } internal IntPtr GetSetterPointer() { return _setter == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(_setter); } } }