Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Lordfirespeed Bus v0.1.0
BepInEx/core/Lordfirespeed.Bus/netstandard2.1/dev.lordfirespeed.bus.dll
Decompiled a year agousing 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(); } }