Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 81 additions & 41 deletions EXILED/Exiled.Events/Features/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
namespace Exiled.Events.Features
{
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;

using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;

using MEC;

/// <summary>
Expand Down Expand Up @@ -219,74 +221,112 @@ public void InvokeSafely()
/// <inheritdoc cref="InvokeSafely"/>
internal void BlendedInvoke()
{
Registration[] innerEvent = this.innerEvent.ToArray();
AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray();
int count = innerEvent.Length + innerAsyncEvent.Length;
int eventIndex = 0, asyncEventIndex = 0;
int syncCount = innerEvent.Count;
int asyncCount = innerAsyncEvent.Count;

Registration[] localInnerEvent = ArrayPool<Registration>.Shared.Rent(syncCount);
AsyncRegistration[] localInnerAsyncEvent = ArrayPool<AsyncRegistration>.Shared.Rent(asyncCount);

int count = syncCount + asyncCount;

for (int i = 0; i < count; i++)
try
{
if (eventIndex < innerEvent.Length && (asyncEventIndex >= innerAsyncEvent.Length || innerEvent[eventIndex].priority >= innerAsyncEvent[asyncEventIndex].priority))
{
try
{
innerEvent[eventIndex].handler();
}
catch (Exception ex)
{
Log.Error($"Method \"{innerEvent[eventIndex].handler.Method.Name}\" of the class \"{innerEvent[eventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
innerEvent.CopyTo(localInnerEvent, 0);
innerAsyncEvent.CopyTo(localInnerAsyncEvent, 0);

eventIndex++;
}
else
int eventIndex = 0, asyncEventIndex = 0;

for (int i = 0; i < count; i++)
{
try
if (eventIndex < syncCount && (asyncEventIndex >= asyncCount || localInnerEvent[eventIndex].priority >= localInnerAsyncEvent[asyncEventIndex].priority))
{
Timing.RunCoroutine(innerAsyncEvent[asyncEventIndex].handler());
try
{
localInnerEvent[eventIndex].handler();
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerEvent[eventIndex].handler.Method.Name}\" of the class \"{localInnerEvent[eventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}

eventIndex++;
}
catch (Exception ex)
else
{
Log.Error($"Method \"{innerAsyncEvent[asyncEventIndex].handler.Method.Name}\" of the class \"{innerAsyncEvent[asyncEventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
Timing.RunCoroutine(localInnerAsyncEvent[asyncEventIndex].handler());
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerAsyncEvent[asyncEventIndex].handler.Method.Name}\" of the class \"{localInnerAsyncEvent[asyncEventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}

asyncEventIndex++;
}

asyncEventIndex++;
}
}
finally
{
ArrayPool<Registration>.Shared.Return(localInnerEvent, true);
ArrayPool<AsyncRegistration>.Shared.Return(localInnerAsyncEvent, true);
}
}

/// <inheritdoc cref="InvokeSafely"/>
internal void InvokeNormal()
{
Registration[] innerEvent = this.innerEvent.ToArray();
foreach (Registration registration in innerEvent)
int count = innerEvent.Count;
Registration[] localInnerEvent = ArrayPool<Registration>.Shared.Rent(count);

try
{
try
{
registration.handler();
}
catch (Exception ex)
innerEvent.CopyTo(localInnerEvent, 0);

for (int i = 0; i < count; i++)
{
Log.Error($"Method \"{registration.handler.Method.Name}\" of the class \"{registration.handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
localInnerEvent[i].handler();
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerEvent[i].handler.Method.Name}\" of the class \"{localInnerEvent[i].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
}
}
finally
{
ArrayPool<Registration>.Shared.Return(localInnerEvent, true);
}
}

/// <inheritdoc cref="InvokeSafely"/>
internal void InvokeAsync()
{
AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray();
foreach (AsyncRegistration registration in innerAsyncEvent)
int count = innerAsyncEvent.Count;
AsyncRegistration[] localInnerAsyncEvent = ArrayPool<AsyncRegistration>.Shared.Rent(count);

try
{
try
{
Timing.RunCoroutine(registration.handler());
}
catch (Exception ex)
innerAsyncEvent.CopyTo(localInnerAsyncEvent, 0);

for (int i = 0; i < count; i++)
{
Log.Error($"Method \"{registration.handler.Method.Name}\" of the class \"{registration.handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
Timing.RunCoroutine(localInnerAsyncEvent[i].handler());
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerAsyncEvent[i].handler.Method.Name}\" of the class \"{localInnerAsyncEvent[i].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
}
}
finally
{
ArrayPool<AsyncRegistration>.Shared.Return(localInnerAsyncEvent, true);
}
}
}
}
}
121 changes: 80 additions & 41 deletions EXILED/Exiled.Events/Features/Event{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
namespace Exiled.Events.Features
{
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;

using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;

using MEC;

/// <summary>
Expand Down Expand Up @@ -226,74 +228,111 @@ public void InvokeSafely(T arg)
/// <inheritdoc cref="InvokeSafely"/>
internal void BlendedInvoke(T arg)
{
Registration[] innerEvent = this.innerEvent.ToArray();
AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray();
int count = innerEvent.Length + innerAsyncEvent.Length;
int eventIndex = 0, asyncEventIndex = 0;
int syncCount = innerEvent.Count;
int asyncCount = innerAsyncEvent.Count;
Registration[] localInnerEvent = ArrayPool<Registration>.Shared.Rent(syncCount);
AsyncRegistration[] localInnerAsyncEvent = ArrayPool<AsyncRegistration>.Shared.Rent(asyncCount);

int count = syncCount + asyncCount;

for (int i = 0; i < count; i++)
try
{
if (eventIndex < innerEvent.Length && (asyncEventIndex >= innerAsyncEvent.Length || innerEvent[eventIndex].priority >= innerAsyncEvent[asyncEventIndex].priority))
{
try
{
innerEvent[eventIndex].handler(arg);
}
catch (Exception ex)
{
Log.Error($"Method \"{innerEvent[eventIndex].handler.Method.Name}\" of the class \"{innerEvent[eventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
innerEvent.CopyTo(localInnerEvent, 0);
innerAsyncEvent.CopyTo(localInnerAsyncEvent, 0);

eventIndex++;
}
else
int eventIndex = 0, asyncEventIndex = 0;

for (int i = 0; i < count; i++)
{
try
if (eventIndex < syncCount && (asyncEventIndex >= asyncCount || localInnerEvent[eventIndex].priority >= localInnerAsyncEvent[asyncEventIndex].priority))
{
Timing.RunCoroutine(innerAsyncEvent[asyncEventIndex].handler(arg));
try
{
localInnerEvent[eventIndex].handler(arg);
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerEvent[eventIndex].handler.Method.Name}\" of the class \"{localInnerEvent[eventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}

eventIndex++;
}
catch (Exception ex)
else
{
Log.Error($"Method \"{innerAsyncEvent[asyncEventIndex].handler.Method.Name}\" of the class \"{innerAsyncEvent[asyncEventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
Timing.RunCoroutine(localInnerAsyncEvent[asyncEventIndex].handler(arg));
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerAsyncEvent[asyncEventIndex].handler.Method.Name}\" of the class \"{localInnerAsyncEvent[asyncEventIndex].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}

asyncEventIndex++;
}

asyncEventIndex++;
}
}
finally
{
ArrayPool<Registration>.Shared.Return(localInnerEvent, true);
ArrayPool<AsyncRegistration>.Shared.Return(localInnerAsyncEvent, true);
}
}

/// <inheritdoc cref="InvokeSafely"/>
internal void InvokeNormal(T arg)
{
Registration[] innerEvent = this.innerEvent.ToArray();
foreach (Registration registration in innerEvent)
int count = innerEvent.Count;
Registration[] localInnerEvent = ArrayPool<Registration>.Shared.Rent(count);

try
{
try
{
registration.handler(arg);
}
catch (Exception ex)
innerEvent.CopyTo(localInnerEvent, 0);

for (int i = 0; i < count; i++)
{
Log.Error($"Method \"{registration.handler.Method.Name}\" of the class \"{registration.handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
localInnerEvent[i].handler(arg);
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerEvent[i].handler.Method.Name}\" of the class \"{localInnerEvent[i].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
}
}
finally
{
ArrayPool<Registration>.Shared.Return(localInnerEvent, true);
}
}

/// <inheritdoc cref="InvokeSafely"/>
internal void InvokeAsync(T arg)
{
AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray();
foreach (AsyncRegistration registration in innerAsyncEvent)
int count = innerAsyncEvent.Count;
AsyncRegistration[] localInnerAsyncEvent = ArrayPool<AsyncRegistration>.Shared.Rent(count);

try
{
try
{
Timing.RunCoroutine(registration.handler(arg));
}
catch (Exception ex)
innerAsyncEvent.CopyTo(localInnerAsyncEvent, 0);

for (int i = 0; i < count; i++)
{
Log.Error($"Method \"{registration.handler.Method.Name}\" of the class \"{registration.handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
try
{
Timing.RunCoroutine(localInnerAsyncEvent[i].handler(arg));
}
catch (Exception ex)
{
Log.Error($"Method \"{localInnerAsyncEvent[i].handler.Method.Name}\" of the class \"{localInnerAsyncEvent[i].handler.Method.ReflectedType.FullName}\" caused an exception when handling the event \"{GetType().FullName}\"\n{ex}");
}
}
}
finally
{
ArrayPool<AsyncRegistration>.Shared.Return(localInnerAsyncEvent, true);
}
}
}
}
}
Loading