using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Assemblies;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using Bus.Api;
using Bus.Collections.Generic;
using Bus.Collections.ObjectModel;
using Bus.Extensions;
using Bus.Listener;
using Microsoft.CodeAnalysis;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Lordfirespeed")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Event firing and listening framework, based on the event bus concept")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+750e16b7d40d175330f4aadf26cd4abbd1f2e3f1")]
[assembly: AssemblyProduct("Bus")]
[assembly: AssemblyTitle("dev.lordfirespeed.bus")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Lordfirespeed/bus")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace Bus
{
public class EventBus : IEventBus
{
private const BindingFlags MethodSearchFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
private readonly EventTree _eventTree = new EventTree();
private readonly ConcurrentDictionary<object, ConcurrentBag<IEventListener>> _listeners = new ConcurrentDictionary<object, ConcurrentBag<IEventListener>>();
private readonly BusConfiguration _configuration;
private bool _shutdown;
public EventBus(BusConfiguration configuration)
{
_configuration = configuration;
_shutdown = !configuration.StartImmediately;
}
private static void CheckSupertypes(Type registeringType)
{
CheckSupertypes(registeringType, registeringType);
}
private static void CheckSupertypes(Type registeringType, Type? supertype)
{
Type registeringType2 = registeringType;
Type supertype2 = supertype;
if ((object)supertype2 != null && !(supertype2 == typeof(object)))
{
Check();
CheckSupertypes(registeringType2, supertype2.BaseType);
Type[] interfaces = supertype2.GetInterfaces();
foreach (Type supertype3 in interfaces)
{
CheckSupertypes(registeringType2, supertype3);
}
}
void Check()
{
if (!(registeringType2 == supertype2))
{
MethodInfo[] methods = supertype2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
for (int j = 0; j < methods.Length; j++)
{
CheckMethod(methods[j]);
}
}
}
void CheckMethod(MethodInfo method)
{
if (method.GetCustomAttribute<SubscribeEventAttribute>() == null)
{
return;
}
throw new ArgumentException($"Attempting to register a listener object of type {registeringType2},\n" + string.Format("however its supertype {0} declares a method annotated with {1}: {2}.\n", supertype2, "SubscribeEventAttribute", method) + "This is not allowed! Only the listener object may declare methods annotated with SubscribeEventAttribute.");
}
}
public virtual void Register(object target)
{
bool targetIsType;
Type targetType;
if (!_listeners.ContainsKey(target))
{
targetIsType = target is Type;
targetType = (targetIsType ? ((Type)target) : target.GetType());
CheckSupertypes(targetType);
MethodInfo[] array = targetType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(HasSubscribeAnnotation).Tap(EnsureContextMatches)
.ToArray();
if (array.Length == 0)
{
throw new ArgumentException("Register() was invoked upon " + (targetIsType ? targetType.ToString() : $"an instance of {targetType}") + ",\n" + string.Format("but {0} declares no methods annotated with {1}.\n", targetType, "SubscribeEventAttribute") + "The event bus only recognises listener methods annotated with SubscribeEventAttribute.");
}
MethodInfo[] array2 = array;
foreach (MethodInfo method2 in array2)
{
Register(target, method2);
}
}
void EnsureContextMatches(MethodInfo method)
{
if (targetIsType == method.IsStatic)
{
return;
}
if (targetIsType)
{
throw new ArgumentException(string.Format("Expected method annotated with {0} {1} to be static\n", "SubscribeEventAttribute", method) + string.Format("because {0}() was invoked with a Type {1}.\n", "Register", targetType) + string.Format("Either make the method static, or invoke {0}() with an instance of {1}.", "Register", targetType));
}
throw new ArgumentException(string.Format("Expected method annotated with {0} {1} NOT to be static\n", "SubscribeEventAttribute", method) + string.Format("because {0}() was invoked with an instance of {1}.\n", "Register", targetType) + string.Format("Either make the method static, or invoke {0}() with an instance of {1}.", "Register", targetType));
}
static bool HasSubscribeAnnotation(MethodInfo method)
{
return method.GetCustomAttribute<SubscribeEventAttribute>() != null;
}
}
private void Register(object target, MethodInfo method)
{
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != 1)
{
throw new ArgumentException(string.Format("Method {0} is annotated with {1},\n", method, "SubscribeEventAttribute") + $"but declares {parameters.Length} parameters.\n" + "Event handler methods must declare exactly one parameter whose type is a subtype of Event.");
}
Type parameterType = parameters[0].ParameterType;
if (!typeof(Event).IsAssignableFrom(parameterType))
{
throw new ArgumentException(string.Format("Method {0} is annotated with {1},\n", method, "SubscribeEventAttribute") + string.Format("but declares a parameter of type {0}, which is not a subtype of {1}.\n", parameterType, "Event") + "Event handler methods must declare exactly one parameter whose type is a subtype of Event.");
}
Register(parameterType, target, method);
}
private void Register(Type eventType, object target, MethodInfo method)
{
SubscribeEventListener subscribeEventListener = new SubscribeEventListener(target, method);
AddToListeners(eventType, target, subscribeEventListener, subscribeEventListener.Priority);
}
public virtual void AddListener<TEvent>(Action<TEvent> listener) where TEvent : Event
{
AddListener(EventPriority.Normal, listener);
}
public virtual void AddListener<TEvent>(EventPriority priority, Action<TEvent> listener) where TEvent : Event
{
AddListener(priority, receiveCancelled: false, listener);
}
public virtual void AddListener<TEvent>(bool receiveCancelled, Action<TEvent> listener) where TEvent : Event
{
AddListener(EventPriority.Normal, receiveCancelled, listener);
}
public virtual void AddListener<TEvent>(EventPriority priority, bool receiveCancelled, Action<TEvent> listener) where TEvent : Event
{
Action<TEvent> listener2 = listener;
IEventListener eventListener = ((!receiveCancelled) ? CancellationFilteringWrappedListener() : PlainWrappedListener());
IEventListener listener3 = eventListener;
AddToListeners(typeof(TEvent), listener2, listener3, priority);
IEventListener CancellationFilteringWrappedListener()
{
return new CancellationFilteredEventListener(PlainWrappedListener());
}
IEventListener PlainWrappedListener()
{
return new ConsumerEventListener(delegate(Event @event)
{
listener2((TEvent)@event);
});
}
}
private void AddToListeners(Type eventType, object target, IEventListener listener, EventPriority priority)
{
if (eventType.IsAbstract)
{
throw new ArgumentException($"Cannot register listeners for abstract event type {eventType}.\n" + $"Register a listener to a subclass of {eventType} instead.");
}
_eventTree.GetNode(eventType).RegisterListener(priority, listener);
_listeners.GetOrAdd(target, (object _) => new ConcurrentBag<IEventListener>()).Add(listener);
}
public void Unregister(object target)
{
if (!_listeners.TryRemove(target, out ConcurrentBag<IEventListener> value))
{
return;
}
foreach (EventTreeNode item in _eventTree.PreOrderTraverseNodes())
{
foreach (IEventListener item2 in value)
{
item.UnregisterListener(item2);
}
}
}
public TEvent Post<TEvent>(TEvent @event) where TEvent : Event
{
return Post(@event, _eventTree.GetNode(typeof(TEvent)).GetListeners());
}
public TEvent Post<TEvent>(EventPriority phase, TEvent @event) where TEvent : Event
{
if (_shutdown)
{
return @event;
}
return Post(@event, _eventTree.GetNode(typeof(TEvent)).GetPriorityListeners(phase));
}
private TEvent Post<TEvent>(TEvent @event, IEnumerable<IEventListener> listeners) where TEvent : Event
{
foreach (IEventListener listener in listeners)
{
try
{
listener.Invoke(@event);
}
catch (Exception inner)
{
throw new EventInvocationException("Uncaught exception during event invocation", inner)
{
Event = @event,
Listener = listener
};
}
}
return @event;
}
public void Start()
{
_shutdown = false;
}
public void Shutdown()
{
_shutdown = true;
}
}
internal class EventListenerFactoryManager
{
private delegate IEventListener EventListenerFactory(object? target);
private static EventListenerFactoryManager? _instance;
private const string RuntimeEmittedAssemblyName = "dev.lordfirespeed.bus.emitted-event-listeners";
protected AssemblyBuilder? RuntimeEmittedAssembly;
protected ModuleBuilder? RuntimeEmittedModule;
private const string RuntimeEmitToNamespace = "Bus.RuntimeEmitted";
private readonly ConcurrentDictionary<MethodInfo, EventListenerFactory> _eventListenerFactories = new ConcurrentDictionary<MethodInfo, EventListenerFactory>();
public static EventListenerFactoryManager Instance => _instance ?? (_instance = new EventListenerFactoryManager());
private EventListenerFactory GetEventListenerFactory(MethodInfo method)
{
return _eventListenerFactories.GetOrAdd(method, ComputeListenerFactory);
}
private EventListenerFactory ComputeListenerFactory(MethodInfo method)
{
try
{
EnsureRuntimeAssembly();
if (!method.IsAccessible(RuntimeEmittedAssembly))
{
throw new MethodAccessException($"{method} is not sufficiently accessible to be invoked as an event listener.\n" + $"Ensure {method}, its declaring type, and enclosing types are `public`.");
}
Type listenerImplementationType = MakeWrapperType(method);
if (method.IsStatic)
{
return StaticFactory;
}
return InstanceFactory;
IEventListener InstanceFactory(object? target)
{
return (IEventListener)Activator.CreateInstance(listenerImplementationType, target);
}
IEventListener StaticFactory(object? _)
{
return (IEventListener)Activator.CreateInstance(listenerImplementationType);
}
}
catch (Exception innerException)
{
throw new Exception(string.Format("Failed to emit {0} implementation for {1}", "IEventListener", method), innerException);
}
}
[MemberNotNull("RuntimeEmittedAssembly")]
protected void EnsureRuntimeAssembly()
{
if ((object)RuntimeEmittedAssembly == null)
{
AssemblyName name = new AssemblyName("dev.lordfirespeed.bus.emitted-event-listeners")
{
CultureInfo = CultureInfo.InvariantCulture,
Flags = AssemblyNameFlags.None,
ProcessorArchitecture = ProcessorArchitecture.MSIL,
VersionCompatibility = AssemblyVersionCompatibility.SameDomain
};
RuntimeEmittedAssembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
}
}
[MemberNotNull("RuntimeEmittedModule")]
protected void EnsureRuntimeModule()
{
if ((object)RuntimeEmittedModule == null)
{
EnsureRuntimeAssembly();
RuntimeEmittedModule = RuntimeEmittedAssembly.DefineDynamicModule("dev.lordfirespeed.bus.emitted-event-listeners");
}
}
private Type MakeWrapperType(MethodInfo method)
{
EnsureRuntimeModule();
TypeBuilder typeBuilder = RuntimeEmittedModule.DefineType(ComputeEmittedTypeName(method), TypeAttributes.Sealed, typeof(EmittedEventListener));
PopulateWrapperType(method, typeBuilder);
return typeBuilder.CreateTypeInfo();
}
private static string ComputeEmittedTypeName(MethodInfo method)
{
return "Bus.RuntimeEmitted." + method.DeclaringType.FullName + "." + method.Name + "_" + method.GetParameters()[0].ParameterType.Name;
}
protected void PopulateWrapperType(MethodInfo method, TypeBuilder builder)
{
MethodInfo method2 = method;
TypeBuilder builder2 = builder;
builder2.AddInterfaceImplementation(typeof(IEventListener));
FieldBuilder targetField = null;
DefineTargetField();
DefineConstructor();
DefineInvokeImplementation();
void DefineConstructor()
{
ILGenerator iLGenerator2 = builder2.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, method2.IsStatic ? Array.Empty<Type>() : new Type[1] { typeof(object) }).GetILGenerator();
iLGenerator2.Emit(OpCodes.Ldarg_0);
iLGenerator2.Emit(OpCodes.Call, typeof(object).GetConstructor(Array.Empty<Type>()));
if (!method2.IsStatic)
{
iLGenerator2.Emit(OpCodes.Ldarg_0);
iLGenerator2.Emit(OpCodes.Ldarg_1);
iLGenerator2.Emit(OpCodes.Stfld, targetField);
}
iLGenerator2.Emit(OpCodes.Ret);
}
void DefineInvokeImplementation()
{
ILGenerator iLGenerator = builder2.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[1] { typeof(Event) }).GetILGenerator();
if (!method2.IsStatic)
{
iLGenerator.Emit(OpCodes.Ldarg_0);
iLGenerator.Emit(OpCodes.Ldfld, targetField);
iLGenerator.Emit(OpCodes.Castclass, method2.DeclaringType);
}
iLGenerator.Emit(OpCodes.Ldarg_1);
iLGenerator.Emit(OpCodes.Castclass, method2.GetParameters()[0].ParameterType);
iLGenerator.Emit(method2.IsStatic ? OpCodes.Call : OpCodes.Callvirt, method2);
iLGenerator.Emit(OpCodes.Ret);
}
void DefineTargetField()
{
if (!method2.IsStatic)
{
targetField = builder2.DefineField("Target", typeof(object), FieldAttributes.Public);
}
}
}
public IEventListener Create(MethodInfo method, object? target)
{
try
{
EventListenerFactory eventListenerFactory = GetEventListenerFactory(method);
if (method.IsStatic)
{
return eventListenerFactory(null);
}
return eventListenerFactory(target);
}
catch (Exception innerException)
{
throw new Exception(string.Format("Failed to instantiate {0} for {1}", "IEventListener", method), innerException);
}
}
}
public sealed class EventTree
{
[CompilerGenerated]
private sealed class <PostOrderTraverseSubtreeNodes>d__11 : IEnumerable<EventTreeNode>, IEnumerable, IEnumerator<EventTreeNode>, IEnumerator, IDisposable
{
private int <>1__state;
private EventTreeNode <>2__current;
private int <>l__initialThreadId;
private EventTreeNode subtreeRoot;
public EventTreeNode <>3__subtreeRoot;
private IEnumerator<EventTreeNode> <>7__wrap1;
private IEnumerator<EventTreeNode> <>7__wrap2;
EventTreeNode IEnumerator<EventTreeNode>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PostOrderTraverseSubtreeNodes>d__11(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if ((uint)(num - -4) <= 1u || num == 1)
{
try
{
if (num == -4 || num == 1)
{
try
{
}
finally
{
<>m__Finally2();
}
}
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<>7__wrap2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = subtreeRoot.Children.GetEnumerator();
<>1__state = -3;
goto IL_00ae;
case 1:
<>1__state = -4;
goto IL_0094;
case 2:
{
<>1__state = -1;
return false;
}
IL_00ae:
if (<>7__wrap1.MoveNext())
{
EventTreeNode current = <>7__wrap1.Current;
<>7__wrap2 = PostOrderTraverseSubtreeNodes(current).GetEnumerator();
<>1__state = -4;
goto IL_0094;
}
<>m__Finally1();
<>7__wrap1 = null;
<>2__current = subtreeRoot;
<>1__state = 2;
return true;
IL_0094:
if (<>7__wrap2.MoveNext())
{
EventTreeNode current2 = <>7__wrap2.Current;
<>2__current = current2;
<>1__state = 1;
return true;
}
<>m__Finally2();
<>7__wrap2 = null;
goto IL_00ae;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
private void <>m__Finally2()
{
<>1__state = -3;
if (<>7__wrap2 != null)
{
<>7__wrap2.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<EventTreeNode> IEnumerable<EventTreeNode>.GetEnumerator()
{
<PostOrderTraverseSubtreeNodes>d__11 <PostOrderTraverseSubtreeNodes>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<PostOrderTraverseSubtreeNodes>d__ = this;
}
else
{
<PostOrderTraverseSubtreeNodes>d__ = new <PostOrderTraverseSubtreeNodes>d__11(0);
}
<PostOrderTraverseSubtreeNodes>d__.subtreeRoot = <>3__subtreeRoot;
return <PostOrderTraverseSubtreeNodes>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<EventTreeNode>)this).GetEnumerator();
}
}
[CompilerGenerated]
private sealed class <PreOrderTraverseSubtreeNodes>d__9 : IEnumerable<EventTreeNode>, IEnumerable, IEnumerator<EventTreeNode>, IEnumerator, IDisposable
{
private int <>1__state;
private EventTreeNode <>2__current;
private int <>l__initialThreadId;
private EventTreeNode subtreeRoot;
public EventTreeNode <>3__subtreeRoot;
private IEnumerator<EventTreeNode> <>7__wrap1;
private IEnumerator<EventTreeNode> <>7__wrap2;
EventTreeNode IEnumerator<EventTreeNode>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PreOrderTraverseSubtreeNodes>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if ((uint)(num - -4) <= 1u || num == 2)
{
try
{
if (num == -4 || num == 2)
{
try
{
}
finally
{
<>m__Finally2();
}
}
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<>7__wrap2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = subtreeRoot;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>7__wrap1 = subtreeRoot.Children.GetEnumerator();
<>1__state = -3;
goto IL_00cf;
case 2:
{
<>1__state = -4;
goto IL_00b5;
}
IL_00cf:
if (<>7__wrap1.MoveNext())
{
EventTreeNode current = <>7__wrap1.Current;
<>7__wrap2 = PreOrderTraverseSubtreeNodes(current).GetEnumerator();
<>1__state = -4;
goto IL_00b5;
}
<>m__Finally1();
<>7__wrap1 = null;
return false;
IL_00b5:
if (<>7__wrap2.MoveNext())
{
EventTreeNode current2 = <>7__wrap2.Current;
<>2__current = current2;
<>1__state = 2;
return true;
}
<>m__Finally2();
<>7__wrap2 = null;
goto IL_00cf;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
private void <>m__Finally2()
{
<>1__state = -3;
if (<>7__wrap2 != null)
{
<>7__wrap2.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<EventTreeNode> IEnumerable<EventTreeNode>.GetEnumerator()
{
<PreOrderTraverseSubtreeNodes>d__9 <PreOrderTraverseSubtreeNodes>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<PreOrderTraverseSubtreeNodes>d__ = this;
}
else
{
<PreOrderTraverseSubtreeNodes>d__ = new <PreOrderTraverseSubtreeNodes>d__9(0);
}
<PreOrderTraverseSubtreeNodes>d__.subtreeRoot = <>3__subtreeRoot;
return <PreOrderTraverseSubtreeNodes>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<EventTreeNode>)this).GetEnumerator();
}
}
private static readonly IEqualityComparer<Type> TypeComparer = new IdentityEqualityComparer<Type>();
private readonly EventTreeNode _root;
private readonly LinkedList<EventTreeNode> _allNodes = new LinkedList<EventTreeNode>();
private readonly ConcurrentDictionary<Type, EventTreeNode> _eventNodes;
internal EventTree()
{
_root = EventTreeNode.CreateRoot(typeof(Event), this);
_allNodes.AddFirst(_root);
_eventNodes = new ConcurrentDictionary<Type, EventTreeNode>(new <>z__ReadOnlySingleElementList<KeyValuePair<Type, EventTreeNode>>(new KeyValuePair<Type, EventTreeNode>(typeof(Event), _root)), TypeComparer);
}
public EventTreeNode GetNode(Type eventType)
{
if (TypeComparer.Equals(eventType, typeof(Event)))
{
return _root;
}
return _eventNodes.GetOrAdd(eventType, ComputeNode);
}
private EventTreeNode ComputeNode(Type eventType)
{
if (eventType.IsGenericType)
{
throw new NotSupportedException("Generic event types & their subtypes are not supported.");
}
Type baseType = eventType.BaseType;
if (eventType.IsAbstract && !baseType.IsAbstract)
{
throw new NotSupportedException($"Abstract event type {eventType} has a non-abstract base type {baseType}.\n" + "Base types of abstract event types must be abstract, with the exception of the root Event type.");
}
return GetNode(baseType).AddChild(baseType);
}
internal void ClearBus(int busId)
{
foreach (EventTreeNode item in PreOrderTraverseNodes())
{
item.Clear();
}
}
public IEnumerable<EventTreeNode> PreOrderTraverseNodes()
{
return PreOrderTraverseSubtreeNodes(_root);
}
[IteratorStateMachine(typeof(<PreOrderTraverseSubtreeNodes>d__9))]
private static IEnumerable<EventTreeNode> PreOrderTraverseSubtreeNodes(EventTreeNode subtreeRoot)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PreOrderTraverseSubtreeNodes>d__9(-2)
{
<>3__subtreeRoot = subtreeRoot
};
}
public IEnumerable<EventTreeNode> PostOrderTraverseNodes()
{
return PostOrderTraverseSubtreeNodes(_root);
}
[IteratorStateMachine(typeof(<PostOrderTraverseSubtreeNodes>d__11))]
private static IEnumerable<EventTreeNode> PostOrderTraverseSubtreeNodes(EventTreeNode subtreeRoot)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PostOrderTraverseSubtreeNodes>d__11(-2)
{
<>3__subtreeRoot = subtreeRoot
};
}
}
public class EventTreeNode
{
protected sealed class EventListenerEnumerable : IEnumerable<IEventListener>, IEnumerable, IDisposable
{
private bool _disposed;
private readonly EventTreeNode _node;
private IEventListener[]? _orderedListenersCache;
private IEventListener[][]? _orderedPriorityListenersCache;
private LinkedList<IEventListener>[] _priorityListenerLists = EventPriority.Values.Select((EventPriority _) => new LinkedList<IEventListener>()).ToArray();
private readonly SemaphoreSlim _accessLock = new SemaphoreSlim(1, 1);
[MemberNotNullWhen(false, new string[] { "_orderedListenersCache", "_orderedPriorityListenersCache" })]
protected bool CacheDirty
{
[MemberNotNullWhen(false, new string[] { "_orderedListenersCache", "_orderedPriorityListenersCache" })]
get;
[MemberNotNullWhen(false, new string[] { "_orderedListenersCache", "_orderedPriorityListenersCache" })]
private set;
} = true;
public EventListenerEnumerable(EventTreeNode node)
{
_node = node;
}
IEnumerator<IEventListener> IEnumerable<IEventListener>.GetEnumerator()
{
EnsureCleanCache();
return _orderedListenersCache.AsEnumerable().GetEnumerator();
}
public IEnumerator GetEnumerator()
{
return ((IEnumerable<IEventListener>)this).GetEnumerator();
}
public IEnumerable<IEventListener> GetPriorityListeners(EventPriority priority)
{
EnsureCleanCache();
return _orderedPriorityListenersCache[priority.Ordinal];
}
[MemberNotNull(new string[] { "_orderedListenersCache", "_orderedPriorityListenersCache" })]
private void EnsureCleanCache()
{
if (CacheDirty)
{
BuildCache();
}
}
[MemberNotNull(new string[] { "_orderedListenersCache", "_orderedPriorityListenersCache" })]
private void BuildCache()
{
_orderedPriorityListenersCache = (from value in EventPriority.Values.Select(GetListeners)
select value ?? Array.Empty<IEventListener>() into enumerable
select enumerable.ToArray()).ToArray();
_orderedListenersCache = _orderedPriorityListenersCache.SelectMany((IEventListener[] x) => x).ToArray();
CacheDirty = false;
}
private IEnumerable<IEventListener>? GetListeners(EventPriority priority)
{
IEnumerable<IEventListener> enumerable = _node.Parent?.GetPriorityListeners(priority);
_accessLock.Wait();
ICollection<IEventListener> collection;
try
{
collection = _priorityListenerLists[priority.Ordinal].Select(Unwrap).ToArray();
}
finally
{
_accessLock.Release();
}
if (enumerable == null && collection.Count == 0)
{
return null;
}
return (enumerable ?? Array.Empty<IEventListener>()).Concat(collection);
IEventListener Unwrap(IEventListener listener)
{
if (_node.IsCancellable)
{
return listener;
}
if (listener is CancellationFilteredEventListener cancellationFilteredEventListener)
{
return cancellationFilteredEventListener.Inner;
}
return listener;
}
}
protected void SetDirty()
{
CacheDirty = true;
foreach (EventTreeNode child in _node.Children)
{
child._listeners.SetDirty();
}
}
public void RegisterListener(EventPriority priority, IEventListener listener)
{
_accessLock.Wait();
try
{
_priorityListenerLists[priority.Ordinal].AddLast(listener);
}
finally
{
_accessLock.Release();
}
}
public void UnregisterListener(IEventListener listener)
{
IEventListener listener2 = listener;
_accessLock.Wait();
try
{
if (_priorityListenerLists.Where((LinkedList<IEventListener> listeners) => listeners.Remove(listener2)).Any())
{
SetDirty();
}
}
finally
{
_accessLock.Release();
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
_accessLock.Wait();
try
{
LinkedList<IEventListener>[] priorityListenerLists = _priorityListenerLists;
for (int i = 0; i < priorityListenerLists.Length; i++)
{
priorityListenerLists[i].Clear();
}
_priorityListenerLists.Initialize();
_priorityListenerLists = null;
}
finally
{
_accessLock.Release();
}
_accessLock.Dispose();
_orderedListenersCache = null;
}
_disposed = true;
}
}
private readonly EventTree _tree;
private LinkedList<EventTreeNode>? _children;
private readonly EventListenerEnumerable _listeners;
public bool HasResult { get; }
public bool IsCancellable { get; }
public EventTreeNode? Parent { get; private set; }
public Type EventType { get; }
public ICollection<EventTreeNode> Children
{
get
{
if (_children != null)
{
return new ReadOnlyAssemblage<EventTreeNode>(_children);
}
return Array.Empty<EventTreeNode>();
}
}
public static EventTreeNode CreateRoot(Type rootEventType, EventTree tree)
{
return new EventTreeNode(rootEventType, tree);
}
private EventTreeNode(Type eventType, EventTree tree)
{
EventType = eventType;
_tree = tree;
_listeners = new EventListenerEnumerable(this);
IsCancellable = typeof(ICancellableEvent).IsAssignableFrom(eventType);
}
public EventTreeNode AddChild(Type childEventType)
{
if (!EventType.IsAssignableFrom(childEventType))
{
throw new ArgumentException("Child event type is not derived from event type this node represents.");
}
EventTreeNode eventTreeNode = new EventTreeNode(childEventType, _tree);
if (_children == null)
{
_children = new LinkedList<EventTreeNode>();
}
_children.AddLast(eventTreeNode);
eventTreeNode.Parent = this;
return eventTreeNode;
}
public IEnumerable<IEventListener> GetListeners()
{
return _listeners;
}
public IEnumerable<IEventListener> GetPriorityListeners(EventPriority priority)
{
return _listeners.GetPriorityListeners(priority);
}
public void RegisterListener(EventPriority priority, IEventListener listener)
{
_listeners.RegisterListener(priority, listener);
}
public void UnregisterListener(IEventListener listener)
{
_listeners.UnregisterListener(listener);
}
public void Clear()
{
_listeners.Dispose();
}
}
internal static class MethodAccessibilityExtensions
{
public static bool IsAccessible(this MethodInfo method, Assembly context)
{
if (method.IsPrivate || method.IsFamily || method.IsFamilyAndAssembly)
{
return false;
}
if (method.IsPublic)
{
return method.DeclaringType.IsAccessible(context);
}
if (method.IsAssembly || method.IsFamilyOrAssembly)
{
if (!method.DeclaringType.Assembly.MakesInternalsVisibleTo(context))
{
return false;
}
return method.DeclaringType.IsAccessible(context);
}
return false;
}
public static bool IsAccessible(this Type type, Assembly context)
{
if (type.IsPublic)
{
return true;
}
if (type.IsNested)
{
if (type.IsNestedPrivate || type.IsNestedFamily || type.IsNestedFamANDAssem)
{
return false;
}
if (type.IsNestedPublic)
{
return type.DeclaringType.IsAccessible(context);
}
if (type.IsNestedAssembly || type.IsNestedFamORAssem)
{
if (!type.Assembly.MakesInternalsVisibleTo(context))
{
return false;
}
return type.DeclaringType.IsAccessible(context);
}
return false;
}
return false;
}
public static bool MakesInternalsVisibleTo(this Assembly assembly, Assembly other)
{
AssemblyName otherName = other.GetName();
return assembly.GetCustomAttributes<InternalsVisibleToAttribute>().Any((InternalsVisibleToAttribute attribute) => AssemblyName.ReferenceMatchesDefinition(new AssemblyName(attribute.AssemblyName), otherName));
}
}
}
namespace Bus.Listener
{
public sealed class CancellationFilteredEventListener : IEventListener
{
public IEventListener Inner { get; }
public CancellationFilteredEventListener(IEventListener inner)
{
Inner = inner;
}
public void Invoke(Event message)
{
if (!(message is ICancellableEvent cancellableEvent) || !cancellableEvent.IsCanceled)
{
Inner.Invoke(message);
}
}
}
public sealed class ConsumerEventListener : IEventListener
{
private readonly Action<Event> _consumer;
public ConsumerEventListener(Action<Event> consumer)
{
_consumer = consumer;
}
public void Invoke(Event message)
{
_consumer(message);
}
public override string ToString()
{
return _consumer.ToString();
}
}
public abstract class EmittedEventListener : IEventListener
{
public abstract void Invoke(Event message);
}
public sealed class SubscribeEventListener : IEventListener
{
private readonly IEventListener _handler;
private readonly SubscribeEventAttribute _subscriptionAttribute;
private readonly string _readable;
public EventPriority Priority => _subscriptionAttribute.Priority;
public SubscribeEventListener(object target, MethodInfo method)
{
_handler = EventListenerFactoryManager.Instance.Create(method, target);
_subscriptionAttribute = method.GetCustomAttribute<SubscribeEventAttribute>();
_readable = $"@SubscribeEvent: {target} {method.Name}";
}
public void Invoke(Event message)
{
if (_handler != null && (_subscriptionAttribute.ReceiveCancelled || !(message is ICancellableEvent cancellableEvent) || !cancellableEvent.IsCanceled))
{
_handler.Invoke(message);
}
}
}
}
namespace Bus.Extensions
{
public static class EnumerableExtensions
{
[CompilerGenerated]
private sealed class <TapIterator>d__1<TSource> : IEnumerable<TSource>, IEnumerable, IEnumerator<TSource>, IEnumerator, IDisposable where TSource : notnull
{
private int <>1__state;
private TSource <>2__current;
private int <>l__initialThreadId;
private IEnumerable<TSource> source;
public IEnumerable<TSource> <>3__source;
private Action<TSource> action;
public Action<TSource> <>3__action;
private IEnumerator<TSource> <>7__wrap1;
TSource IEnumerator<TSource>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TapIterator>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = source.GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
break;
}
if (<>7__wrap1.MoveNext())
{
TSource current = <>7__wrap1.Current;
action(current);
<>2__current = current;
<>1__state = 1;
return true;
}
<>m__Finally1();
<>7__wrap1 = null;
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
{
<TapIterator>d__1<TSource> <TapIterator>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<TapIterator>d__ = this;
}
else
{
<TapIterator>d__ = new <TapIterator>d__1<TSource>(0);
}
<TapIterator>d__.source = <>3__source;
<TapIterator>d__.action = <>3__action;
return <TapIterator>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<TSource>)this).GetEnumerator();
}
}
public static IEnumerable<TSource> Tap<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (action == null)
{
throw new ArgumentNullException("action");
}
return TapIterator(source, action);
}
[IteratorStateMachine(typeof(<TapIterator>d__1<>))]
private static IEnumerable<TSource> TapIterator<TSource>(IEnumerable<TSource> source, Action<TSource> action)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TapIterator>d__1<TSource>(-2)
{
<>3__source = source,
<>3__action = action
};
}
}
}
namespace Bus.Collections.ObjectModel
{
public static class CollectionExtensions
{
public static ReadOnlyAssemblage<T> AsReadOnly<T>(this ICollection<T> collection)
{
return new ReadOnlyAssemblage<T>(collection);
}
}
public class ReadOnlyAssemblage<T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, ICollection<T>
{
[CompilerGenerated]
private ICollection<T> <assemblage>P;
int ICollection<T>.Count => <assemblage>P.Count;
public bool IsReadOnly => true;
int IReadOnlyCollection<T>.Count => <assemblage>P.Count;
public ReadOnlyAssemblage(ICollection<T> assemblage)
{
<assemblage>P = assemblage;
base..ctor();
}
public IEnumerator<T> GetEnumerator()
{
return <assemblage>P.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
public void Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
public bool Contains(T item)
{
return <assemblage>P.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
<assemblage>P.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
}
}
namespace Bus.Collections.Generic
{
public sealed class IdentityEqualityComparer<T> : IEqualityComparer<T> where T : class
{
public int GetHashCode(T value)
{
return RuntimeHelpers.GetHashCode(value);
}
public bool Equals(T left, T right)
{
return left == right;
}
}
}
namespace Bus.Api
{
public record BusConfiguration
{
public bool StartImmediately { get; init; } = true;
public IEventBus Build()
{
return new EventBus(this);
}
}
public abstract class Event
{
internal bool _isCancelled;
}
public class EventInvocationException : Exception
{
public required Event Event { get; init; }
public required IEventListener? Listener { get; init; }
public EventInvocationException()
{
}
public EventInvocationException(string message)
: base(message)
{
}
public EventInvocationException(string message, Exception inner)
: base(message, inner)
{
}
}
public class EventPriority
{
private static readonly LinkedList<EventPriority> Priorities;
public static EventPriority Highest;
public static EventPriority High;
public static EventPriority Normal;
public static EventPriority Low;
public static EventPriority Lowest;
public static int Count => Priorities.Count;
public string Name { get; }
public int Ordinal { get; }
public static IEnumerable<EventPriority> Values => new ReadOnlyAssemblage<EventPriority>(Priorities);
static EventPriority()
{
Priorities = new LinkedList<EventPriority>();
Highest = new EventPriority("Highest");
High = new EventPriority("High");
Normal = new EventPriority("Normal");
Low = new EventPriority("Low");
Lowest = new EventPriority("Lowest");
}
private EventPriority(string name)
{
Name = name;
Ordinal = Priorities.Count;
Priorities.AddLast(this);
}
}
public interface ICancellableEvent
{
bool IsCanceled => ((Event)this)._isCancelled;
void SetCanceled(bool canceled)
{
((Event)this)._isCancelled = canceled;
}
}
public interface IEventBus
{
public delegate void InvokeDispatcher(IEventListener listener, Event @event);
void Register(object target);
void AddListener<TEvent>(Action<TEvent> listener) where TEvent : Event;
void AddListener<TEvent>(EventPriority priority, Action<TEvent> listener) where TEvent : Event;
void AddListener<TEvent>(bool receiveCancelled, Action<TEvent> listener) where TEvent : Event;
void AddListener<TEvent>(EventPriority priority, bool receiveCancelled, Action<TEvent> listener) where TEvent : Event;
void Unregister(object target);
TEvent Post<TEvent>(TEvent @event) where TEvent : Event;
TEvent Post<TEvent>(EventPriority phase, TEvent @event) where TEvent : Event;
void Shutdown();
void Start();
}
public interface IEventListener
{
void Invoke(Event message);
}
[AttributeUsage(AttributeTargets.Method)]
public class SubscribeEventAttribute : Attribute
{
public EventPriority Priority { get; }
public bool ReceiveCancelled { get; }
public SubscribeEventAttribute()
: this(receiveCancelled: false)
{
}
public SubscribeEventAttribute(bool receiveCancelled)
: this(EventPriority.Normal, receiveCancelled)
{
}
public SubscribeEventAttribute(EventPriority priority, bool receiveCancelled = false)
{
Priority = priority;
ReceiveCancelled = receiveCancelled;
}
}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
{
object IEnumerator.Current => _item;
T IEnumerator<T>.Current => _item;
public Enumerator(T item)
{
_item = item;
}
bool IEnumerator.MoveNext()
{
if (!_moveNextCalled)
{
return _moveNextCalled = true;
}
return false;
}
void IEnumerator.Reset()
{
_moveNextCalled = false;
}
void IDisposable.Dispose()
{
}
}
int ICollection.Count => 1;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => 1;
T IReadOnlyList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
}
int ICollection<T>.Count => 1;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlySingleElementList(T item)
{
_item = item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection.CopyTo(Array array, int index)
{
array.SetValue(_item, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return EqualityComparer<T>.Default.Equals(_item, (T)value);
}
int IList.IndexOf(object value)
{
if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
{
return -1;
}
return 0;
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return EqualityComparer<T>.Default.Equals(_item, item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
array[arrayIndex] = _item;
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
if (!EqualityComparer<T>.Default.Equals(_item, item))
{
return -1;
}
return 0;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}