@@ -9,27 +9,27 @@ namespace Lagrange.Core.Events;
99public class EventInvoker ( BotContext context ) : IDisposable
1010{
1111 private const string Tag = nameof ( EventInvoker ) ;
12-
12+
1313 private readonly Dictionary < Type , Action < BotContext , EventBase > > _actions = new ( ) ;
14-
14+
1515 private readonly Dictionary < Type , Func < BotContext , EventBase , Task > > _asyncActions = new ( ) ;
1616
1717 public delegate void LagrangeEventHandler < in TEvent > ( BotContext context , TEvent e ) where TEvent : EventBase ;
18-
18+
1919 public delegate Task LagrangeAsyncEventHandler < in TEvent > ( BotContext context , TEvent e ) where TEvent : EventBase ;
20-
20+
2121 [ UnconditionalSuppressMessage ( "AOT" , "IL3050" , Justification = "DynamicMethod is not supported in AOT, but this if block is not executed in AOT" ) ]
2222 public void RegisterEvent < TEvent > ( LagrangeEventHandler < TEvent > handler ) where TEvent : EventBase
2323 {
2424 Debug . Assert ( ! handler . Method . IsStatic ) ;
2525 ArgumentNullException . ThrowIfNull ( handler . Target ) ;
26-
26+
2727 if ( RuntimeFeature . IsDynamicCodeSupported )
2828 {
2929 Type [ ] args = [ handler . Target . GetType ( ) , typeof ( BotContext ) , typeof ( EventBase ) ] ;
3030 var method = new DynamicMethod ( $ "EventInvoker_{ typeof ( TEvent ) } ", typeof ( void ) , args , typeof ( EventInvoker ) , true ) ;
3131 var il = method . GetILGenerator ( ) ;
32-
32+
3333 il . Emit ( OpCodes . Ldarg_0 ) ; // [Target]
3434 il . Emit ( OpCodes . Ldarg_1 ) ; // [Target, BotContext]
3535 il . Emit ( OpCodes . Ldarg_2 ) ; // [Target, BotContext, EventBase]
@@ -44,26 +44,26 @@ public void RegisterEvent<TEvent>(LagrangeEventHandler<TEvent> handler) where TE
4444 _actions [ typeof ( TEvent ) ] = ( ctx , e ) => handler ( ctx , ( TEvent ) e ) ;
4545 }
4646 }
47-
47+
4848 [ UnconditionalSuppressMessage ( "AOT" , "IL3050" , Justification = "DynamicMethod is not supported in AOT, but this if block is not executed in AOT" ) ]
4949 public void RegisterEvent < TEvent > ( LagrangeAsyncEventHandler < TEvent > handler ) where TEvent : EventBase
5050 {
5151 Debug . Assert ( ! handler . Method . IsStatic ) ;
5252 ArgumentNullException . ThrowIfNull ( handler . Target ) ;
53-
53+
5454 if ( RuntimeFeature . IsDynamicCodeSupported )
5555 {
5656 Type [ ] args = [ handler . Target . GetType ( ) , typeof ( BotContext ) , typeof ( EventBase ) ] ;
5757 var method = new DynamicMethod ( $ "EventInvoker_{ typeof ( TEvent ) } ", typeof ( Task ) , args , typeof ( EventInvoker ) , true ) ;
5858 var il = method . GetILGenerator ( ) ;
59-
59+
6060 il . Emit ( OpCodes . Ldarg_0 ) ; // [Target]
6161 il . Emit ( OpCodes . Ldarg_1 ) ; // [Target, BotContext]
6262 il . Emit ( OpCodes . Ldarg_2 ) ; // [Target, BotContext, EventBase]
6363 il . Emit ( OpCodes . Castclass , typeof ( TEvent ) ) ; // [Target, BotContext, TEvent]
6464 il . Emit ( OpCodes . Callvirt , handler . Method ) ; // [Task]
6565 il . Emit ( OpCodes . Ret ) ; // []
66-
66+
6767 _asyncActions [ typeof ( TEvent ) ] = method . CreateDelegate < Func < BotContext , EventBase , Task > > ( handler . Target ) ;
6868 }
6969 else
@@ -72,10 +72,18 @@ public void RegisterEvent<TEvent>(LagrangeAsyncEventHandler<TEvent> handler) whe
7272 }
7373 }
7474
75+ public void UnregisterEvent < TEvent > ( ) where TEvent : EventBase
76+ {
77+ Type type = typeof ( TEvent ) ;
78+
79+ _actions . Remove ( type ) ;
80+ _asyncActions . Remove ( type ) ;
81+ }
82+
7583 internal void PostEvent < T > ( T @event ) where T : EventBase => Task . Run ( async ( ) =>
7684 {
7785 await context . EventContext . HandleOutgoingEvent ( @event ) ;
78-
86+
7987 try
8088 {
8189 if ( _actions . TryGetValue ( typeof ( T ) , out var @delegate ) )
@@ -89,7 +97,7 @@ internal void PostEvent<T>(T @event) where T : EventBase => Task.Run(async () =>
8997 }
9098 catch ( Exception ex ) when ( ex is not OperationCanceledException )
9199 {
92- if ( typeof ( T ) == typeof ( BotLogEvent ) )
100+ if ( typeof ( T ) == typeof ( BotLogEvent ) )
93101 {
94102 Console . WriteLine ( $ "Failed to post event: { @event } ") ;
95103 return ;
@@ -99,6 +107,7 @@ internal void PostEvent<T>(T @event) where T : EventBase => Task.Run(async () =>
99107 }
100108 } ) ;
101109
110+
102111 public void Dispose ( )
103112 {
104113 _actions . Clear ( ) ;
0 commit comments