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:
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user