diff --git a/EXILED/Exiled.Events/Features/Event.cs b/EXILED/Exiled.Events/Features/Event.cs index bbbc638401..222f7ec930 100644 --- a/EXILED/Exiled.Events/Features/Event.cs +++ b/EXILED/Exiled.Events/Features/Event.cs @@ -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; /// @@ -219,74 +221,112 @@ public void 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.Shared.Rent(syncCount); + AsyncRegistration[] localInnerAsyncEvent = ArrayPool.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.Shared.Return(localInnerEvent, true); + ArrayPool.Shared.Return(localInnerAsyncEvent, true); + } } /// internal void InvokeNormal() { - Registration[] innerEvent = this.innerEvent.ToArray(); - foreach (Registration registration in innerEvent) + int count = innerEvent.Count; + Registration[] localInnerEvent = ArrayPool.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.Shared.Return(localInnerEvent, true); + } } /// internal void InvokeAsync() { - AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray(); - foreach (AsyncRegistration registration in innerAsyncEvent) + int count = innerAsyncEvent.Count; + AsyncRegistration[] localInnerAsyncEvent = ArrayPool.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.Shared.Return(localInnerAsyncEvent, true); + } } } -} +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Features/Event{T}.cs b/EXILED/Exiled.Events/Features/Event{T}.cs index 2d6252b91e..476f166ada 100644 --- a/EXILED/Exiled.Events/Features/Event{T}.cs +++ b/EXILED/Exiled.Events/Features/Event{T}.cs @@ -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; /// @@ -226,74 +228,111 @@ public void InvokeSafely(T arg) /// 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.Shared.Rent(syncCount); + AsyncRegistration[] localInnerAsyncEvent = ArrayPool.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.Shared.Return(localInnerEvent, true); + ArrayPool.Shared.Return(localInnerAsyncEvent, true); + } } /// internal void InvokeNormal(T arg) { - Registration[] innerEvent = this.innerEvent.ToArray(); - foreach (Registration registration in innerEvent) + int count = innerEvent.Count; + Registration[] localInnerEvent = ArrayPool.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.Shared.Return(localInnerEvent, true); + } } /// internal void InvokeAsync(T arg) { - AsyncRegistration[] innerAsyncEvent = this.innerAsyncEvent.ToArray(); - foreach (AsyncRegistration registration in innerAsyncEvent) + int count = innerAsyncEvent.Count; + AsyncRegistration[] localInnerAsyncEvent = ArrayPool.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.Shared.Return(localInnerAsyncEvent, true); + } } } -} +} \ No newline at end of file