M Core/NosSmooth.Game/Events/Core/EventDispatcher.cs => Core/NosSmooth.Game/Events/Core/EventDispatcher.cs +23 -3
@@ 36,10 36,30 @@ public class EventDispatcher
where TEvent : IGameEvent
{
using var scope = _provider.CreateScope();
- var results = await Task.WhenAll(
+
+ async Task<Result> SafeCall(Func<Task<Result>> result)
+ {
+ try
+ {
+ return await result();
+ }
+ catch (Exception e)
+ {
+ return e;
+ }
+ }
+
+ var results = await Task.WhenAll
+ (
scope.ServiceProvider
.GetServices<IGameResponder<TEvent>>()
- .Select(responder => responder.Respond(@event, ct))
+ .Select(responder => SafeCall(() => responder.Respond(@event, ct)))
+ .Concat
+ (
+ scope.ServiceProvider
+ .GetServices<IEveryGameResponder>()
+ .Select(responder => SafeCall(() => responder.Respond(@event, ct)))
+ )
);
return results.Length switch
@@ 49,4 69,4 @@ public class EventDispatcher
_ => new AggregateError(results.Cast<IResult>().ToArray()),
};
}
-}
+}<
\ No newline at end of file
M Core/NosSmooth.Game/Events/Core/IGameResponder.cs => Core/NosSmooth.Game/Events/Core/IGameResponder.cs +18 -2
@@ 24,10 24,26 @@ public interface IGameResponder<TEvent> : IGameResponder
where TEvent : IGameEvent
{
/// <summary>
- /// Respond to the given packet.
+ /// Respond to the given event.
/// </summary>
- /// <param name="gameEvent">The packet to respond to.</param>
+ /// <param name="gameEvent">The event to respond to.</param>
/// <param name="ct">The cancellation token for cancelling the operation.</param>
/// <returns>A result that may or may not have succeeded.</returns>
public Task<Result> Respond(TEvent gameEvent, CancellationToken ct = default);
}
+
+/// <summary>
+/// Represents interface for classes that respond to every game event.
+/// Responds to any game event.
+/// </summary>
+public interface IEveryGameResponder
+{
+ /// <summary>
+ /// Respond to any event.
+ /// </summary>
+ /// <param name="gameEvent">The event to respond to.</param>
+ /// <param name="ct">The cancellation token for cancelling the operation.</param>
+ /// <typeparam name="TEvent">The current event type.</typeparam>
+ /// <returns>A result that may or may not have succeeded.</returns>
+ public Task<Result> Respond<TEvent>(TEvent gameEvent, CancellationToken ct = default);
+}<
\ No newline at end of file