Decompiled source of Lordfirespeed Bus v0.1.0

BepInEx/core/Lordfirespeed.Bus/netstandard2.1/dev.lordfirespeed.bus.dll

Decompiled a week ago
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();
	}
}