2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-26 21:13:13 +00:00

DynamicMethod Nullable Events

This commit is contained in:
2022-04-01 15:47:19 +03:00
parent 20fcaba518
commit 2809d389bd
7 changed files with 293 additions and 234 deletions

View File

@ -15,6 +15,7 @@ using Esiur.Proxy;
using Esiur.Core;
using System.Text.Json;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection.Emit;
namespace Esiur.Resource;
@ -607,6 +608,27 @@ public class Instance
}
}
internal void EmitResourceEventByIndex(byte eventIndex, object value)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
var eventTemplate = template.GetEventTemplateByIndex(eventIndex);
EventOccurred?.Invoke(new EventOccurredInfo(res, eventTemplate, value));
}
}
internal void EmitCustomResourceEventByIndex(object issuer, Func<Session, bool> receivers, byte eventIndex, object value)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
var eventTemplate = template.GetEventTemplateByIndex(eventIndex);
CustomEventOccurred?.Invoke(new CustomEventOccurredInfo(res, eventTemplate, receivers, issuer, value));
}
}
/// <summary>
/// Get the value of a given property by name.
/// </summary>
@ -844,6 +866,13 @@ public class Instance
/// </summary>
public AutoList<IPermissionsManager, Instance> Managers => managers;
public void CallMeTest(Instance ins, int? val) =>
ins.EmitResourceEventByIndex(201, val);
public void CallMeTest2(Instance instance, object issuer, Func<Session, bool> receivers, int? val) =>
instance.EmitCustomResourceEventByIndex(issuer, receivers, 201, val);
/// <summary>
/// Create new instance.
/// </summary>
@ -893,10 +922,11 @@ public class Instance
#endif
var emitEventByIndexMethod = GetType().GetMethod("EmitResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic);
var emitCustomEventByIndexMethod = GetType().GetMethod("EmitCustomResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var evt in template.Events)
{
//if (evt.EventHandlerType != typeof(ResourceEventHandler))
// continue;
if (evt.EventInfo == null)
continue;
@ -906,21 +936,51 @@ public class Instance
if (eventGenericType == typeof(ResourceEventHandler<>))
{
// var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
// if (ca.Length == 0)
// continue;
var dm = new DynamicMethod("_", null,
new Type[] {typeof(Instance), evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },
typeof(Instance).Module, true);
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt, args);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, (int)evt.Index);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]);
il.Emit(OpCodes.Callvirt, emitEventByIndexMethod);
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ret);
var proxyDelegate= dm.CreateDelegate(evt.EventInfo.EventHandlerType, this);
//ResourceEventHandler<object> proxyDelegate = new ResourceEventHandler<object>((args) => EmitResourceEvent(evt, args));
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
}
else if (eventGenericType == typeof(CustomResourceEventHandler<>))
{
//var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
//if (ca.Length == 0)
// continue;
var dm = new DynamicMethod("_", null,
new Type[] { typeof(Instance), typeof(object), typeof(Func<Session, bool>),
evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },
typeof(Instance).Module, true);
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldc_I4, (int)evt.Index);
il.Emit(OpCodes.Ldarg_3);
il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]);
il.Emit(OpCodes.Callvirt, emitCustomEventByIndexMethod);
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ret);
var proxyDelegate = dm.CreateDelegate(evt.EventInfo.EventHandlerType, this);
//CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
}