com.wallstop-studios.dxmessaging 2.2.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +315 -67
- package/CHANGELOG.md.meta +7 -7
- package/Editor/Analyzers/BaseCallIlInspector.cs +277 -0
- package/Editor/Analyzers/BaseCallIlInspector.cs.meta +11 -0
- package/Editor/Analyzers/BaseCallLogMessageParser.cs +295 -0
- package/Editor/Analyzers/BaseCallLogMessageParser.cs.meta +11 -0
- package/Editor/Analyzers/BaseCallReportAggregator.cs +308 -0
- package/Editor/Analyzers/BaseCallReportAggregator.cs.meta +11 -0
- package/Editor/Analyzers/BaseCallTypeScanner.cs +110 -0
- package/Editor/Analyzers/BaseCallTypeScanner.cs.meta +11 -0
- package/Editor/Analyzers/BaseCallTypeScannerCore.cs +562 -0
- package/Editor/Analyzers/BaseCallTypeScannerCore.cs.meta +11 -0
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +1129 -0
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs.meta +11 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +44 -44
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +44 -44
- package/Editor/Analyzers/System.Collections.Immutable.dll.meta +44 -44
- package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +44 -44
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +44 -44
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +46 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +72 -72
- package/Editor/Analyzers.meta +8 -8
- package/Editor/AssemblyInfo.cs.meta +11 -3
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +81 -0
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs.meta +11 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +429 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs.meta +11 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +1 -1
- package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +11 -3
- package/Editor/CustomEditors.meta +2 -2
- package/Editor/DxMessagingEditorIdle.cs +62 -0
- package/Editor/DxMessagingEditorIdle.cs.meta +11 -0
- package/Editor/DxMessagingEditorInitializer.cs +112 -15
- package/Editor/DxMessagingEditorInitializer.cs.meta +11 -3
- package/Editor/DxMessagingEditorLog.cs +32 -0
- package/Editor/DxMessagingEditorLog.cs.meta +11 -0
- package/Editor/DxMessagingMenu.cs.meta +11 -11
- package/Editor/DxMessagingSceneBuildProcessor.cs.meta +11 -11
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +313 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs.meta +11 -0
- package/Editor/Settings/DxMessagingSettings.cs +261 -11
- package/Editor/Settings/DxMessagingSettings.cs.meta +11 -3
- package/Editor/Settings/DxMessagingSettingsProvider.cs +50 -33
- package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +11 -3
- package/Editor/Settings.meta +2 -2
- package/Editor/SetupCscRsp.cs +406 -39
- package/Editor/SetupCscRsp.cs.meta +11 -3
- package/Editor/Testing/MessagingComponentEditorHarness.cs +2 -2
- package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +11 -3
- package/Editor/Testing.meta +3 -3
- package/Editor/WallstopStudios.DxMessaging.Editor.asmdef +14 -14
- package/Editor/WallstopStudios.DxMessaging.Editor.asmdef.meta +7 -7
- package/Editor.meta +8 -8
- package/LICENSE.md +9 -9
- package/LICENSE.md.meta +7 -7
- package/README.md +940 -900
- package/README.md.meta +7 -7
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/AssemblyInfo.cs.meta +11 -3
- package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +11 -3
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +11 -3
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs +26 -0
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +2 -4
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +11 -3
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +11 -3
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +11 -3
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs +56 -0
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes.meta +2 -2
- package/Runtime/Core/Configuration/DxMessagingRuntimeSettings.cs +195 -0
- package/Runtime/Core/Configuration/DxMessagingRuntimeSettings.cs.meta +11 -0
- package/Runtime/Core/Configuration/DxMessagingRuntimeSettingsProvider.cs +179 -0
- package/Runtime/Core/Configuration/DxMessagingRuntimeSettingsProvider.cs.meta +11 -0
- package/Runtime/Core/Configuration.meta +9 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +46 -28
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +11 -3
- package/Runtime/Core/DataStructure.meta +2 -2
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +11 -3
- package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +11 -3
- package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +11 -3
- package/Runtime/Core/Diagnostics.meta +2 -2
- package/Runtime/Core/DxMessagingStaticState.cs +19 -0
- package/Runtime/Core/DxMessagingStaticState.cs.meta +11 -11
- package/Runtime/Core/Extensions/EnumExtensions.cs +6 -5
- package/Runtime/Core/Extensions/EnumExtensions.cs.meta +11 -3
- package/Runtime/Core/Extensions/IListExtensions.cs.meta +11 -3
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -12
- package/Runtime/Core/Extensions/MessageExtensions.cs +0 -60
- package/Runtime/Core/Extensions/MessageExtensions.cs.meta +11 -11
- package/Runtime/Core/Extensions.meta +8 -8
- package/Runtime/Core/Helper/MessageCache.cs +32 -0
- package/Runtime/Core/Helper/MessageCache.cs.meta +11 -3
- package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +11 -3
- package/Runtime/Core/Helper.meta +2 -2
- package/Runtime/Core/IMessage.cs +3 -3
- package/Runtime/Core/IMessage.cs.meta +11 -11
- package/Runtime/Core/InstanceId.cs +25 -1
- package/Runtime/Core/InstanceId.cs.meta +11 -11
- package/Runtime/Core/Internal/DxUnsafe.cs +60 -0
- package/Runtime/Core/Internal/DxUnsafe.cs.meta +11 -0
- package/Runtime/Core/Internal/FlatDispatch.cs +198 -0
- package/Runtime/Core/Internal/FlatDispatch.cs.meta +11 -0
- package/Runtime/Core/Internal/TypedGlobalSlotIndex.cs +38 -0
- package/Runtime/Core/Internal/TypedGlobalSlotIndex.cs.meta +11 -0
- package/Runtime/Core/Internal/TypedSlotIndex.cs +81 -0
- package/Runtime/Core/Internal/TypedSlotIndex.cs.meta +11 -0
- package/Runtime/Core/Internal/TypedSlots.cs +597 -0
- package/Runtime/Core/Internal/TypedSlots.cs.meta +11 -0
- package/Runtime/Core/Internal.meta +9 -0
- package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +11 -11
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +11 -11
- package/Runtime/Core/MessageBus/IMessageBus.cs +189 -15
- package/Runtime/Core/MessageBus/IMessageBus.cs.meta +11 -11
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -11
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +1 -0
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +11 -11
- package/Runtime/Core/MessageBus/Internal/BusContextIndex.cs +16 -0
- package/Runtime/Core/MessageBus/Internal/BusContextIndex.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/BusSinkIndex.cs +40 -0
- package/Runtime/Core/MessageBus/Internal/BusSinkIndex.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/BusSlots.cs +719 -0
- package/Runtime/Core/MessageBus/Internal/BusSlots.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/DispatchKind.cs +38 -0
- package/Runtime/Core/MessageBus/Internal/DispatchKind.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/DispatchPhase.cs +20 -0
- package/Runtime/Core/MessageBus/Internal/DispatchPhase.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/DispatchVariant.cs +28 -0
- package/Runtime/Core/MessageBus/Internal/DispatchVariant.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/IEvictableSlot.cs +48 -0
- package/Runtime/Core/MessageBus/Internal/IEvictableSlot.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/ISweepable.cs +15 -0
- package/Runtime/Core/MessageBus/Internal/ISweepable.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/RegistrationMethodAxes.cs +222 -0
- package/Runtime/Core/MessageBus/Internal/RegistrationMethodAxes.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal/SlotKey.cs +192 -0
- package/Runtime/Core/MessageBus/Internal/SlotKey.cs.meta +11 -0
- package/Runtime/Core/MessageBus/Internal.meta +9 -0
- package/Runtime/Core/MessageBus/MessageBus.cs +5366 -3838
- package/Runtime/Core/MessageBus/MessageBus.cs.meta +11 -11
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -11
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +187 -14
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +11 -11
- package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +11 -11
- package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +11 -11
- package/Runtime/Core/MessageBus.meta +8 -8
- package/Runtime/Core/MessageHandler.cs +2399 -1042
- package/Runtime/Core/MessageHandler.cs.meta +11 -11
- package/Runtime/Core/MessageRegistrationHandle.cs.meta +11 -11
- package/Runtime/Core/MessageRegistrationToken.cs +429 -44
- package/Runtime/Core/MessageRegistrationToken.cs.meta +11 -11
- package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +11 -3
- package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +11 -11
- package/Runtime/Core/Messages/ITargetedMessage.cs.meta +11 -11
- package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +11 -11
- package/Runtime/Core/Messages/ReflexiveMessage.cs.meta +11 -3
- package/Runtime/Core/Messages/SourcedStringMessage.cs.meta +11 -11
- package/Runtime/Core/Messages/StringMessage.cs.meta +11 -3
- package/Runtime/Core/Messages.meta +8 -8
- package/Runtime/Core/MessagingDebug.cs.meta +11 -11
- package/Runtime/Core/Pooling/CollectionPool.cs +266 -0
- package/Runtime/Core/Pooling/CollectionPool.cs.meta +11 -0
- package/Runtime/Core/Pooling/CollectionPoolDiagnostics.cs +30 -0
- package/Runtime/Core/Pooling/CollectionPoolDiagnostics.cs.meta +11 -0
- package/Runtime/Core/Pooling/DxPools.cs +157 -0
- package/Runtime/Core/Pooling/DxPools.cs.meta +11 -0
- package/Runtime/Core/Pooling/EvictionPlayerLoopHook.cs +106 -0
- package/Runtime/Core/Pooling/EvictionPlayerLoopHook.cs.meta +11 -0
- package/Runtime/Core/Pooling/IDxMessagingClock.cs +18 -0
- package/Runtime/Core/Pooling/IDxMessagingClock.cs.meta +11 -0
- package/Runtime/Core/Pooling/PoolDiagnosticsSnapshot.cs +55 -0
- package/Runtime/Core/Pooling/PoolDiagnosticsSnapshot.cs.meta +11 -0
- package/Runtime/Core/Pooling/StopwatchClock.cs +27 -0
- package/Runtime/Core/Pooling/StopwatchClock.cs.meta +11 -0
- package/Runtime/Core/Pooling/UnityRealtimeClock.cs +31 -0
- package/Runtime/Core/Pooling/UnityRealtimeClock.cs.meta +11 -0
- package/Runtime/Core/Pooling.meta +9 -0
- package/Runtime/Core.meta +8 -8
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +12 -12
- package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +11 -11
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +12 -12
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +11 -3
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +73 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +11 -11
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef +20 -20
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef.meta +7 -7
- package/Runtime/Unity/Integrations/Reflex.meta +8 -8
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +11 -3
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +109 -1
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +11 -11
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef +30 -30
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef.meta +7 -7
- package/Runtime/Unity/Integrations/VContainer.meta +8 -8
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +11 -3
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef +30 -30
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef.meta +7 -7
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +79 -1
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +11 -11
- package/Runtime/Unity/Integrations/Zenject.meta +8 -8
- package/Runtime/Unity/Integrations.meta +8 -8
- package/Runtime/Unity/MessageAwareComponent.cs +74 -0
- package/Runtime/Unity/MessageAwareComponent.cs.meta +11 -11
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -12
- package/Runtime/Unity/MessagingComponent.cs +43 -10
- package/Runtime/Unity/MessagingComponent.cs.meta +11 -11
- package/Runtime/Unity/MessagingComponentInstaller.cs.meta +12 -12
- package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +12 -12
- package/Runtime/Unity.meta +8 -8
- package/Runtime/WallstopStudios.DxMessaging.asmdef +14 -14
- package/Runtime/WallstopStudios.DxMessaging.asmdef.meta +7 -7
- package/Runtime.meta +8 -8
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab +98 -98
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab.meta +7 -7
- package/Samples~/DI/Prefabs.meta +8 -8
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset +14 -14
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset.meta +8 -8
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset +14 -14
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset.meta +8 -8
- package/Samples~/DI/Providers.meta +8 -8
- package/Samples~/DI/README.md +51 -51
- package/Samples~/DI/README.md.meta +7 -7
- package/Samples~/DI/Reflex/SampleInstaller.cs +7 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs.meta +11 -11
- package/Samples~/DI/Reflex.meta +8 -8
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs +6 -1
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -11
- package/Samples~/DI/VContainer.meta +8 -8
- package/Samples~/DI/Zenject/SampleInstaller.cs +8 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs.meta +11 -11
- package/Samples~/DI/Zenject.meta +8 -8
- package/Samples~/DI.meta +8 -8
- package/Samples~/Mini Combat/Boot.cs.meta +11 -11
- package/Samples~/Mini Combat/Enemy.cs.meta +11 -11
- package/Samples~/Mini Combat/Messages.cs.meta +11 -11
- package/Samples~/Mini Combat/Player.cs.meta +11 -11
- package/Samples~/Mini Combat/README.md +324 -323
- package/Samples~/Mini Combat/README.md.meta +7 -7
- package/Samples~/Mini Combat/UIOverlay.cs.meta +11 -11
- package/Samples~/Mini Combat/Walkthrough.md +430 -430
- package/Samples~/Mini Combat/Walkthrough.md.meta +7 -7
- package/Samples~/Mini Combat/WallstopStudios.DxMessaging.MiniCombat.Sample.asmdef +13 -13
- package/Samples~/Mini Combat/WallstopStudios.DxMessaging.MiniCombat.Sample.asmdef.meta +7 -7
- package/Samples~/Mini Combat.meta +8 -8
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs.meta +11 -11
- package/Samples~/UI Buttons + Inspector/Messages.cs.meta +11 -11
- package/Samples~/UI Buttons + Inspector/MessagingObserver.cs.meta +11 -11
- package/Samples~/UI Buttons + Inspector/README.md +210 -209
- package/Samples~/UI Buttons + Inspector/README.md.meta +7 -7
- package/Samples~/UI Buttons + Inspector/UIButtonEmitter.cs.meta +11 -11
- package/Samples~/UI Buttons + Inspector/WallstopStudios.DxMessaging.UIButtons.Sample.asmdef +13 -13
- package/Samples~/UI Buttons + Inspector/WallstopStudios.DxMessaging.UIButtons.Sample.asmdef.meta +7 -7
- package/Samples~/UI Buttons + Inspector.meta +8 -8
- package/SourceGenerators/Directory.Build.props +50 -3
- package/SourceGenerators/Directory.Build.props.meta +7 -7
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +96 -63
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs.meta +11 -11
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +745 -87
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +11 -3
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +39 -46
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj.meta +7 -7
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.meta +8 -8
- package/SourceGenerators/global.json +7 -0
- package/SourceGenerators/global.json.meta +7 -0
- package/SourceGenerators.meta +8 -8
- package/Third Party Notices.md +3 -3
- package/Third Party Notices.md.meta +7 -7
- package/package.json +102 -92
- package/package.json.meta +7 -7
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
namespace DxMessaging.Core.Internal
|
|
2
|
+
{
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Runtime.CompilerServices;
|
|
5
|
+
using DxMessaging.Core;
|
|
6
|
+
using DxMessaging.Core.MessageBus.Internal;
|
|
7
|
+
using DxMessaging.Core.Pooling;
|
|
8
|
+
|
|
9
|
+
/// <summary>
|
|
10
|
+
/// Non-generic erasure interface over the per-delegate-shape
|
|
11
|
+
/// <c>HandlerActionCache<TDelegate></c> type currently nested in
|
|
12
|
+
/// <see cref="MessageHandler"/>. Exposes only the metadata the staged
|
|
13
|
+
/// dispatch + eviction layers need so the typed-handler-side slot grid
|
|
14
|
+
/// (<see cref="TypedSlot{T}"/>, <see cref="TypedGlobalSlot"/>) can hold
|
|
15
|
+
/// caches polymorphically across the four typed delegate shapes
|
|
16
|
+
/// (<c>Action<T></c>, <c>FastHandler<T></c>,
|
|
17
|
+
/// <c>Action<InstanceId, T></c>,
|
|
18
|
+
/// <c>FastHandlerWithContext<T></c>) plus the six global
|
|
19
|
+
/// non-generic shapes (3 kinds {<c>IUntargetedMessage</c>,
|
|
20
|
+
/// <c>ITargetedMessage</c>, <c>IBroadcastMessage</c>} times 2 variants
|
|
21
|
+
/// {<c>Default</c>, <c>Fast</c>}), 10 distinct shapes total.
|
|
22
|
+
/// </summary>
|
|
23
|
+
/// <remarks>
|
|
24
|
+
/// <para>
|
|
25
|
+
/// <c>HandlerActionCache<TDelegate></c> implements this interface
|
|
26
|
+
/// explicitly; the explicit form keeps the public field
|
|
27
|
+
/// shape on the nested cache type unchanged, so the public dispatch
|
|
28
|
+
/// surface picks up no new members from the interface retrofit.
|
|
29
|
+
/// </para>
|
|
30
|
+
/// <para>
|
|
31
|
+
/// Deliberately a thin, marker-style surface: only the five members that
|
|
32
|
+
/// staged dispatch (<see cref="Version"/>, <see cref="LastSeenVersion"/>,
|
|
33
|
+
/// <see cref="LastSeenEmissionId"/>) and eviction
|
|
34
|
+
/// (<see cref="IsEmpty"/>, <see cref="Reset"/>) require. The
|
|
35
|
+
/// <c>entries</c> dictionary and <c>cache</c> list are NOT exposed
|
|
36
|
+
/// because their generic shape is the very thing this interface erases;
|
|
37
|
+
/// dispatchers that need the typed cache down-cast at the call site.
|
|
38
|
+
/// </para>
|
|
39
|
+
/// </remarks>
|
|
40
|
+
internal interface IHandlerActionCache
|
|
41
|
+
{
|
|
42
|
+
/// <summary>
|
|
43
|
+
/// Strictly monotonic version counter for the cache's structural
|
|
44
|
+
/// state. Mirrors <c>HandlerActionCache<TDelegate>.version</c>.
|
|
45
|
+
/// Read-only on this surface; bumped internally by the cache's own
|
|
46
|
+
/// register / deregister sites and by <see cref="Reset"/>.
|
|
47
|
+
/// </summary>
|
|
48
|
+
long Version { get; }
|
|
49
|
+
|
|
50
|
+
/// <summary>
|
|
51
|
+
/// The <see cref="Version"/> value observed by the most recent
|
|
52
|
+
/// dispatcher snapshot. Mirrors
|
|
53
|
+
/// <c>HandlerActionCache<TDelegate>.lastSeenVersion</c> and is
|
|
54
|
+
/// mutated by the staged dispatch path to detect when the flat cache
|
|
55
|
+
/// list needs to be re-materialised.
|
|
56
|
+
/// </summary>
|
|
57
|
+
long LastSeenVersion { get; set; }
|
|
58
|
+
|
|
59
|
+
/// <summary>
|
|
60
|
+
/// The bus emission id of the most recent dispatch that consumed
|
|
61
|
+
/// this cache. Mirrors
|
|
62
|
+
/// <c>HandlerActionCache<TDelegate>.lastSeenEmissionId</c>.
|
|
63
|
+
/// Used by the staged dispatch staleness check. Implementations use
|
|
64
|
+
/// an invalid sentinel before the first dispatch so emission id 0
|
|
65
|
+
/// still materializes an initial snapshot.
|
|
66
|
+
/// </summary>
|
|
67
|
+
long LastSeenEmissionId { get; set; }
|
|
68
|
+
|
|
69
|
+
/// <summary>
|
|
70
|
+
/// True iff the cache currently retains zero entries. Cheap (single
|
|
71
|
+
/// integer compare against <c>entries.Count</c>); used by the
|
|
72
|
+
/// eviction sweep so empty caches can be reclaimed without walking
|
|
73
|
+
/// inner state.
|
|
74
|
+
/// </summary>
|
|
75
|
+
bool IsEmpty { get; }
|
|
76
|
+
|
|
77
|
+
/// <summary>
|
|
78
|
+
/// Eviction-driven full clear. Empties the entries dictionary and
|
|
79
|
+
/// the flat cache list, resets <see cref="LastSeenVersion"/> /
|
|
80
|
+
/// <see cref="LastSeenEmissionId"/>,
|
|
81
|
+
/// and bumps <see cref="Version"/> as the LAST step so any captured
|
|
82
|
+
/// dispatch closure that observed the prior version detects
|
|
83
|
+
/// invalidation. Idempotent.
|
|
84
|
+
/// </summary>
|
|
85
|
+
void Reset();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// <summary>
|
|
89
|
+
/// Non-generic sweep surface for <c>MessageHandler.TypedHandler<T></c>.
|
|
90
|
+
/// The owning <see cref="MessageHandler"/> stores typed handlers in a
|
|
91
|
+
/// <c>MessageCache<object></c>, so external reclamation code needs an
|
|
92
|
+
/// erased entry point that can reset empty typed slots without reflection.
|
|
93
|
+
/// </summary>
|
|
94
|
+
internal interface ITypedHandlerSlotSweeper
|
|
95
|
+
{
|
|
96
|
+
/// <summary>
|
|
97
|
+
/// Message type index for the owning typed-handler wrapper.
|
|
98
|
+
/// </summary>
|
|
99
|
+
int MessageTypeIndex { get; }
|
|
100
|
+
|
|
101
|
+
/// <summary>
|
|
102
|
+
/// True when the last sweep found no live typed slots worth
|
|
103
|
+
/// retaining and the owning <c>MessageCache</c> entry can be
|
|
104
|
+
/// removed.
|
|
105
|
+
/// </summary>
|
|
106
|
+
bool MarkedForOuterRemoval { get; }
|
|
107
|
+
|
|
108
|
+
/// <summary>
|
|
109
|
+
/// Resets every empty typed or typed-global slot and removes it from
|
|
110
|
+
/// the handler's slot arrays.
|
|
111
|
+
/// </summary>
|
|
112
|
+
/// <returns>Number of slots reset.</returns>
|
|
113
|
+
int ResetEmptySlotsForSweep();
|
|
114
|
+
|
|
115
|
+
/// <summary>
|
|
116
|
+
/// Resets every typed or typed-global slot and removes it from the
|
|
117
|
+
/// handler's slot arrays.
|
|
118
|
+
/// </summary>
|
|
119
|
+
/// <returns>Number of slots reset.</returns>
|
|
120
|
+
int ResetAllSlotsForBusReset();
|
|
121
|
+
|
|
122
|
+
/// <summary>
|
|
123
|
+
/// Counts empty typed or typed-global slots still occupying memory and
|
|
124
|
+
/// eligible for a sweep reset.
|
|
125
|
+
/// </summary>
|
|
126
|
+
/// <returns>Number of empty slots still allocated.</returns>
|
|
127
|
+
int CountEmptySlotsForSweep();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// <summary>
|
|
131
|
+
/// Per-message-type, per-<see cref="SlotKey"/> dispatch slot on the
|
|
132
|
+
/// typed-handler side. Mirrors the role of
|
|
133
|
+
/// <see cref="BusSinkSlot"/> on the bus side: holds a priority-keyed map
|
|
134
|
+
/// of <see cref="IHandlerActionCache"/>s plus the snapshot-friendly
|
|
135
|
+
/// ordered-priority list, and tracks the staged-dispatch / eviction
|
|
136
|
+
/// counters.
|
|
137
|
+
/// </summary>
|
|
138
|
+
/// <remarks>
|
|
139
|
+
/// <para>
|
|
140
|
+
/// This type is sealed because the current slot layout uses one
|
|
141
|
+
/// type-erased cache shape for every delegate variant. A future
|
|
142
|
+
/// delegate-specific fast path can promote the type to <c>abstract</c>
|
|
143
|
+
/// together with its concrete subclasses, without affecting the current
|
|
144
|
+
/// storage contract.
|
|
145
|
+
/// </para>
|
|
146
|
+
/// <para>
|
|
147
|
+
/// The context requirement is represented as a readonly field
|
|
148
|
+
/// (<see cref="requiresContext"/>) set via the constructor. The field is
|
|
149
|
+
/// <c>true</c> for
|
|
150
|
+
/// slots whose <see cref="SlotKey"/> resolves to a
|
|
151
|
+
/// <see cref="DispatchVariant"/> that carries an
|
|
152
|
+
/// <see cref="InstanceId"/> recipient or source (Targeted / Broadcast,
|
|
153
|
+
/// excluding the <c>WithoutContext</c> variants), and <c>false</c>
|
|
154
|
+
/// otherwise.
|
|
155
|
+
/// </para>
|
|
156
|
+
/// <para>
|
|
157
|
+
/// <see cref="TypedHandler{T}"/> routes storage through this slot;
|
|
158
|
+
/// the legacy named fields were deleted and the
|
|
159
|
+
/// <c>_slots[<see cref="TypedSlotIndex.Length"/>]</c> array the
|
|
160
|
+
/// storage owner.
|
|
161
|
+
/// </para>
|
|
162
|
+
/// </remarks>
|
|
163
|
+
/// <typeparam name="T">
|
|
164
|
+
/// The strongly-typed message contract this slot's parent
|
|
165
|
+
/// <see cref="TypedHandler{T}"/> binds to. The slot itself does not
|
|
166
|
+
/// reference <typeparamref name="T"/> directly today (the type-erased
|
|
167
|
+
/// <see cref="IHandlerActionCache"/> handles the per-delegate generic
|
|
168
|
+
/// shapes) -- the parameter is carried so typed storage can add a
|
|
169
|
+
/// concrete cache reference here without an additional
|
|
170
|
+
/// generic re-parameterization.
|
|
171
|
+
/// </typeparam>
|
|
172
|
+
internal sealed class TypedSlot<T> : IEvictableSlot
|
|
173
|
+
where T : IMessage
|
|
174
|
+
{
|
|
175
|
+
/// <summary>
|
|
176
|
+
/// Per-priority handler caches keyed by priority value.
|
|
177
|
+
/// <see cref="TypedHandler{T}"/> routes non-context storage through
|
|
178
|
+
/// this slot.
|
|
179
|
+
/// </summary>
|
|
180
|
+
public readonly Dictionary<int, IHandlerActionCache> byPriority = new();
|
|
181
|
+
|
|
182
|
+
/// <summary>
|
|
183
|
+
/// Insertion-ordered list of priority keys present in
|
|
184
|
+
/// <see cref="byPriority"/>. Mirrors the legacy ordered-priority
|
|
185
|
+
/// list used by the staged dispatch snapshot pattern.
|
|
186
|
+
/// </summary>
|
|
187
|
+
public readonly List<int> orderedPriorities = new();
|
|
188
|
+
|
|
189
|
+
/// <summary>Monotonic version counter for the slot's structural state.</summary>
|
|
190
|
+
public long version;
|
|
191
|
+
|
|
192
|
+
/// <summary>
|
|
193
|
+
/// The <see cref="version"/> value observed by the most recent
|
|
194
|
+
/// dispatcher snapshot. Used to decide whether the cache list needs
|
|
195
|
+
/// to be re-materialised before the next dispatch.
|
|
196
|
+
/// </summary>
|
|
197
|
+
public long lastSeenVersion = -1;
|
|
198
|
+
|
|
199
|
+
/// <summary>
|
|
200
|
+
/// The bus emission id of the most recent dispatch that consumed
|
|
201
|
+
/// this slot. Used by the staged dispatch staleness check.
|
|
202
|
+
/// </summary>
|
|
203
|
+
public long lastSeenEmissionId = -1;
|
|
204
|
+
|
|
205
|
+
/// <summary>
|
|
206
|
+
/// Bus tick counter value at the most recent register / deregister /
|
|
207
|
+
/// emit that touched this slot. Maintained by the sweep touch hook;
|
|
208
|
+
/// preserved across <see cref="Clear"/> and <see cref="Reset"/>
|
|
209
|
+
/// so the sweep can distinguish freshly-reset slots from
|
|
210
|
+
/// never-touched slots.
|
|
211
|
+
/// </summary>
|
|
212
|
+
public long lastTouchTicks;
|
|
213
|
+
|
|
214
|
+
/// <summary>
|
|
215
|
+
/// Reserved live-handler counter intended to mirror the unique
|
|
216
|
+
/// (handler, priority) pair count across every entry in
|
|
217
|
+
/// <see cref="byPriority"/>; for context-bound slots, the SUM of
|
|
218
|
+
/// (handler, priority) pair counts across every (InstanceId,
|
|
219
|
+
/// priority) leaf in <see cref="byContext"/> -- matching
|
|
220
|
+
/// <see cref="BusSinkSlot.liveCount"/> semantics so eviction logic
|
|
221
|
+
/// does not diverge between bus-side and handler-side.
|
|
222
|
+
/// <see cref="IsEmpty"/> is a single integer compare. The typed
|
|
223
|
+
/// handler maintains this counter on first-registration and
|
|
224
|
+
/// final-deregistration transitions so <see cref="IsEmpty"/>
|
|
225
|
+
/// reflects whether the slot still owns live handlers.
|
|
226
|
+
/// </summary>
|
|
227
|
+
public int liveCount;
|
|
228
|
+
|
|
229
|
+
/// <summary>
|
|
230
|
+
/// True iff this slot's <see cref="SlotKey"/> resolves to a
|
|
231
|
+
/// dispatch variant that carries an <see cref="InstanceId"/>
|
|
232
|
+
/// recipient or source (the non-<c>WithoutContext</c> Targeted and
|
|
233
|
+
/// Broadcast variants). When <c>true</c>, context-bound storage uses
|
|
234
|
+
/// <see cref="byContext"/>; when <c>false</c>, storage flows through
|
|
235
|
+
/// <see cref="byPriority"/> directly.
|
|
236
|
+
/// </summary>
|
|
237
|
+
/// <remarks>
|
|
238
|
+
/// Kept as a readonly field because <see cref="TypedSlot{T}"/> is
|
|
239
|
+
/// sealed (see class remarks).
|
|
240
|
+
/// </remarks>
|
|
241
|
+
public readonly bool requiresContext;
|
|
242
|
+
|
|
243
|
+
/// <summary>
|
|
244
|
+
/// Inner per-context map for context-bound slots. Null unless
|
|
245
|
+
/// <see cref="requiresContext"/> is <c>true</c> AND at least one
|
|
246
|
+
/// context has been registered.
|
|
247
|
+
/// </summary>
|
|
248
|
+
/// <remarks>
|
|
249
|
+
/// <para>
|
|
250
|
+
/// Lifetime semantic: <see cref="Clear"/> and <see cref="Reset"/>
|
|
251
|
+
/// return the outer context dictionary and every inner priority
|
|
252
|
+
/// dictionary to <see cref="DxPools"/> before nulling the field.
|
|
253
|
+
/// </para>
|
|
254
|
+
/// <para>
|
|
255
|
+
/// Unlike the bus-side <see cref="BusContextSlot.byContext"/>, which
|
|
256
|
+
/// is rented from <c>DxPools.InstanceIdDicts</c> as a
|
|
257
|
+
/// <c>Dictionary<InstanceId, object></c> (boxed
|
|
258
|
+
/// <see cref="BusSinkSlot"/>) for cross-message-type pool sharing,
|
|
259
|
+
/// the typed-handler-side equivalent here is a strongly-typed
|
|
260
|
+
/// <c>Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>></c>.
|
|
261
|
+
/// Both the outer context dictionary and the inner priority
|
|
262
|
+
/// dictionaries are rented from typed-handler-specific
|
|
263
|
+
/// <see cref="DxPools"/> pools.
|
|
264
|
+
/// </para>
|
|
265
|
+
/// <para>
|
|
266
|
+
/// Shape: <c>InstanceId -> (priority -> IHandlerActionCache)</c>,
|
|
267
|
+
/// with the leaf cache type-erased to <see cref="IHandlerActionCache"/>.
|
|
268
|
+
/// The inner dictionary is keyed by priority, matching the legacy
|
|
269
|
+
/// <c>Dictionary<InstanceId, Dictionary<int, HandlerActionCache<TDelegate>>></c>
|
|
270
|
+
/// layout on <c>MessageHandler.TypedHandler<T></c>. The flat
|
|
271
|
+
/// 3-level shape was chosen over the alternatives (extend
|
|
272
|
+
/// <see cref="IHandlerActionCache"/> with per-priority buckets, or
|
|
273
|
+
/// recurse with <c>Dictionary<InstanceId, TypedSlot<T>></c>)
|
|
274
|
+
/// because it preserves the legacy storage layout exactly and keeps
|
|
275
|
+
/// call sites aligned with the existing shape. The monotonic-version
|
|
276
|
+
/// drain contract on
|
|
277
|
+
/// <see cref="Reset"/> requires every inner cache to be drained through
|
|
278
|
+
/// <see cref="IHandlerActionCache.Reset"/> before the outer
|
|
279
|
+
/// container is cleared.
|
|
280
|
+
/// </para>
|
|
281
|
+
/// </remarks>
|
|
282
|
+
public Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> byContext;
|
|
283
|
+
|
|
284
|
+
/// <summary>
|
|
285
|
+
/// Constructs a <see cref="TypedSlot{T}"/> with the supplied
|
|
286
|
+
/// context-binding flag. All other fields take their default
|
|
287
|
+
/// initial values.
|
|
288
|
+
/// </summary>
|
|
289
|
+
/// <param name="requiresContext">
|
|
290
|
+
/// Value for <see cref="TypedSlot{T}.requiresContext"/>; see that
|
|
291
|
+
/// field's remarks for the semantic.
|
|
292
|
+
/// </param>
|
|
293
|
+
public TypedSlot(bool requiresContext)
|
|
294
|
+
{
|
|
295
|
+
this.requiresContext = requiresContext;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/// <inheritdoc />
|
|
299
|
+
public long LastTouchTicks
|
|
300
|
+
{
|
|
301
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
302
|
+
get => lastTouchTicks;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/// <inheritdoc />
|
|
306
|
+
public bool IsEmpty
|
|
307
|
+
{
|
|
308
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
309
|
+
get => liveCount == 0;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/// <inheritdoc />
|
|
313
|
+
public long Version
|
|
314
|
+
{
|
|
315
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
316
|
+
get => version;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/// <summary>
|
|
320
|
+
/// Full-reset semantic. Empties <see cref="byPriority"/> and
|
|
321
|
+
/// <see cref="orderedPriorities"/>, nulls out
|
|
322
|
+
/// <see cref="byContext"/>, and resets the staged-dispatch
|
|
323
|
+
/// counters. Resets <see cref="version"/> to <c>0</c>; this is NOT
|
|
324
|
+
/// monotonic and is intended only for the typed-handler analog of
|
|
325
|
+
/// <c>MessageBus.ResetState()</c> if and when that code path is
|
|
326
|
+
/// wired up. Use <see cref="Reset"/> for sweep-driven slot
|
|
327
|
+
/// reclamation.
|
|
328
|
+
/// </summary>
|
|
329
|
+
/// <remarks>
|
|
330
|
+
/// <para>
|
|
331
|
+
/// Mirrors <see cref="BusSinkSlot.Clear"/>. <see cref="byContext"/>
|
|
332
|
+
/// returns <see cref="byContext"/> and its inner priority
|
|
333
|
+
/// dictionaries to <see cref="DxPools"/>.
|
|
334
|
+
/// </para>
|
|
335
|
+
/// <para>
|
|
336
|
+
/// Unlike <see cref="BusSinkSlot.Clear"/> which drains inner buckets,
|
|
337
|
+
/// this <see cref="Clear"/> drops references only -- <see cref="Clear"/>
|
|
338
|
+
/// is intended for the typed-handler analog of
|
|
339
|
+
/// <c>MessageBus.ResetState()</c> where the entire
|
|
340
|
+
/// <see cref="MessageHandler"/> graph is being torn down, so per-cache
|
|
341
|
+
/// drain would be redundant work. <see cref="Reset"/> (eviction-driven)
|
|
342
|
+
/// DOES drain inner caches via <see cref="IHandlerActionCache.Reset"/>
|
|
343
|
+
/// because outer-version invalidation alone is insufficient when the
|
|
344
|
+
/// slot is being re-used after sweep.
|
|
345
|
+
/// </para>
|
|
346
|
+
/// </remarks>
|
|
347
|
+
public void Clear()
|
|
348
|
+
{
|
|
349
|
+
byPriority.Clear();
|
|
350
|
+
orderedPriorities.Clear();
|
|
351
|
+
ReturnContextDictionaries();
|
|
352
|
+
byContext = null;
|
|
353
|
+
version = 0;
|
|
354
|
+
lastSeenVersion = -1;
|
|
355
|
+
lastSeenEmissionId = -1;
|
|
356
|
+
liveCount = 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/// <summary>
|
|
360
|
+
/// Eviction-driven reset. Drains every inner
|
|
361
|
+
/// <see cref="IHandlerActionCache"/> held by <see cref="byPriority"/>
|
|
362
|
+
/// and <see cref="byContext"/> through
|
|
363
|
+
/// <see cref="IHandlerActionCache.Reset"/> first, then clears the
|
|
364
|
+
/// outer containers, then bumps <see cref="version"/> as the LAST
|
|
365
|
+
/// step so any captured dispatch closure that observed the prior
|
|
366
|
+
/// version detects invalidation.
|
|
367
|
+
/// <see cref="lastTouchTicks"/> is intentionally preserved so the
|
|
368
|
+
/// sweep can distinguish freshly-reset slots from never-touched
|
|
369
|
+
/// ones.
|
|
370
|
+
/// </summary>
|
|
371
|
+
/// <remarks>
|
|
372
|
+
/// Drain order is load-bearing: inner caches must be reset (and their
|
|
373
|
+
/// own monotonic versions bumped)
|
|
374
|
+
/// BEFORE the outer container is cleared, so any captured dispatch
|
|
375
|
+
/// closure observing an inner cache detects invalidation regardless
|
|
376
|
+
/// of whether the outer reference is still reachable. The outer
|
|
377
|
+
/// <see cref="version"/> bump is the LAST statement in the method
|
|
378
|
+
/// for the same reason at the slot level.
|
|
379
|
+
/// </remarks>
|
|
380
|
+
public void Reset()
|
|
381
|
+
{
|
|
382
|
+
// Inline the structural-clear body of Clear(); do NOT call
|
|
383
|
+
// Clear() because that resets version=0 and would break the
|
|
384
|
+
// monotonic invariant the eviction layer depends on: stale
|
|
385
|
+
// deregister closures captured before reset must observe a
|
|
386
|
+
// strictly larger version after reset and skip their work.
|
|
387
|
+
// Per-cache drain BEFORE the structural clear: every
|
|
388
|
+
// IHandlerActionCache.Reset() bumps its own version internally,
|
|
389
|
+
// so closures captured against the inner cache also detect
|
|
390
|
+
// invalidation -- not just closures captured against the slot.
|
|
391
|
+
foreach (KeyValuePair<int, IHandlerActionCache> kv in byPriority)
|
|
392
|
+
{
|
|
393
|
+
kv.Value?.Reset();
|
|
394
|
+
}
|
|
395
|
+
if (byContext != null)
|
|
396
|
+
{
|
|
397
|
+
foreach (
|
|
398
|
+
KeyValuePair<InstanceId, Dictionary<int, IHandlerActionCache>> ctx in byContext
|
|
399
|
+
)
|
|
400
|
+
{
|
|
401
|
+
if (ctx.Value == null)
|
|
402
|
+
{
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
foreach (KeyValuePair<int, IHandlerActionCache> kv in ctx.Value)
|
|
406
|
+
{
|
|
407
|
+
kv.Value?.Reset();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
byPriority.Clear();
|
|
412
|
+
orderedPriorities.Clear();
|
|
413
|
+
ReturnContextDictionaries();
|
|
414
|
+
byContext = null;
|
|
415
|
+
lastSeenVersion = -1;
|
|
416
|
+
lastSeenEmissionId = -1;
|
|
417
|
+
liveCount = 0;
|
|
418
|
+
unchecked
|
|
419
|
+
{
|
|
420
|
+
++version;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private void ReturnContextDictionaries()
|
|
425
|
+
{
|
|
426
|
+
if (byContext == null)
|
|
427
|
+
{
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
foreach (
|
|
432
|
+
KeyValuePair<InstanceId, Dictionary<int, IHandlerActionCache>> ctx in byContext
|
|
433
|
+
)
|
|
434
|
+
{
|
|
435
|
+
DxPools.TypedHandlerPriorityDicts.Return(ctx.Value);
|
|
436
|
+
}
|
|
437
|
+
DxPools.TypedHandlerContextDicts.Return(byContext);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/// <summary>
|
|
442
|
+
/// Per-message-type accept-all slot on the typed-handler side. Mirrors
|
|
443
|
+
/// the role of <see cref="BusGlobalSlot"/> on the bus side: holds a
|
|
444
|
+
/// single type-erased cache for the slot's
|
|
445
|
+
/// (<see cref="DispatchKind"/>, <see cref="DispatchVariant"/>)
|
|
446
|
+
/// coordinate and the staged-dispatch / eviction counters.
|
|
447
|
+
/// </summary>
|
|
448
|
+
/// <remarks>
|
|
449
|
+
/// <para>
|
|
450
|
+
/// The typed handler holds an array of 6 <see cref="TypedGlobalSlot"/>
|
|
451
|
+
/// entries. The per-(<see cref="DispatchKind"/>,
|
|
452
|
+
/// <see cref="DispatchVariant"/>) indexing scheme maps the six global
|
|
453
|
+
/// flavours (3 kinds {<c>Untargeted</c>, <c>Targeted</c>,
|
|
454
|
+
/// <c>Broadcast</c>} times 2 variants {<c>Default</c>, <c>Fast</c>}) to
|
|
455
|
+
/// array slots and is committed in <see cref="TypedGlobalSlotIndex"/>
|
|
456
|
+
/// (sibling file in the same folder). This type defines the per-slot
|
|
457
|
+
/// shape; the index file owns the layout decision.
|
|
458
|
+
/// <see cref="TypedHandler{T}"/> routes global storage through this type.
|
|
459
|
+
/// </para>
|
|
460
|
+
/// <para>
|
|
461
|
+
/// Non-generic by design: the typed handler's six legacy global
|
|
462
|
+
/// fields each carry a different non-generic delegate shape
|
|
463
|
+
/// (<c>Action<IUntargetedMessage></c>,
|
|
464
|
+
/// <c>FastHandler<IUntargetedMessage></c>,
|
|
465
|
+
/// <c>Action<InstanceId, ITargetedMessage></c>, etc.), and the
|
|
466
|
+
/// bus-side <see cref="BusGlobalSlot"/> mirrors this. The single
|
|
467
|
+
/// <see cref="cache"/> field holds an erased
|
|
468
|
+
/// <see cref="IHandlerActionCache"/> whose concrete generic shape is
|
|
469
|
+
/// determined by the slot's coordinate; dispatchers down-cast at the
|
|
470
|
+
/// call site.
|
|
471
|
+
/// </para>
|
|
472
|
+
/// <para>
|
|
473
|
+
/// Single <see cref="cache"/> field intentionally -- not three like
|
|
474
|
+
/// <see cref="BusGlobalSlot"/>'s
|
|
475
|
+
/// <c>untargetedDispatchState</c> / <c>targetedDispatchState</c> /
|
|
476
|
+
/// <c>broadcastDispatchState</c> trio. The typed-handler-side global
|
|
477
|
+
/// array is the per-kind-and-variant fan-out (six slots), so each
|
|
478
|
+
/// slot already corresponds to a single kind+variant coordinate and
|
|
479
|
+
/// holds exactly one cache.
|
|
480
|
+
/// </para>
|
|
481
|
+
/// </remarks>
|
|
482
|
+
internal sealed class TypedGlobalSlot : IEvictableSlot
|
|
483
|
+
{
|
|
484
|
+
/// <summary>
|
|
485
|
+
/// Type-erased handler cache for this slot's
|
|
486
|
+
/// (<see cref="DispatchKind"/>, <see cref="DispatchVariant"/>)
|
|
487
|
+
/// coordinate. Lazy alloc on first registration; nulled by
|
|
488
|
+
/// <see cref="Clear"/> and <see cref="Reset"/>.
|
|
489
|
+
/// </summary>
|
|
490
|
+
public IHandlerActionCache cache;
|
|
491
|
+
|
|
492
|
+
/// <summary>Monotonic version counter for the slot's structural state.</summary>
|
|
493
|
+
public long version;
|
|
494
|
+
|
|
495
|
+
/// <summary>
|
|
496
|
+
/// The <see cref="version"/> value observed by the most recent
|
|
497
|
+
/// dispatcher snapshot.
|
|
498
|
+
/// </summary>
|
|
499
|
+
public long lastSeenVersion = -1;
|
|
500
|
+
|
|
501
|
+
/// <summary>
|
|
502
|
+
/// The bus emission id of the most recent dispatch that consumed
|
|
503
|
+
/// this slot.
|
|
504
|
+
/// </summary>
|
|
505
|
+
public long lastSeenEmissionId = -1;
|
|
506
|
+
|
|
507
|
+
/// <summary>
|
|
508
|
+
/// Bus tick counter value at the most recent register / deregister /
|
|
509
|
+
/// emit that touched this slot. Maintained by the sweep touch hook;
|
|
510
|
+
/// preserved across <see cref="Clear"/> and
|
|
511
|
+
/// <see cref="Reset"/>.
|
|
512
|
+
/// </summary>
|
|
513
|
+
public long lastTouchTicks;
|
|
514
|
+
|
|
515
|
+
/// <summary>
|
|
516
|
+
/// Reserved live-handler counter intended to mirror the entry count
|
|
517
|
+
/// of <see cref="cache"/> at every stable observation point so
|
|
518
|
+
/// <see cref="IsEmpty"/> is a single integer compare rather than a
|
|
519
|
+
/// dispatch through the type-erased
|
|
520
|
+
/// <see cref="IHandlerActionCache.IsEmpty"/> property. The typed
|
|
521
|
+
/// handler maintains this counter on first-registration and
|
|
522
|
+
/// final-deregistration transitions so <see cref="IsEmpty"/>
|
|
523
|
+
/// reflects whether the slot still owns live global handlers.
|
|
524
|
+
/// </summary>
|
|
525
|
+
public int liveCount;
|
|
526
|
+
|
|
527
|
+
/// <inheritdoc />
|
|
528
|
+
public long LastTouchTicks
|
|
529
|
+
{
|
|
530
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
531
|
+
get => lastTouchTicks;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/// <inheritdoc />
|
|
535
|
+
public bool IsEmpty
|
|
536
|
+
{
|
|
537
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
538
|
+
get => liveCount == 0;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/// <inheritdoc />
|
|
542
|
+
public long Version
|
|
543
|
+
{
|
|
544
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
545
|
+
get => version;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/// <summary>
|
|
549
|
+
/// Full-reset semantic. Nulls out <see cref="cache"/> and resets
|
|
550
|
+
/// the staged-dispatch counters. Resets <see cref="version"/> to
|
|
551
|
+
/// <c>0</c>; this is NOT monotonic and is intended only for the
|
|
552
|
+
/// typed-handler analog of <c>MessageBus.ResetState()</c> if and
|
|
553
|
+
/// when that code path is wired up. Use <see cref="Reset"/> for
|
|
554
|
+
/// sweep-driven slot reclamation.
|
|
555
|
+
/// </summary>
|
|
556
|
+
public void Clear()
|
|
557
|
+
{
|
|
558
|
+
cache = null;
|
|
559
|
+
version = 0;
|
|
560
|
+
lastSeenVersion = -1;
|
|
561
|
+
lastSeenEmissionId = -1;
|
|
562
|
+
liveCount = 0;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/// <summary>
|
|
566
|
+
/// Eviction-driven reset. Drains <see cref="cache"/> through
|
|
567
|
+
/// <see cref="IHandlerActionCache.Reset"/> first, then nulls the
|
|
568
|
+
/// reference, then bumps <see cref="version"/> as the LAST step so
|
|
569
|
+
/// any captured dispatch closure that observed the prior version
|
|
570
|
+
/// detects invalidation.
|
|
571
|
+
/// <see cref="lastTouchTicks"/> is intentionally preserved.
|
|
572
|
+
/// </summary>
|
|
573
|
+
/// <remarks>
|
|
574
|
+
/// Drain order is load-bearing: the inner cache's own monotonic
|
|
575
|
+
/// version is bumped BEFORE the slot
|
|
576
|
+
/// drops the reference, so closures captured against the inner
|
|
577
|
+
/// cache also detect invalidation. The outer <see cref="version"/>
|
|
578
|
+
/// bump is the LAST statement in the method for the same reason at
|
|
579
|
+
/// the slot level.
|
|
580
|
+
/// </remarks>
|
|
581
|
+
public void Reset()
|
|
582
|
+
{
|
|
583
|
+
// Inline the structural-clear body of Clear(); do NOT call
|
|
584
|
+
// Clear() because that resets version=0 and would break the
|
|
585
|
+
// monotonic invariant the eviction layer depends on.
|
|
586
|
+
cache?.Reset();
|
|
587
|
+
cache = null;
|
|
588
|
+
lastSeenVersion = -1;
|
|
589
|
+
lastSeenEmissionId = -1;
|
|
590
|
+
liveCount = 0;
|
|
591
|
+
unchecked
|
|
592
|
+
{
|
|
593
|
+
++version;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
fileFormatVersion: 2
|
|
2
|
-
guid: d2ff6bbe0b187ff4ab1051164b721d67
|
|
3
|
-
MonoImporter:
|
|
4
|
-
externalObjects: {}
|
|
5
|
-
serializedVersion: 2
|
|
6
|
-
defaultReferences: []
|
|
7
|
-
executionOrder: 0
|
|
8
|
-
icon: {instanceID: 0}
|
|
9
|
-
userData:
|
|
10
|
-
assetBundleName:
|
|
11
|
-
assetBundleVariant:
|
|
1
|
+
fileFormatVersion: 2
|
|
2
|
+
guid: d2ff6bbe0b187ff4ab1051164b721d67
|
|
3
|
+
MonoImporter:
|
|
4
|
+
externalObjects: {}
|
|
5
|
+
serializedVersion: 2
|
|
6
|
+
defaultReferences: []
|
|
7
|
+
executionOrder: 0
|
|
8
|
+
icon: {instanceID: 0}
|
|
9
|
+
userData:
|
|
10
|
+
assetBundleName:
|
|
11
|
+
assetBundleVariant:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
fileFormatVersion: 2
|
|
2
|
-
guid: 45218d07f193b154a9aa56435fcbb83d
|
|
3
|
-
MonoImporter:
|
|
4
|
-
externalObjects: {}
|
|
5
|
-
serializedVersion: 2
|
|
6
|
-
defaultReferences: []
|
|
7
|
-
executionOrder: 0
|
|
8
|
-
icon: {instanceID: 0}
|
|
9
|
-
userData:
|
|
10
|
-
assetBundleName:
|
|
11
|
-
assetBundleVariant:
|
|
1
|
+
fileFormatVersion: 2
|
|
2
|
+
guid: 45218d07f193b154a9aa56435fcbb83d
|
|
3
|
+
MonoImporter:
|
|
4
|
+
externalObjects: {}
|
|
5
|
+
serializedVersion: 2
|
|
6
|
+
defaultReferences: []
|
|
7
|
+
executionOrder: 0
|
|
8
|
+
icon: {instanceID: 0}
|
|
9
|
+
userData:
|
|
10
|
+
assetBundleName:
|
|
11
|
+
assetBundleVariant:
|