diff --git a/Dockerfile b/Dockerfile
index 49fddc9c..30666079 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,10 +8,8 @@ WORKDIR /source
# Copy csproj and restore.
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
-COPY src/Impostor.Server.Api/Impostor.Server.Api.csproj ./src/Impostor.Server.Api/Impostor.Server.Api.csproj
-COPY src/Impostor.Server.Hazel/Impostor.Server.Hazel.csproj ./src/Impostor.Server.Hazel/Impostor.Server.Hazel.csproj
-COPY src/Impostor.Shared/Impostor.Shared.csproj ./src/Impostor.Shared/Impostor.Shared.csproj
-COPY submodules/Hazel-Networking/Hazel/Hazel.csproj ./submodules/Hazel-Networking/Hazel/Hazel.csproj
+COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
+COPY src/Impostor.Hazel/Impostor.Hazel.csproj ./src/Impostor.Hazel/Impostor.Hazel.csproj
RUN case "$TARGETARCH" in \
amd64) NETCORE_PLATFORM='linux-x64';; \
@@ -20,13 +18,10 @@ RUN case "$TARGETARCH" in \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
- dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server.Api/Impostor.Server.Api.csproj && \
- dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server.Hazel/Impostor.Server.Hazel.csproj && \
- dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Shared/Impostor.Shared.csproj && \
- dotnet restore -r "$NETCORE_PLATFORM" ./submodules/Hazel-Networking/Hazel/Hazel.csproj
+ dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj && \
+ dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Impostor.Hazel.csproj
# Copy everything else.
-COPY submodules/. ./submodules/
COPY src/. ./src/
RUN case "$TARGETARCH" in \
amd64) NETCORE_PLATFORM='linux-x64';; \
diff --git a/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs b/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs
index a3739465..b31d2d1a 100644
--- a/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs
+++ b/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs
@@ -30,10 +30,5 @@ namespace Impostor.Api.Events
/// If set to true, the listener will be called regardless of the .
///
public bool IgnoreCancelled { get; set; }
-
- ///
- /// The order of the priority.
- ///
- public int PriorityOrder { get; set; } = 100;
}
}
\ No newline at end of file
diff --git a/src/Impostor.Api/Events/Managers/IEventManager.cs b/src/Impostor.Api/Events/Managers/IEventManager.cs
index a9d433bf..07a7f7cf 100644
--- a/src/Impostor.Api/Events/Managers/IEventManager.cs
+++ b/src/Impostor.Api/Events/Managers/IEventManager.cs
@@ -5,15 +5,6 @@ namespace Impostor.Api.Events.Managers
{
public interface IEventManager
{
- ///
- /// Register a temporary event listener.
- ///
- /// Event callback.
- /// Disposable that unregisters the callback from the event manager.
- /// Type of the event.
- IDisposable Register(Func callback)
- where TEvent : IEvent;
-
///
/// Register a temporary event listener.
///
diff --git a/src/Impostor.Server/Events/EventHandler.cs b/src/Impostor.Server/Events/EventHandler.cs
index e4582ca7..190f7f39 100644
--- a/src/Impostor.Server/Events/EventHandler.cs
+++ b/src/Impostor.Server/Events/EventHandler.cs
@@ -1,10 +1,11 @@
using Impostor.Api.Events;
+using Impostor.Server.Events.Register;
namespace Impostor.Server.Events
{
internal readonly struct EventHandler
{
- public EventHandler(IEventListener o, RegisteredEventListener listener)
+ public EventHandler(IEventListener o, IRegisteredEventListener listener)
{
Object = o;
Listener = listener;
@@ -12,9 +13,9 @@ namespace Impostor.Server.Events
public IEventListener Object { get; }
- public RegisteredEventListener Listener { get; }
+ public IRegisteredEventListener Listener { get; }
- public void Deconstruct(out IEventListener o, out RegisteredEventListener listener)
+ public void Deconstruct(out IEventListener o, out IRegisteredEventListener listener)
{
o = Object;
listener = Listener;
diff --git a/src/Impostor.Server/Events/EventManager.cs b/src/Impostor.Server/Events/EventManager.cs
index 05a3e70d..504fcd0c 100644
--- a/src/Impostor.Server/Events/EventManager.cs
+++ b/src/Impostor.Server/Events/EventManager.cs
@@ -6,30 +6,20 @@ using System.Reflection;
using System.Threading.Tasks;
using Impostor.Api.Events;
using Impostor.Api.Events.Managers;
+using Impostor.Server.Events.Register;
using Microsoft.Extensions.DependencyInjection;
namespace Impostor.Server.Events
{
internal class EventManager : IEventManager
{
- private readonly ConcurrentDictionary _temporaryEventListeners;
+ private readonly ConcurrentDictionary _temporaryEventListeners;
private readonly IServiceProvider _serviceProvider;
public EventManager(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
- _temporaryEventListeners = new ConcurrentDictionary();
- }
-
- ///
- public IDisposable Register(Func callback)
- where TEvent : IEvent
- {
- var register = (TemporaryEventRegister) _temporaryEventListeners.GetOrAdd(
- typeof(TEvent),
- _ => new TemporaryEventRegister());
-
- return register.Add(callback);
+ _temporaryEventListeners = new ConcurrentDictionary();
}
///
@@ -41,17 +31,23 @@ namespace Impostor.Server.Events
throw new ArgumentNullException(nameof(listener));
}
- var registerMethod = typeof(EventManager).GetMethod(nameof(RegisterListenerImpl), BindingFlags.Instance | BindingFlags.NonPublic);
- var methods = RegisteredEventListener.FromType(listener.GetType());
- var disposes = new IDisposable[methods.Count];
+ var eventListeners = RegisteredEventListener.FromType(listener.GetType());
+ var disposes = new IDisposable[eventListeners.Count];
- for (var i = 0; i < methods.Count; i++)
+ foreach (var eventListener in eventListeners)
{
- var method = methods[i];
+ IRegisteredEventListener wrappedEventListener = new WrappedRegisteredEventListener(eventListener, listener);
- disposes[i] = (IDisposable) registerMethod!
- .MakeGenericMethod(method.EventType)
- .Invoke(this, new object[] { listener, method, invoker });
+ if (invoker != null)
+ {
+ wrappedEventListener = new InvokedRegisteredEventListener(wrappedEventListener, invoker);
+ }
+
+ var register = _temporaryEventListeners.GetOrAdd(
+ wrappedEventListener.EventType,
+ _ => new TemporaryEventRegister());
+
+ register.Add(wrappedEventListener);
}
return new MultiDisposable(disposes);
@@ -74,15 +70,11 @@ namespace Impostor.Server.Events
try
{
- foreach (var (handler, eventListener) in GetHandlers(scope.ServiceProvider))
+ foreach (var (handler, eventListener) in GetHandlers(scope.ServiceProvider)
+ .OrderByDescending(e => e.Listener.Priority))
{
await eventListener.InvokeAsync(handler, @event, scope.ServiceProvider);
}
-
- if (_temporaryEventListeners.TryGetValue(typeof(T), out var cb))
- {
- await ((TemporaryEventRegister) cb).CallAsync(scope.ServiceProvider, @event);
- }
}
finally
{
@@ -95,7 +87,7 @@ namespace Impostor.Server.Events
///
/// Current service provider.
/// The event listeners.
- private static IEnumerable GetHandlers(IServiceProvider services)
+ private IEnumerable GetHandlers(IServiceProvider services)
where TEvent : IEvent
{
foreach (var handler in services.GetServices())
@@ -112,14 +104,14 @@ namespace Impostor.Server.Events
yield return new EventHandler(handler, eventHandler);
}
}
- }
- private IDisposable RegisterListenerImpl(object obj, RegisteredEventListener listener, Func, Task> invoker = null)
- where TEvent : IEvent
- {
- return invoker == null
- ? Register((provider, @event) => listener.InvokeAsync(obj, @event, provider))
- : Register((provider, @event) => new ValueTask(invoker(() => listener.InvokeAsync(obj, @event, provider).AsTask())));
+ if (_temporaryEventListeners.TryGetValue(typeof(TEvent), out var cb))
+ {
+ foreach (var eventListener in cb.GetEventListeners())
+ {
+ yield return new EventHandler(null, eventListener);
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs
new file mode 100644
index 00000000..479a3f64
--- /dev/null
+++ b/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Threading.Tasks;
+using Impostor.Api.Events;
+
+namespace Impostor.Server.Events.Register
+{
+ internal interface IRegisteredEventListener
+ {
+ Type EventType { get; }
+
+ EventPriority Priority { get; }
+
+ ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider);
+ }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs
new file mode 100644
index 00000000..a21c3b1f
--- /dev/null
+++ b/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Threading.Tasks;
+using Impostor.Api.Events;
+
+namespace Impostor.Server.Events.Register
+{
+ internal class InvokedRegisteredEventListener : IRegisteredEventListener
+ {
+ private readonly IRegisteredEventListener _innerObject;
+ private readonly Func, Task> _invoker;
+
+ public InvokedRegisteredEventListener(IRegisteredEventListener innerObject, Func, Task> invoker)
+ {
+ _innerObject = innerObject;
+ _invoker = invoker;
+ }
+
+ public Type EventType => _innerObject.EventType;
+
+ public EventPriority Priority => _innerObject.Priority;
+
+ public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider)
+ {
+ return new ValueTask(_invoker(() => _innerObject.InvokeAsync(eventHandler, @event, provider).AsTask()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Events/RegisteredEventListener.cs b/src/Impostor.Server/Events/Register/RegisteredEventListener.cs
similarity index 98%
rename from src/Impostor.Server/Events/RegisteredEventListener.cs
rename to src/Impostor.Server/Events/Register/RegisteredEventListener.cs
index 80df9d8a..0c49a07c 100644
--- a/src/Impostor.Server/Events/RegisteredEventListener.cs
+++ b/src/Impostor.Server/Events/Register/RegisteredEventListener.cs
@@ -8,9 +8,9 @@ using System.Threading.Tasks;
using Impostor.Api.Events;
using Microsoft.Extensions.DependencyInjection;
-namespace Impostor.Server.Events
+namespace Impostor.Server.Events.Register
{
- internal class RegisteredEventListener
+ internal class RegisteredEventListener : IRegisteredEventListener
{
private static readonly ConcurrentDictionary Instances = new ConcurrentDictionary();
private readonly Func