Skip to content

Commit 257fc1d

Browse files
committed
[Core] Support unregistering event handlers
1 parent cb243e2 commit 257fc1d

2 files changed

Lines changed: 22 additions & 13 deletions

File tree

Lagrange.Core/Events/EventInvoker.cs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,27 @@ namespace Lagrange.Core.Events;
99
public 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();

Lagrange.Core/Lagrange.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<LangVersion>13</LangVersion>
88
<IsAotCompatible>true</IsAotCompatible>
99

10-
<Version>2.0.1-beta</Version>
10+
<Version>2.0.2-beta</Version>
1111
</PropertyGroup>
1212

1313
<ItemGroup>

0 commit comments

Comments
 (0)