Skip to content

Commit

Permalink
Use IExecutor for events
Browse files Browse the repository at this point in the history
  • Loading branch information
Tides committed Jan 24, 2024
1 parent f761e26 commit b265481
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 75 deletions.
69 changes: 0 additions & 69 deletions Obsidian/Events/MinecraftEvent.cs

This file was deleted.

42 changes: 42 additions & 0 deletions Obsidian/Events/MinecraftEventExecutor.Delegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Microsoft.Extensions.Logging;
using Obsidian.Plugins;
using Obsidian.Utilities.Interfaces;
using System.Reflection;

namespace Obsidian.Events;
internal readonly struct MinecraftEventDelegateExecutor : IEventExecutor
{
public required Type EventType { get; init; }

public required Priority Priority { get; init; }

public required ILogger? Logger { get; init; }

public PluginContainer? PluginContainer { get; init; }

public required Delegate MethodDelegate { get; init; }

public ParameterInfo[] GetParameters() => this.MethodDelegate.Method.GetParameters();

public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>() where TAttribute : Attribute =>
this.MethodDelegate.Method.GetCustomAttributes<TAttribute>();

//TODO PARAM INJECTIONS
public async ValueTask Execute(IServiceProvider serviceProvider, params object[]? methodParams)
{
if (this.MethodDelegate.Method.ReturnType == typeof(ValueTask))
{
await (ValueTask)this.MethodDelegate.DynamicInvoke(methodParams)!;
return;
}
else if (this.MethodDelegate.Method.ReturnType == typeof(Task))
{
await ((Task)this.MethodDelegate.DynamicInvoke(methodParams)!).ConfigureAwait(false);
return;
}

this.MethodDelegate.DynamicInvoke(methodParams);
}

public bool MatchParams(object[] args) => throw new NotImplementedException();
}
54 changes: 54 additions & 0 deletions Obsidian/Events/MinecraftEventExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;
using Obsidian.Plugins;
using Obsidian.Utilities.Interfaces;
using System.Diagnostics;
using System.Reflection;

namespace Obsidian.Events;
internal readonly struct MinecraftEventExecutor : IEventExecutor
{
public required Type EventType { get; init; }

public required ILogger Logger { get; init; }

public required Type ModuleType { get; init; }

public required PluginContainer? PluginContainer { get; init; }

public required Priority Priority { get; init; }

public required ObjectFactory ModuleFactory { get; init; }

public required ObjectMethodExecutor MethodExecutor { get; init; }

//TODO PARAM INJECTION
public async ValueTask Execute(IServiceProvider serviceProvider, params object[]? methodParams)
{
var module = this.ModuleFactory!.Invoke(this.PluginContainer?.ServiceScope.ServiceProvider
?? serviceProvider, null);//Will inject services through constructor

this.PluginContainer?.InjectServices(this.Logger, module); //inject through attribute

if (this.MethodExecutor.MethodReturnType == typeof(ValueTask))
{
await (ValueTask)this.MethodExecutor.Execute(module, methodParams)!;
return;
}
else if (this.MethodExecutor.MethodReturnType == typeof(Task))
{
await ((Task)this.MethodExecutor.Execute(module, methodParams)!).ConfigureAwait(false);
return;
}

this.MethodExecutor.Execute(module, methodParams);
}

public ParameterInfo[] GetParameters() => this.MethodExecutor.MethodParameters;

public IEnumerable<TAttribute> GetCustomAttributes<TAttribute>() where TAttribute : Attribute =>
this.MethodExecutor.MethodInfo.GetCustomAttributes<TAttribute>();

public bool MatchParams(object[] args) => this.GetParameters().Length - 1 == args.Length;
}
13 changes: 7 additions & 6 deletions Obsidian/Services/EventDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Obsidian.Events;
using Obsidian.Events.EventArgs;
using Obsidian.Plugins;
using Obsidian.Utilities.Interfaces;
using System.Collections.Frozen;
using System.Reflection;
using System.Runtime.CompilerServices;
Expand All @@ -21,7 +22,7 @@ public sealed class EventDispatcher : IDisposable

private readonly ILogger<EventDispatcher> logger;
private readonly IServiceProvider serviceProvider;
private readonly FrozenDictionary<string, List<MinecraftEvent>> registeredEvents;
private readonly FrozenDictionary<string, List<IEventExecutor>> registeredEvents;
private readonly FrozenDictionary<Type, string> eventNames;

public EventDispatcher(ILogger<EventDispatcher> logger, IServiceProvider serviceProvider)
Expand All @@ -33,7 +34,7 @@ public EventDispatcher(ILogger<EventDispatcher> logger, IServiceProvider service
.ToList();

//Temp workaround until we decide to expose this event
var dict = new Dictionary<string, List<MinecraftEvent>>()
var dict = new Dictionary<string, List<IEventExecutor>>()
{
{ "QueuePacket", [] }
};
Expand Down Expand Up @@ -73,7 +74,7 @@ public void RegisterEvents<TEventModule>(PluginContainer? pluginContainer) where
if (!this.registeredEvents.TryGetValue(this.eventNames[eventType], out var values))
continue;

values.Add(new()
values.Add(new MinecraftEventExecutor
{
EventType = eventType,
ModuleFactory = ActivatorUtilities.CreateFactory(eventModule, []),
Expand All @@ -93,7 +94,7 @@ public void RegisterEvent<TEventArgs>(PluginContainer pluginContainer, ValueTask
if (!this.registeredEvents.TryGetValue(this.eventNames[typeof(TEventArgs)], out var values))
return;

values.Add(new()
values.Add(new MinecraftEventDelegateExecutor
{
EventType = typeof(TEventArgs),
PluginContainer = pluginContainer,
Expand All @@ -111,7 +112,7 @@ public void RegisterEvent(PluginContainer? pluginContainer, Delegate handler, Pr
if (!this.registeredEvents.TryGetValue(this.eventNames[eventType], out var values))
return;

values.Add(new()
values.Add(new MinecraftEventDelegateExecutor
{
EventType = eventType,
PluginContainer = pluginContainer,
Expand Down Expand Up @@ -143,7 +144,7 @@ public void RegisterEvents(PluginContainer pluginContainer)
if (!this.registeredEvents.TryGetValue(this.eventNames[eventType], out var values))
continue;

values.Add(new()
values.Add(new MinecraftEventExecutor
{
EventType = eventType,
ModuleFactory = ActivatorUtilities.CreateFactory(eventModule, []),
Expand Down
7 changes: 7 additions & 0 deletions Obsidian/Utilities/Interfaces/IExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,10 @@ public interface IExecutor<TArg>

public ValueTask Execute(IServiceProvider serviceProvider, TArg arg, params object[]? methodParams);
}

public interface IEventExecutor : IExecutor
{
public Type EventType { get; init; }

public Priority Priority { get; init; }
}

0 comments on commit b265481

Please sign in to comment.