com.wallstop-studios.dxmessaging 2.1.9 → 3.0.1
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 +106 -65
- 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 +1122 -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 +33 -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 +3 -3
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +81 -0
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs.meta +11 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +420 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs.meta +11 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +1 -1
- package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +2 -2
- package/Editor/CustomEditors.meta +2 -2
- package/Editor/DxMessagingEditorInitializer.cs +1 -1
- package/Editor/DxMessagingEditorInitializer.cs.meta +2 -2
- package/Editor/DxMessagingMenu.cs.meta +11 -11
- package/Editor/DxMessagingSceneBuildProcessor.cs.meta +11 -11
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +190 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs.meta +11 -0
- package/Editor/Settings/DxMessagingSettings.cs +189 -0
- package/Editor/Settings/DxMessagingSettings.cs.meta +2 -2
- package/Editor/Settings/DxMessagingSettingsProvider.cs +50 -33
- package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +2 -2
- package/Editor/Settings.meta +2 -2
- package/Editor/SetupCscRsp.cs +209 -8
- package/Editor/SetupCscRsp.cs.meta +2 -2
- package/Editor/Testing/MessagingComponentEditorHarness.cs +1 -1
- package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +3 -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 +941 -900
- package/README.md.meta +7 -7
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/AssemblyInfo.cs.meta +2 -2
- package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs +26 -0
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +2 -2
- 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 +2 -2
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +2 -2
- package/Runtime/Core/DataStructure.meta +2 -2
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +2 -2
- package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +2 -2
- package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +2 -2
- 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.meta +2 -2
- package/Runtime/Core/Extensions/IListExtensions.cs.meta +2 -2
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -12
- 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 +2 -2
- package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +2 -2
- 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.meta +11 -11
- package/Runtime/Core/Internal/TypedDispatchLinkIndex.cs +51 -0
- package/Runtime/Core/Internal/TypedDispatchLinkIndex.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 +613 -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 +177 -3
- package/Runtime/Core/MessageBus/IMessageBus.cs.meta +11 -11
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -11
- 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 +718 -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 +2651 -500
- package/Runtime/Core/MessageBus/MessageBus.cs.meta +11 -11
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -11
- 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 +2019 -542
- package/Runtime/Core/MessageHandler.cs.meta +11 -11
- package/Runtime/Core/MessageRegistrationHandle.cs.meta +11 -11
- package/Runtime/Core/MessageRegistrationToken.cs +7 -0
- package/Runtime/Core/MessageRegistrationToken.cs.meta +11 -11
- package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +2 -2
- 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 +2 -2
- package/Runtime/Core/Messages/SourcedStringMessage.cs.meta +11 -11
- package/Runtime/Core/Messages/StringMessage.cs.meta +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +29 -0
- package/Runtime/Unity/MessageAwareComponent.cs.meta +11 -11
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -12
- 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.meta +7 -7
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs.meta +11 -11
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +2 -2
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj.meta +7 -7
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.meta +8 -8
- package/SourceGenerators.meta +8 -8
- package/Third Party Notices.md +3 -3
- package/Third Party Notices.md.meta +7 -7
- package/package.json +115 -92
- package/package.json.meta +7 -7
|
@@ -2,10 +2,13 @@ namespace DxMessaging.Core
|
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Generic;
|
|
5
|
+
using System.Diagnostics;
|
|
5
6
|
using System.Runtime.CompilerServices;
|
|
7
|
+
using DxMessaging.Core.Internal;
|
|
6
8
|
using Helper;
|
|
7
9
|
using MessageBus;
|
|
8
10
|
using Messages;
|
|
11
|
+
using Pooling;
|
|
9
12
|
|
|
10
13
|
/// <summary>
|
|
11
14
|
/// Per-owner handler that executes registered message callbacks.
|
|
@@ -34,6 +37,76 @@ namespace DxMessaging.Core
|
|
|
34
37
|
IComparable,
|
|
35
38
|
IComparable<MessageHandler>
|
|
36
39
|
{
|
|
40
|
+
private static void PrefreezePriorityCache<TMessage, THandler>(
|
|
41
|
+
TypedHandler<TMessage> handler,
|
|
42
|
+
int slotIndex,
|
|
43
|
+
int priority,
|
|
44
|
+
long emissionId
|
|
45
|
+
)
|
|
46
|
+
where TMessage : IMessage
|
|
47
|
+
{
|
|
48
|
+
Dictionary<int, IHandlerActionCache> byPriority = handler.GetPriorityHandlers(
|
|
49
|
+
slotIndex
|
|
50
|
+
);
|
|
51
|
+
if (
|
|
52
|
+
byPriority != null
|
|
53
|
+
&& byPriority.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
54
|
+
&& erasedCache is HandlerActionCache<THandler> cache
|
|
55
|
+
)
|
|
56
|
+
{
|
|
57
|
+
_ = TypedHandler<TMessage>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
58
|
+
cache.prefreezeInvocationCount++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private static void PrefreezeContextCache<TMessage, THandler>(
|
|
63
|
+
TypedHandler<TMessage> handler,
|
|
64
|
+
int slotIndex,
|
|
65
|
+
InstanceId context,
|
|
66
|
+
int priority,
|
|
67
|
+
long emissionId
|
|
68
|
+
)
|
|
69
|
+
where TMessage : IMessage
|
|
70
|
+
{
|
|
71
|
+
Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> byContext =
|
|
72
|
+
handler.GetContextHandlers(slotIndex);
|
|
73
|
+
if (
|
|
74
|
+
byContext != null
|
|
75
|
+
&& byContext.TryGetValue(
|
|
76
|
+
context,
|
|
77
|
+
out Dictionary<int, IHandlerActionCache> byPriority
|
|
78
|
+
)
|
|
79
|
+
&& byPriority.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
80
|
+
&& erasedCache is HandlerActionCache<THandler> cache
|
|
81
|
+
)
|
|
82
|
+
{
|
|
83
|
+
_ = TypedHandler<TMessage>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
84
|
+
cache.prefreezeInvocationCount++;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private static int GetPriorityPrefreezeInvocationCount<TMessage, THandler>(
|
|
89
|
+
TypedHandler<TMessage> handler,
|
|
90
|
+
int slotIndex,
|
|
91
|
+
int priority
|
|
92
|
+
)
|
|
93
|
+
where TMessage : IMessage
|
|
94
|
+
{
|
|
95
|
+
Dictionary<int, IHandlerActionCache> byPriority = handler.GetPriorityHandlers(
|
|
96
|
+
slotIndex
|
|
97
|
+
);
|
|
98
|
+
if (
|
|
99
|
+
byPriority != null
|
|
100
|
+
&& byPriority.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
101
|
+
&& erasedCache is HandlerActionCache<THandler> cache
|
|
102
|
+
)
|
|
103
|
+
{
|
|
104
|
+
return cache.prefreezeInvocationCount;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
37
110
|
/// <summary>
|
|
38
111
|
/// Pre-freezes this handler's broadcast post-processor caches for the given message type, source, and priority
|
|
39
112
|
/// for the specified emission id, so registrations during the same emission are not observed.
|
|
@@ -56,32 +129,20 @@ namespace DxMessaging.Core
|
|
|
56
129
|
return;
|
|
57
130
|
}
|
|
58
131
|
|
|
59
|
-
|
|
60
|
-
handler
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
handler._broadcastPostProcessingHandlers != null
|
|
76
|
-
&& handler._broadcastPostProcessingHandlers.TryGetValue(
|
|
77
|
-
source,
|
|
78
|
-
out Dictionary<int, HandlerActionCache<Action<T>>> byPriority
|
|
79
|
-
)
|
|
80
|
-
&& byPriority.TryGetValue(priority, out HandlerActionCache<Action<T>> cache)
|
|
81
|
-
)
|
|
82
|
-
{
|
|
83
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
84
|
-
}
|
|
132
|
+
PrefreezeContextCache<T, FastHandler<T>>(
|
|
133
|
+
handler,
|
|
134
|
+
TypedSlotIndex.BroadcastPostProcessFast,
|
|
135
|
+
source,
|
|
136
|
+
priority,
|
|
137
|
+
emissionId
|
|
138
|
+
);
|
|
139
|
+
PrefreezeContextCache<T, Action<T>>(
|
|
140
|
+
handler,
|
|
141
|
+
TypedSlotIndex.BroadcastPostProcessDefault,
|
|
142
|
+
source,
|
|
143
|
+
priority,
|
|
144
|
+
emissionId
|
|
145
|
+
);
|
|
85
146
|
}
|
|
86
147
|
|
|
87
148
|
/// <summary>
|
|
@@ -106,32 +167,20 @@ namespace DxMessaging.Core
|
|
|
106
167
|
return;
|
|
107
168
|
}
|
|
108
169
|
|
|
109
|
-
|
|
110
|
-
handler
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
handler._targetedPostProcessingHandlers != null
|
|
126
|
-
&& handler._targetedPostProcessingHandlers.TryGetValue(
|
|
127
|
-
target,
|
|
128
|
-
out Dictionary<int, HandlerActionCache<Action<T>>> byPriority
|
|
129
|
-
)
|
|
130
|
-
&& byPriority.TryGetValue(priority, out HandlerActionCache<Action<T>> cache)
|
|
131
|
-
)
|
|
132
|
-
{
|
|
133
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
134
|
-
}
|
|
170
|
+
PrefreezeContextCache<T, FastHandler<T>>(
|
|
171
|
+
handler,
|
|
172
|
+
TypedSlotIndex.TargetedPostProcessFast,
|
|
173
|
+
target,
|
|
174
|
+
priority,
|
|
175
|
+
emissionId
|
|
176
|
+
);
|
|
177
|
+
PrefreezeContextCache<T, Action<T>>(
|
|
178
|
+
handler,
|
|
179
|
+
TypedSlotIndex.TargetedPostProcessDefault,
|
|
180
|
+
target,
|
|
181
|
+
priority,
|
|
182
|
+
emissionId
|
|
183
|
+
);
|
|
135
184
|
}
|
|
136
185
|
|
|
137
186
|
/// <summary>
|
|
@@ -150,27 +199,18 @@ namespace DxMessaging.Core
|
|
|
150
199
|
return;
|
|
151
200
|
}
|
|
152
201
|
|
|
153
|
-
|
|
154
|
-
handler
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
handler._targetedWithoutTargetingHandlers != null
|
|
166
|
-
&& handler._targetedWithoutTargetingHandlers.TryGetValue(
|
|
167
|
-
priority,
|
|
168
|
-
out HandlerActionCache<Action<InstanceId, T>> cache
|
|
169
|
-
)
|
|
170
|
-
)
|
|
171
|
-
{
|
|
172
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
173
|
-
}
|
|
202
|
+
PrefreezePriorityCache<T, FastHandlerWithContext<T>>(
|
|
203
|
+
handler,
|
|
204
|
+
TypedSlotIndex.TargetedHandleWithoutContextFast,
|
|
205
|
+
priority,
|
|
206
|
+
emissionId
|
|
207
|
+
);
|
|
208
|
+
PrefreezePriorityCache<T, Action<InstanceId, T>>(
|
|
209
|
+
handler,
|
|
210
|
+
TypedSlotIndex.TargetedHandleWithoutContext,
|
|
211
|
+
priority,
|
|
212
|
+
emissionId
|
|
213
|
+
);
|
|
174
214
|
}
|
|
175
215
|
|
|
176
216
|
/// <summary>
|
|
@@ -188,27 +228,18 @@ namespace DxMessaging.Core
|
|
|
188
228
|
return;
|
|
189
229
|
}
|
|
190
230
|
|
|
191
|
-
|
|
192
|
-
handler
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
handler._targetedWithoutTargetingPostProcessingHandlers != null
|
|
204
|
-
&& handler._targetedWithoutTargetingPostProcessingHandlers.TryGetValue(
|
|
205
|
-
priority,
|
|
206
|
-
out HandlerActionCache<Action<InstanceId, T>> cache
|
|
207
|
-
)
|
|
208
|
-
)
|
|
209
|
-
{
|
|
210
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
211
|
-
}
|
|
231
|
+
PrefreezePriorityCache<T, FastHandlerWithContext<T>>(
|
|
232
|
+
handler,
|
|
233
|
+
TypedSlotIndex.TargetedPostProcessWithoutContextFast,
|
|
234
|
+
priority,
|
|
235
|
+
emissionId
|
|
236
|
+
);
|
|
237
|
+
PrefreezePriorityCache<T, Action<InstanceId, T>>(
|
|
238
|
+
handler,
|
|
239
|
+
TypedSlotIndex.TargetedPostProcessWithoutContext,
|
|
240
|
+
priority,
|
|
241
|
+
emissionId
|
|
242
|
+
);
|
|
212
243
|
}
|
|
213
244
|
|
|
214
245
|
/// <summary>
|
|
@@ -226,27 +257,18 @@ namespace DxMessaging.Core
|
|
|
226
257
|
return;
|
|
227
258
|
}
|
|
228
259
|
|
|
229
|
-
|
|
230
|
-
handler
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
handler._untargetedPostProcessingHandlers != null
|
|
242
|
-
&& handler._untargetedPostProcessingHandlers.TryGetValue(
|
|
243
|
-
priority,
|
|
244
|
-
out HandlerActionCache<Action<T>> cache
|
|
245
|
-
)
|
|
246
|
-
)
|
|
247
|
-
{
|
|
248
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
249
|
-
}
|
|
260
|
+
PrefreezePriorityCache<T, FastHandler<T>>(
|
|
261
|
+
handler,
|
|
262
|
+
TypedSlotIndex.UntargetedPostProcessFast,
|
|
263
|
+
priority,
|
|
264
|
+
emissionId
|
|
265
|
+
);
|
|
266
|
+
PrefreezePriorityCache<T, Action<T>>(
|
|
267
|
+
handler,
|
|
268
|
+
TypedSlotIndex.UntargetedPostProcessDefault,
|
|
269
|
+
priority,
|
|
270
|
+
emissionId
|
|
271
|
+
);
|
|
250
272
|
}
|
|
251
273
|
|
|
252
274
|
/// <summary>
|
|
@@ -264,27 +286,18 @@ namespace DxMessaging.Core
|
|
|
264
286
|
return;
|
|
265
287
|
}
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
handler
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
handler._broadcastWithoutSourcePostProcessingHandlers != null
|
|
280
|
-
&& handler._broadcastWithoutSourcePostProcessingHandlers.TryGetValue(
|
|
281
|
-
priority,
|
|
282
|
-
out HandlerActionCache<Action<InstanceId, T>> cache
|
|
283
|
-
)
|
|
284
|
-
)
|
|
285
|
-
{
|
|
286
|
-
_ = TypedHandler<T>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
287
|
-
}
|
|
289
|
+
PrefreezePriorityCache<T, FastHandlerWithContext<T>>(
|
|
290
|
+
handler,
|
|
291
|
+
TypedSlotIndex.BroadcastPostProcessWithoutContextFast,
|
|
292
|
+
priority,
|
|
293
|
+
emissionId
|
|
294
|
+
);
|
|
295
|
+
PrefreezePriorityCache<T, Action<InstanceId, T>>(
|
|
296
|
+
handler,
|
|
297
|
+
TypedSlotIndex.BroadcastPostProcessWithoutContext,
|
|
298
|
+
priority,
|
|
299
|
+
emissionId
|
|
300
|
+
);
|
|
288
301
|
}
|
|
289
302
|
|
|
290
303
|
/// <summary>
|
|
@@ -307,27 +320,128 @@ namespace DxMessaging.Core
|
|
|
307
320
|
return;
|
|
308
321
|
}
|
|
309
322
|
|
|
310
|
-
|
|
311
|
-
handler
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
323
|
+
PrefreezePriorityCache<T, FastHandlerWithContext<T>>(
|
|
324
|
+
handler,
|
|
325
|
+
TypedSlotIndex.BroadcastHandleWithoutContextFast,
|
|
326
|
+
priority,
|
|
327
|
+
emissionId
|
|
328
|
+
);
|
|
329
|
+
PrefreezePriorityCache<T, Action<InstanceId, T>>(
|
|
330
|
+
handler,
|
|
331
|
+
TypedSlotIndex.BroadcastHandleWithoutContext,
|
|
332
|
+
priority,
|
|
333
|
+
emissionId
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/// <summary>
|
|
338
|
+
/// Pre-freezes this handler's untargeted handler caches for the given message type and priority
|
|
339
|
+
/// for the specified emission id, so removals during the same emission are not observed.
|
|
340
|
+
/// </summary>
|
|
341
|
+
/// <typeparam name="T">Untargeted message type.</typeparam>
|
|
342
|
+
/// <param name="priority">Priority bucket to freeze.</param>
|
|
343
|
+
/// <param name="emissionId">Current emission id.</param>
|
|
344
|
+
/// <param name="messageBus">Bus whose typed handler mapping to use.</param>
|
|
345
|
+
internal void PrefreezeUntargetedHandlersForEmission<T>(
|
|
346
|
+
int priority,
|
|
347
|
+
long emissionId,
|
|
348
|
+
IMessageBus messageBus
|
|
349
|
+
)
|
|
350
|
+
where T : IUntargetedMessage
|
|
351
|
+
{
|
|
352
|
+
if (!GetHandlerForType(messageBus, out TypedHandler<T> handler))
|
|
317
353
|
{
|
|
318
|
-
|
|
354
|
+
return;
|
|
319
355
|
}
|
|
320
356
|
|
|
321
|
-
|
|
322
|
-
handler
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
357
|
+
PrefreezePriorityCache<T, FastHandler<T>>(
|
|
358
|
+
handler,
|
|
359
|
+
TypedSlotIndex.UntargetedHandleFast,
|
|
360
|
+
priority,
|
|
361
|
+
emissionId
|
|
362
|
+
);
|
|
363
|
+
PrefreezePriorityCache<T, Action<T>>(
|
|
364
|
+
handler,
|
|
365
|
+
TypedSlotIndex.UntargetedHandleDefault,
|
|
366
|
+
priority,
|
|
367
|
+
emissionId
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/// <summary>
|
|
372
|
+
/// Pre-freezes this handler's targeted handler caches for the given message type, target, and priority
|
|
373
|
+
/// for the specified emission id, so removals during the same emission are not observed.
|
|
374
|
+
/// </summary>
|
|
375
|
+
/// <typeparam name="T">Targeted message type.</typeparam>
|
|
376
|
+
/// <param name="target">Target instance id.</param>
|
|
377
|
+
/// <param name="priority">Priority bucket to freeze.</param>
|
|
378
|
+
/// <param name="emissionId">Current emission id.</param>
|
|
379
|
+
/// <param name="messageBus">Bus whose typed handler mapping to use.</param>
|
|
380
|
+
internal void PrefreezeTargetedHandlersForEmission<T>(
|
|
381
|
+
InstanceId target,
|
|
382
|
+
int priority,
|
|
383
|
+
long emissionId,
|
|
384
|
+
IMessageBus messageBus
|
|
385
|
+
)
|
|
386
|
+
where T : ITargetedMessage
|
|
387
|
+
{
|
|
388
|
+
if (!GetHandlerForType(messageBus, out TypedHandler<T> handler))
|
|
389
|
+
{
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
PrefreezeContextCache<T, FastHandler<T>>(
|
|
394
|
+
handler,
|
|
395
|
+
TypedSlotIndex.TargetedHandleFast,
|
|
396
|
+
target,
|
|
397
|
+
priority,
|
|
398
|
+
emissionId
|
|
399
|
+
);
|
|
400
|
+
PrefreezeContextCache<T, Action<T>>(
|
|
401
|
+
handler,
|
|
402
|
+
TypedSlotIndex.TargetedHandleDefault,
|
|
403
|
+
target,
|
|
404
|
+
priority,
|
|
405
|
+
emissionId
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/// <summary>
|
|
410
|
+
/// Pre-freezes this handler's broadcast handler caches for the given message type, source, and priority
|
|
411
|
+
/// for the specified emission id, so removals during the same emission are not observed.
|
|
412
|
+
/// </summary>
|
|
413
|
+
/// <typeparam name="T">Broadcast message type.</typeparam>
|
|
414
|
+
/// <param name="source">Source instance id.</param>
|
|
415
|
+
/// <param name="priority">Priority bucket to freeze.</param>
|
|
416
|
+
/// <param name="emissionId">Current emission id.</param>
|
|
417
|
+
/// <param name="messageBus">Bus whose typed handler mapping to use.</param>
|
|
418
|
+
internal void PrefreezeBroadcastHandlersForEmission<T>(
|
|
419
|
+
InstanceId source,
|
|
420
|
+
int priority,
|
|
421
|
+
long emissionId,
|
|
422
|
+
IMessageBus messageBus
|
|
423
|
+
)
|
|
424
|
+
where T : IBroadcastMessage
|
|
425
|
+
{
|
|
426
|
+
if (!GetHandlerForType(messageBus, out TypedHandler<T> handler))
|
|
328
427
|
{
|
|
329
|
-
|
|
428
|
+
return;
|
|
330
429
|
}
|
|
430
|
+
|
|
431
|
+
PrefreezeContextCache<T, FastHandler<T>>(
|
|
432
|
+
handler,
|
|
433
|
+
TypedSlotIndex.BroadcastHandleFast,
|
|
434
|
+
source,
|
|
435
|
+
priority,
|
|
436
|
+
emissionId
|
|
437
|
+
);
|
|
438
|
+
PrefreezeContextCache<T, Action<T>>(
|
|
439
|
+
handler,
|
|
440
|
+
TypedSlotIndex.BroadcastHandleDefault,
|
|
441
|
+
source,
|
|
442
|
+
priority,
|
|
443
|
+
emissionId
|
|
444
|
+
);
|
|
331
445
|
}
|
|
332
446
|
|
|
333
447
|
/// <summary>
|
|
@@ -378,6 +492,19 @@ namespace DxMessaging.Core
|
|
|
378
492
|
ResetStatics();
|
|
379
493
|
}
|
|
380
494
|
|
|
495
|
+
/// <summary>
|
|
496
|
+
/// Reclaims empty slots and pooled collections owned by the current global message bus.
|
|
497
|
+
/// </summary>
|
|
498
|
+
/// <param name="force">
|
|
499
|
+
/// When true, ignores idle-age thresholds and drains shared pools to zero.
|
|
500
|
+
/// When false, only slots past the configured idle threshold are eligible.
|
|
501
|
+
/// </param>
|
|
502
|
+
/// <returns>Counts describing what was reclaimed.</returns>
|
|
503
|
+
public static IMessageBus.TrimResult TrimAll(bool force = false)
|
|
504
|
+
{
|
|
505
|
+
return MessageBus.Trim(force);
|
|
506
|
+
}
|
|
507
|
+
|
|
381
508
|
/// <summary>
|
|
382
509
|
/// Replaces the global <see cref="Core.MessageBus.MessageBus"/> instance returned by <see cref="MessageBus"/>.
|
|
383
510
|
/// </summary>
|
|
@@ -928,19 +1055,19 @@ namespace DxMessaging.Core
|
|
|
928
1055
|
return;
|
|
929
1056
|
}
|
|
930
1057
|
|
|
931
|
-
|
|
1058
|
+
HandlerActionCache<FastHandler<IUntargetedMessage>> fastCache = handler.GetGlobalCache<
|
|
1059
|
+
FastHandler<IUntargetedMessage>
|
|
1060
|
+
>(TypedGlobalSlotIndex.UntargetedFast);
|
|
1061
|
+
if (fastCache != null)
|
|
932
1062
|
{
|
|
933
|
-
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(
|
|
934
|
-
handler._globalUntargetedFastHandlers,
|
|
935
|
-
emissionId
|
|
936
|
-
);
|
|
1063
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(fastCache, emissionId);
|
|
937
1064
|
}
|
|
938
|
-
|
|
1065
|
+
HandlerActionCache<Action<IUntargetedMessage>> cache = handler.GetGlobalCache<
|
|
1066
|
+
Action<IUntargetedMessage>
|
|
1067
|
+
>(TypedGlobalSlotIndex.UntargetedDefault);
|
|
1068
|
+
if (cache != null)
|
|
939
1069
|
{
|
|
940
|
-
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(
|
|
941
|
-
handler._globalUntargetedHandlers,
|
|
942
|
-
emissionId
|
|
943
|
-
);
|
|
1070
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
944
1071
|
}
|
|
945
1072
|
}
|
|
946
1073
|
|
|
@@ -954,19 +1081,20 @@ namespace DxMessaging.Core
|
|
|
954
1081
|
return;
|
|
955
1082
|
}
|
|
956
1083
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
handler._globalTargetedFastHandlers,
|
|
961
|
-
emissionId
|
|
1084
|
+
HandlerActionCache<FastHandlerWithContext<ITargetedMessage>> fastCache =
|
|
1085
|
+
handler.GetGlobalCache<FastHandlerWithContext<ITargetedMessage>>(
|
|
1086
|
+
TypedGlobalSlotIndex.TargetedFast
|
|
962
1087
|
);
|
|
1088
|
+
if (fastCache != null)
|
|
1089
|
+
{
|
|
1090
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(fastCache, emissionId);
|
|
963
1091
|
}
|
|
964
|
-
|
|
1092
|
+
HandlerActionCache<Action<InstanceId, ITargetedMessage>> cache = handler.GetGlobalCache<
|
|
1093
|
+
Action<InstanceId, ITargetedMessage>
|
|
1094
|
+
>(TypedGlobalSlotIndex.TargetedDefault);
|
|
1095
|
+
if (cache != null)
|
|
965
1096
|
{
|
|
966
|
-
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(
|
|
967
|
-
handler._globalTargetedHandlers,
|
|
968
|
-
emissionId
|
|
969
|
-
);
|
|
1097
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
970
1098
|
}
|
|
971
1099
|
}
|
|
972
1100
|
|
|
@@ -980,19 +1108,21 @@ namespace DxMessaging.Core
|
|
|
980
1108
|
return;
|
|
981
1109
|
}
|
|
982
1110
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
handler._globalBroadcastFastHandlers,
|
|
987
|
-
emissionId
|
|
1111
|
+
HandlerActionCache<FastHandlerWithContext<IBroadcastMessage>> fastCache =
|
|
1112
|
+
handler.GetGlobalCache<FastHandlerWithContext<IBroadcastMessage>>(
|
|
1113
|
+
TypedGlobalSlotIndex.BroadcastFast
|
|
988
1114
|
);
|
|
989
|
-
|
|
990
|
-
if (handler._globalBroadcastHandlers != null)
|
|
1115
|
+
if (fastCache != null)
|
|
991
1116
|
{
|
|
992
|
-
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(
|
|
993
|
-
|
|
994
|
-
|
|
1117
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(fastCache, emissionId);
|
|
1118
|
+
}
|
|
1119
|
+
HandlerActionCache<Action<InstanceId, IBroadcastMessage>> cache =
|
|
1120
|
+
handler.GetGlobalCache<Action<InstanceId, IBroadcastMessage>>(
|
|
1121
|
+
TypedGlobalSlotIndex.BroadcastDefault
|
|
995
1122
|
);
|
|
1123
|
+
if (cache != null)
|
|
1124
|
+
{
|
|
1125
|
+
_ = TypedHandler<IMessage>.GetOrAddNewHandlerStack(cache, emissionId);
|
|
996
1126
|
}
|
|
997
1127
|
}
|
|
998
1128
|
|
|
@@ -1071,25 +1201,28 @@ namespace DxMessaging.Core
|
|
|
1071
1201
|
Action untargetedDeregistration = typedHandler.AddGlobalUntargetedHandler(
|
|
1072
1202
|
originalUntargetedMessageHandler,
|
|
1073
1203
|
untargetedMessageHandler,
|
|
1074
|
-
NullDeregistration
|
|
1204
|
+
NullDeregistration,
|
|
1205
|
+
messageBus
|
|
1075
1206
|
);
|
|
1076
1207
|
Action targetedDeregistration = typedHandler.AddGlobalTargetedHandler(
|
|
1077
1208
|
originalTargetedMessageHandler,
|
|
1078
1209
|
targetedMessageHandler,
|
|
1079
|
-
NullDeregistration
|
|
1210
|
+
NullDeregistration,
|
|
1211
|
+
messageBus
|
|
1080
1212
|
);
|
|
1081
1213
|
Action broadcastDeregistration = typedHandler.AddGlobalBroadcastHandler(
|
|
1082
1214
|
originalBroadcastMessageHandler,
|
|
1083
1215
|
broadcastMessageHandler,
|
|
1084
|
-
NullDeregistration
|
|
1216
|
+
NullDeregistration,
|
|
1217
|
+
messageBus
|
|
1085
1218
|
);
|
|
1086
1219
|
|
|
1087
1220
|
return () =>
|
|
1088
1221
|
{
|
|
1222
|
+
messageBusDeregistration?.Invoke();
|
|
1089
1223
|
untargetedDeregistration();
|
|
1090
1224
|
targetedDeregistration();
|
|
1091
1225
|
broadcastDeregistration();
|
|
1092
|
-
messageBusDeregistration?.Invoke();
|
|
1093
1226
|
};
|
|
1094
1227
|
|
|
1095
1228
|
void NullDeregistration()
|
|
@@ -1123,25 +1256,28 @@ namespace DxMessaging.Core
|
|
|
1123
1256
|
Action untargetedDeregistration = typedHandler.AddGlobalUntargetedHandler(
|
|
1124
1257
|
originalUntargetedMessageHandler,
|
|
1125
1258
|
untargetedMessageHandler,
|
|
1126
|
-
NullDeregistration
|
|
1259
|
+
NullDeregistration,
|
|
1260
|
+
messageBus
|
|
1127
1261
|
);
|
|
1128
1262
|
Action targetedDeregistration = typedHandler.AddGlobalTargetedHandler(
|
|
1129
1263
|
originalTargetedMessageHandler,
|
|
1130
1264
|
targetedMessageHandler,
|
|
1131
|
-
NullDeregistration
|
|
1265
|
+
NullDeregistration,
|
|
1266
|
+
messageBus
|
|
1132
1267
|
);
|
|
1133
1268
|
Action broadcastDeregistration = typedHandler.AddGlobalBroadcastHandler(
|
|
1134
1269
|
originalBroadcastMessageHandler,
|
|
1135
1270
|
broadcastMessageHandler,
|
|
1136
|
-
NullDeregistration
|
|
1271
|
+
NullDeregistration,
|
|
1272
|
+
messageBus
|
|
1137
1273
|
);
|
|
1138
1274
|
|
|
1139
1275
|
return () =>
|
|
1140
1276
|
{
|
|
1277
|
+
messageBusDeregistration?.Invoke();
|
|
1141
1278
|
untargetedDeregistration();
|
|
1142
1279
|
targetedDeregistration();
|
|
1143
1280
|
broadcastDeregistration();
|
|
1144
|
-
messageBusDeregistration?.Invoke();
|
|
1145
1281
|
};
|
|
1146
1282
|
|
|
1147
1283
|
void NullDeregistration()
|
|
@@ -1181,7 +1317,7 @@ namespace DxMessaging.Core
|
|
|
1181
1317
|
messageHandler,
|
|
1182
1318
|
messageBusDeregistration,
|
|
1183
1319
|
priority,
|
|
1184
|
-
messageBus
|
|
1320
|
+
messageBus
|
|
1185
1321
|
);
|
|
1186
1322
|
}
|
|
1187
1323
|
|
|
@@ -1216,7 +1352,7 @@ namespace DxMessaging.Core
|
|
|
1216
1352
|
messageHandler,
|
|
1217
1353
|
messageBusDeregistration,
|
|
1218
1354
|
priority,
|
|
1219
|
-
messageBus
|
|
1355
|
+
messageBus
|
|
1220
1356
|
);
|
|
1221
1357
|
}
|
|
1222
1358
|
|
|
@@ -1251,7 +1387,7 @@ namespace DxMessaging.Core
|
|
|
1251
1387
|
messageHandler,
|
|
1252
1388
|
messageBusDeregistration,
|
|
1253
1389
|
priority,
|
|
1254
|
-
messageBus
|
|
1390
|
+
messageBus
|
|
1255
1391
|
);
|
|
1256
1392
|
}
|
|
1257
1393
|
|
|
@@ -1286,7 +1422,7 @@ namespace DxMessaging.Core
|
|
|
1286
1422
|
messageHandler,
|
|
1287
1423
|
messageBusDeregistration,
|
|
1288
1424
|
priority,
|
|
1289
|
-
messageBus
|
|
1425
|
+
messageBus
|
|
1290
1426
|
);
|
|
1291
1427
|
}
|
|
1292
1428
|
|
|
@@ -1318,7 +1454,7 @@ namespace DxMessaging.Core
|
|
|
1318
1454
|
messageHandler,
|
|
1319
1455
|
messageBusDeregistration,
|
|
1320
1456
|
priority,
|
|
1321
|
-
messageBus
|
|
1457
|
+
messageBus
|
|
1322
1458
|
);
|
|
1323
1459
|
}
|
|
1324
1460
|
|
|
@@ -1350,7 +1486,7 @@ namespace DxMessaging.Core
|
|
|
1350
1486
|
messageHandler,
|
|
1351
1487
|
messageBusDeregistration,
|
|
1352
1488
|
priority,
|
|
1353
|
-
messageBus
|
|
1489
|
+
messageBus
|
|
1354
1490
|
);
|
|
1355
1491
|
}
|
|
1356
1492
|
|
|
@@ -1381,7 +1517,7 @@ namespace DxMessaging.Core
|
|
|
1381
1517
|
messageHandler,
|
|
1382
1518
|
messageBusDeregistration,
|
|
1383
1519
|
priority,
|
|
1384
|
-
messageBus
|
|
1520
|
+
messageBus
|
|
1385
1521
|
);
|
|
1386
1522
|
}
|
|
1387
1523
|
|
|
@@ -1412,7 +1548,7 @@ namespace DxMessaging.Core
|
|
|
1412
1548
|
messageHandler,
|
|
1413
1549
|
messageBusDeregistration,
|
|
1414
1550
|
priority,
|
|
1415
|
-
messageBus
|
|
1551
|
+
messageBus
|
|
1416
1552
|
);
|
|
1417
1553
|
}
|
|
1418
1554
|
|
|
@@ -1443,7 +1579,7 @@ namespace DxMessaging.Core
|
|
|
1443
1579
|
messageHandler,
|
|
1444
1580
|
messageBusDeregistration,
|
|
1445
1581
|
priority,
|
|
1446
|
-
messageBus
|
|
1582
|
+
messageBus
|
|
1447
1583
|
);
|
|
1448
1584
|
}
|
|
1449
1585
|
|
|
@@ -1474,7 +1610,7 @@ namespace DxMessaging.Core
|
|
|
1474
1610
|
messageHandler,
|
|
1475
1611
|
messageBusDeregistration,
|
|
1476
1612
|
priority,
|
|
1477
|
-
messageBus
|
|
1613
|
+
messageBus
|
|
1478
1614
|
);
|
|
1479
1615
|
}
|
|
1480
1616
|
|
|
@@ -1505,7 +1641,7 @@ namespace DxMessaging.Core
|
|
|
1505
1641
|
messageHandler,
|
|
1506
1642
|
messageBusDeregistration,
|
|
1507
1643
|
priority,
|
|
1508
|
-
messageBus
|
|
1644
|
+
messageBus
|
|
1509
1645
|
);
|
|
1510
1646
|
}
|
|
1511
1647
|
|
|
@@ -1536,7 +1672,7 @@ namespace DxMessaging.Core
|
|
|
1536
1672
|
messageHandler,
|
|
1537
1673
|
messageBusDeregistration,
|
|
1538
1674
|
priority,
|
|
1539
|
-
messageBus
|
|
1675
|
+
messageBus
|
|
1540
1676
|
);
|
|
1541
1677
|
}
|
|
1542
1678
|
|
|
@@ -1572,7 +1708,7 @@ namespace DxMessaging.Core
|
|
|
1572
1708
|
messageHandler,
|
|
1573
1709
|
messageBusDeregistration,
|
|
1574
1710
|
priority,
|
|
1575
|
-
messageBus
|
|
1711
|
+
messageBus
|
|
1576
1712
|
);
|
|
1577
1713
|
}
|
|
1578
1714
|
|
|
@@ -1607,7 +1743,7 @@ namespace DxMessaging.Core
|
|
|
1607
1743
|
messageHandler,
|
|
1608
1744
|
messageBusDeregistration,
|
|
1609
1745
|
priority,
|
|
1610
|
-
messageBus
|
|
1746
|
+
messageBus
|
|
1611
1747
|
);
|
|
1612
1748
|
}
|
|
1613
1749
|
|
|
@@ -1638,7 +1774,7 @@ namespace DxMessaging.Core
|
|
|
1638
1774
|
messageHandler,
|
|
1639
1775
|
messageBusDeregistration,
|
|
1640
1776
|
priority,
|
|
1641
|
-
messageBus
|
|
1777
|
+
messageBus
|
|
1642
1778
|
);
|
|
1643
1779
|
}
|
|
1644
1780
|
|
|
@@ -1669,7 +1805,7 @@ namespace DxMessaging.Core
|
|
|
1669
1805
|
messageHandler,
|
|
1670
1806
|
messageBusDeregistration,
|
|
1671
1807
|
priority,
|
|
1672
|
-
messageBus
|
|
1808
|
+
messageBus
|
|
1673
1809
|
);
|
|
1674
1810
|
}
|
|
1675
1811
|
|
|
@@ -1704,7 +1840,7 @@ namespace DxMessaging.Core
|
|
|
1704
1840
|
messageHandler,
|
|
1705
1841
|
messageBusDeregistration,
|
|
1706
1842
|
priority,
|
|
1707
|
-
messageBus
|
|
1843
|
+
messageBus
|
|
1708
1844
|
);
|
|
1709
1845
|
}
|
|
1710
1846
|
|
|
@@ -1739,7 +1875,7 @@ namespace DxMessaging.Core
|
|
|
1739
1875
|
messageHandler,
|
|
1740
1876
|
messageBusDeregistration,
|
|
1741
1877
|
priority,
|
|
1742
|
-
messageBus
|
|
1878
|
+
messageBus
|
|
1743
1879
|
);
|
|
1744
1880
|
}
|
|
1745
1881
|
|
|
@@ -1771,7 +1907,7 @@ namespace DxMessaging.Core
|
|
|
1771
1907
|
messageHandler,
|
|
1772
1908
|
messageBusDeregistration,
|
|
1773
1909
|
priority,
|
|
1774
|
-
messageBus
|
|
1910
|
+
messageBus
|
|
1775
1911
|
);
|
|
1776
1912
|
}
|
|
1777
1913
|
|
|
@@ -1803,7 +1939,7 @@ namespace DxMessaging.Core
|
|
|
1803
1939
|
messageHandler,
|
|
1804
1940
|
messageBusDeregistration,
|
|
1805
1941
|
priority,
|
|
1806
|
-
messageBus
|
|
1942
|
+
messageBus
|
|
1807
1943
|
);
|
|
1808
1944
|
}
|
|
1809
1945
|
|
|
@@ -1996,31 +2132,120 @@ namespace DxMessaging.Core
|
|
|
1996
2132
|
return false;
|
|
1997
2133
|
}
|
|
1998
2134
|
|
|
2135
|
+
/// <summary>
|
|
2136
|
+
/// Resets empty typed-handler slots associated with
|
|
2137
|
+
/// <paramref name="messageBus"/>. The eviction layer calls through
|
|
2138
|
+
/// this erased surface after bus-side slots prove idle and empty.
|
|
2139
|
+
/// </summary>
|
|
2140
|
+
/// <param name="messageBus">
|
|
2141
|
+
/// Bus whose typed-handler cache should be swept. Null resolves to
|
|
2142
|
+
/// this handler's default bus.
|
|
2143
|
+
/// </param>
|
|
2144
|
+
/// <returns>Number of typed or typed-global slots reset.</returns>
|
|
2145
|
+
internal int ResetEmptyTypedSlotsForSweep(IMessageBus messageBus = null)
|
|
2146
|
+
{
|
|
2147
|
+
messageBus = ResolveMessageBus(messageBus);
|
|
2148
|
+
int messageBusIndex = messageBus.RegisteredGlobalSequentialIndex;
|
|
2149
|
+
if (messageBusIndex < 0 || _handlersByTypeByMessageBus.Count <= messageBusIndex)
|
|
2150
|
+
{
|
|
2151
|
+
return 0;
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
int resetCount = 0;
|
|
2155
|
+
MessageCache<object> handlersByType = _handlersByTypeByMessageBus[messageBusIndex];
|
|
2156
|
+
foreach (object untypedHandler in _handlersByTypeByMessageBus[messageBusIndex])
|
|
2157
|
+
{
|
|
2158
|
+
if (untypedHandler is ITypedHandlerSlotSweeper sweeper)
|
|
2159
|
+
{
|
|
2160
|
+
resetCount += sweeper.ResetEmptySlotsForSweep();
|
|
2161
|
+
if (sweeper.MarkedForOuterRemoval)
|
|
2162
|
+
{
|
|
2163
|
+
handlersByType.RemoveAtIndex(sweeper.MessageTypeIndex);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
return resetCount;
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
internal int ResetAllTypedSlotsForBusReset(IMessageBus messageBus = null)
|
|
2172
|
+
{
|
|
2173
|
+
messageBus = ResolveMessageBus(messageBus);
|
|
2174
|
+
int messageBusIndex = messageBus.RegisteredGlobalSequentialIndex;
|
|
2175
|
+
if (messageBusIndex < 0 || _handlersByTypeByMessageBus.Count <= messageBusIndex)
|
|
2176
|
+
{
|
|
2177
|
+
return 0;
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
int resetCount = 0;
|
|
2181
|
+
foreach (object untypedHandler in _handlersByTypeByMessageBus[messageBusIndex])
|
|
2182
|
+
{
|
|
2183
|
+
if (untypedHandler is ITypedHandlerSlotSweeper sweeper)
|
|
2184
|
+
{
|
|
2185
|
+
resetCount += sweeper.ResetAllSlotsForBusReset();
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
return resetCount;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
internal int CountEmptyTypedSlotsForSweep(IMessageBus messageBus = null)
|
|
2193
|
+
{
|
|
2194
|
+
messageBus = ResolveMessageBus(messageBus);
|
|
2195
|
+
int messageBusIndex = messageBus.RegisteredGlobalSequentialIndex;
|
|
2196
|
+
if (messageBusIndex < 0 || _handlersByTypeByMessageBus.Count <= messageBusIndex)
|
|
2197
|
+
{
|
|
2198
|
+
return 0;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
int count = 0;
|
|
2202
|
+
foreach (object untypedHandler in _handlersByTypeByMessageBus[messageBusIndex])
|
|
2203
|
+
{
|
|
2204
|
+
if (untypedHandler is ITypedHandlerSlotSweeper sweeper)
|
|
2205
|
+
{
|
|
2206
|
+
count += sweeper.CountEmptySlotsForSweep();
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
return count;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
internal bool HasTypedHandlersForBus(IMessageBus messageBus = null)
|
|
2214
|
+
{
|
|
2215
|
+
messageBus = ResolveMessageBus(messageBus);
|
|
2216
|
+
int messageBusIndex = messageBus.RegisteredGlobalSequentialIndex;
|
|
2217
|
+
if (messageBusIndex < 0 || _handlersByTypeByMessageBus.Count <= messageBusIndex)
|
|
2218
|
+
{
|
|
2219
|
+
return false;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
foreach (object untypedHandler in _handlersByTypeByMessageBus[messageBusIndex])
|
|
2223
|
+
{
|
|
2224
|
+
if (untypedHandler != null)
|
|
2225
|
+
{
|
|
2226
|
+
return true;
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
return false;
|
|
2231
|
+
}
|
|
2232
|
+
|
|
1999
2233
|
internal int GetUntargetedPostProcessingPrefreezeCount<T>(
|
|
2000
2234
|
IMessageBus messageBus,
|
|
2001
2235
|
int priority
|
|
2002
2236
|
)
|
|
2003
2237
|
where T : IMessage
|
|
2004
2238
|
{
|
|
2005
|
-
if (
|
|
2006
|
-
!GetHandlerForType(messageBus, out TypedHandler<T> handler)
|
|
2007
|
-
|| handler._untargetedPostProcessingFastHandlers == null
|
|
2008
|
-
)
|
|
2239
|
+
if (!GetHandlerForType(messageBus, out TypedHandler<T> handler))
|
|
2009
2240
|
{
|
|
2010
2241
|
return 0;
|
|
2011
2242
|
}
|
|
2012
2243
|
|
|
2013
|
-
|
|
2014
|
-
handler
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
)
|
|
2019
|
-
{
|
|
2020
|
-
return cache.prefreezeInvocationCount;
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
return 0;
|
|
2244
|
+
return GetPriorityPrefreezeInvocationCount<T, FastHandler<T>>(
|
|
2245
|
+
handler,
|
|
2246
|
+
TypedSlotIndex.UntargetedPostProcessFast,
|
|
2247
|
+
priority
|
|
2248
|
+
);
|
|
2024
2249
|
}
|
|
2025
2250
|
|
|
2026
2251
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2121,8 +2346,12 @@ namespace DxMessaging.Core
|
|
|
2121
2346
|
return typedHandler.GetOrCreateBroadcastWithoutSourcePostLink();
|
|
2122
2347
|
}
|
|
2123
2348
|
|
|
2124
|
-
internal sealed class HandlerActionCache<T>
|
|
2349
|
+
internal sealed class HandlerActionCache<T> : DxMessaging.Core.Internal.IHandlerActionCache
|
|
2125
2350
|
{
|
|
2351
|
+
// Uses outer T as a field type -- reflection callers must close
|
|
2352
|
+
// via MakeGenericType(outer.GetGenericArguments()) before passing
|
|
2353
|
+
// this type to Activator.CreateInstance. See
|
|
2354
|
+
// Tests/Editor/Contract/ReflectionHelpers.cs::CloseNestedGeneric.
|
|
2126
2355
|
internal readonly struct Entry
|
|
2127
2356
|
{
|
|
2128
2357
|
/// <summary>
|
|
@@ -2144,18 +2373,76 @@ namespace DxMessaging.Core
|
|
|
2144
2373
|
public readonly List<T> cache = new();
|
|
2145
2374
|
public long version;
|
|
2146
2375
|
public long lastSeenVersion = -1;
|
|
2147
|
-
public long lastSeenEmissionId;
|
|
2376
|
+
public long lastSeenEmissionId = -1;
|
|
2148
2377
|
internal int prefreezeInvocationCount;
|
|
2378
|
+
|
|
2379
|
+
/// <summary>Monotonic version field, read-only on the interface surface.</summary>
|
|
2380
|
+
long DxMessaging.Core.Internal.IHandlerActionCache.Version
|
|
2381
|
+
{
|
|
2382
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2383
|
+
get => version;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
/// <summary>Most recent dispatcher-observed version; mutable through the staged dispatch path.</summary>
|
|
2387
|
+
long DxMessaging.Core.Internal.IHandlerActionCache.LastSeenVersion
|
|
2388
|
+
{
|
|
2389
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2390
|
+
get => lastSeenVersion;
|
|
2391
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2392
|
+
set => lastSeenVersion = value;
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
/// <summary>Most recent dispatcher-observed bus emission id.</summary>
|
|
2396
|
+
long DxMessaging.Core.Internal.IHandlerActionCache.LastSeenEmissionId
|
|
2397
|
+
{
|
|
2398
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2399
|
+
get => lastSeenEmissionId;
|
|
2400
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2401
|
+
set => lastSeenEmissionId = value;
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
/// <summary>Prefreeze invocation counter mirror; maintained by the dispatchers.</summary>
|
|
2405
|
+
int DxMessaging.Core.Internal.IHandlerActionCache.PrefreezeInvocationCount
|
|
2406
|
+
{
|
|
2407
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2408
|
+
get => prefreezeInvocationCount;
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
/// <summary>True iff the entries dictionary holds zero handlers.</summary>
|
|
2412
|
+
bool DxMessaging.Core.Internal.IHandlerActionCache.IsEmpty
|
|
2413
|
+
{
|
|
2414
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2415
|
+
get => entries.Count == 0;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
/// <summary>
|
|
2419
|
+
/// Eviction-driven full clear; bumps <see cref="version"/> as the LAST step
|
|
2420
|
+
/// so captured dispatch closures observe invalidation.
|
|
2421
|
+
/// </summary>
|
|
2422
|
+
void DxMessaging.Core.Internal.IHandlerActionCache.Reset()
|
|
2423
|
+
{
|
|
2424
|
+
entries.Clear();
|
|
2425
|
+
cache.Clear();
|
|
2426
|
+
lastSeenVersion = -1;
|
|
2427
|
+
lastSeenEmissionId = -1;
|
|
2428
|
+
prefreezeInvocationCount = 0;
|
|
2429
|
+
unchecked
|
|
2430
|
+
{
|
|
2431
|
+
++version;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2149
2434
|
}
|
|
2150
2435
|
|
|
2151
2436
|
internal sealed class UntargetedDispatchLink<T>
|
|
2152
2437
|
where T : IMessage
|
|
2153
2438
|
{
|
|
2154
2439
|
private readonly TypedHandler<T> typedHandler;
|
|
2440
|
+
internal readonly long capturedGeneration;
|
|
2155
2441
|
|
|
2156
|
-
internal UntargetedDispatchLink(TypedHandler<T> typedHandler)
|
|
2442
|
+
internal UntargetedDispatchLink(TypedHandler<T> typedHandler, long capturedGeneration)
|
|
2157
2443
|
{
|
|
2158
2444
|
this.typedHandler = typedHandler;
|
|
2445
|
+
this.capturedGeneration = capturedGeneration;
|
|
2159
2446
|
}
|
|
2160
2447
|
|
|
2161
2448
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2166,6 +2453,14 @@ namespace DxMessaging.Core
|
|
|
2166
2453
|
long emissionId
|
|
2167
2454
|
)
|
|
2168
2455
|
{
|
|
2456
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2457
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2458
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2459
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2460
|
+
{
|
|
2461
|
+
return;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2169
2464
|
if (!messageHandler.active)
|
|
2170
2465
|
{
|
|
2171
2466
|
return;
|
|
@@ -2179,10 +2474,15 @@ namespace DxMessaging.Core
|
|
|
2179
2474
|
where TMessage : IMessage
|
|
2180
2475
|
{
|
|
2181
2476
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2477
|
+
internal readonly long capturedGeneration;
|
|
2182
2478
|
|
|
2183
|
-
internal UntargetedPostDispatchLink(
|
|
2479
|
+
internal UntargetedPostDispatchLink(
|
|
2480
|
+
TypedHandler<TMessage> typedHandler,
|
|
2481
|
+
long capturedGeneration
|
|
2482
|
+
)
|
|
2184
2483
|
{
|
|
2185
2484
|
this.typedHandler = typedHandler;
|
|
2485
|
+
this.capturedGeneration = capturedGeneration;
|
|
2186
2486
|
}
|
|
2187
2487
|
|
|
2188
2488
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2193,6 +2493,14 @@ namespace DxMessaging.Core
|
|
|
2193
2493
|
long emissionId
|
|
2194
2494
|
)
|
|
2195
2495
|
{
|
|
2496
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2497
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2498
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2499
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2500
|
+
{
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2196
2504
|
if (!messageHandler.active)
|
|
2197
2505
|
{
|
|
2198
2506
|
return;
|
|
@@ -2206,10 +2514,15 @@ namespace DxMessaging.Core
|
|
|
2206
2514
|
where TMessage : IMessage
|
|
2207
2515
|
{
|
|
2208
2516
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2517
|
+
internal readonly long capturedGeneration;
|
|
2209
2518
|
|
|
2210
|
-
internal TargetedDispatchLink(
|
|
2519
|
+
internal TargetedDispatchLink(
|
|
2520
|
+
TypedHandler<TMessage> typedHandler,
|
|
2521
|
+
long capturedGeneration
|
|
2522
|
+
)
|
|
2211
2523
|
{
|
|
2212
2524
|
this.typedHandler = typedHandler;
|
|
2525
|
+
this.capturedGeneration = capturedGeneration;
|
|
2213
2526
|
}
|
|
2214
2527
|
|
|
2215
2528
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2221,6 +2534,14 @@ namespace DxMessaging.Core
|
|
|
2221
2534
|
long emissionId
|
|
2222
2535
|
)
|
|
2223
2536
|
{
|
|
2537
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2538
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2539
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2540
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2541
|
+
{
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2224
2545
|
typedHandler.HandleTargeted(ref target, ref message, priority, emissionId);
|
|
2225
2546
|
}
|
|
2226
2547
|
}
|
|
@@ -2229,10 +2550,15 @@ namespace DxMessaging.Core
|
|
|
2229
2550
|
where TMessage : IMessage
|
|
2230
2551
|
{
|
|
2231
2552
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2553
|
+
internal readonly long capturedGeneration;
|
|
2232
2554
|
|
|
2233
|
-
internal TargetedPostDispatchLink(
|
|
2555
|
+
internal TargetedPostDispatchLink(
|
|
2556
|
+
TypedHandler<TMessage> typedHandler,
|
|
2557
|
+
long capturedGeneration
|
|
2558
|
+
)
|
|
2234
2559
|
{
|
|
2235
2560
|
this.typedHandler = typedHandler;
|
|
2561
|
+
this.capturedGeneration = capturedGeneration;
|
|
2236
2562
|
}
|
|
2237
2563
|
|
|
2238
2564
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2244,6 +2570,14 @@ namespace DxMessaging.Core
|
|
|
2244
2570
|
long emissionId
|
|
2245
2571
|
)
|
|
2246
2572
|
{
|
|
2573
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2574
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2575
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2576
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2577
|
+
{
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2247
2581
|
typedHandler.HandleTargetedPostProcessing(
|
|
2248
2582
|
ref target,
|
|
2249
2583
|
ref message,
|
|
@@ -2257,10 +2591,15 @@ namespace DxMessaging.Core
|
|
|
2257
2591
|
where TMessage : IMessage
|
|
2258
2592
|
{
|
|
2259
2593
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2594
|
+
internal readonly long capturedGeneration;
|
|
2260
2595
|
|
|
2261
|
-
internal TargetedWithoutTargetingDispatchLink(
|
|
2596
|
+
internal TargetedWithoutTargetingDispatchLink(
|
|
2597
|
+
TypedHandler<TMessage> typedHandler,
|
|
2598
|
+
long capturedGeneration
|
|
2599
|
+
)
|
|
2262
2600
|
{
|
|
2263
2601
|
this.typedHandler = typedHandler;
|
|
2602
|
+
this.capturedGeneration = capturedGeneration;
|
|
2264
2603
|
}
|
|
2265
2604
|
|
|
2266
2605
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2272,6 +2611,14 @@ namespace DxMessaging.Core
|
|
|
2272
2611
|
long emissionId
|
|
2273
2612
|
)
|
|
2274
2613
|
{
|
|
2614
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2615
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2616
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2617
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2618
|
+
{
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2275
2622
|
typedHandler.HandleTargetedWithoutTargeting(
|
|
2276
2623
|
ref target,
|
|
2277
2624
|
ref message,
|
|
@@ -2285,10 +2632,15 @@ namespace DxMessaging.Core
|
|
|
2285
2632
|
where TMessage : IMessage
|
|
2286
2633
|
{
|
|
2287
2634
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2635
|
+
internal readonly long capturedGeneration;
|
|
2288
2636
|
|
|
2289
|
-
internal TargetedWithoutTargetingPostDispatchLink(
|
|
2637
|
+
internal TargetedWithoutTargetingPostDispatchLink(
|
|
2638
|
+
TypedHandler<TMessage> typedHandler,
|
|
2639
|
+
long capturedGeneration
|
|
2640
|
+
)
|
|
2290
2641
|
{
|
|
2291
2642
|
this.typedHandler = typedHandler;
|
|
2643
|
+
this.capturedGeneration = capturedGeneration;
|
|
2292
2644
|
}
|
|
2293
2645
|
|
|
2294
2646
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2300,6 +2652,14 @@ namespace DxMessaging.Core
|
|
|
2300
2652
|
long emissionId
|
|
2301
2653
|
)
|
|
2302
2654
|
{
|
|
2655
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2656
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2657
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2658
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2659
|
+
{
|
|
2660
|
+
return;
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2303
2663
|
typedHandler.HandleTargetedWithoutTargetingPostProcessing(
|
|
2304
2664
|
ref target,
|
|
2305
2665
|
ref message,
|
|
@@ -2313,10 +2673,15 @@ namespace DxMessaging.Core
|
|
|
2313
2673
|
where TMessage : IMessage
|
|
2314
2674
|
{
|
|
2315
2675
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2676
|
+
internal readonly long capturedGeneration;
|
|
2316
2677
|
|
|
2317
|
-
internal BroadcastDispatchLink(
|
|
2678
|
+
internal BroadcastDispatchLink(
|
|
2679
|
+
TypedHandler<TMessage> typedHandler,
|
|
2680
|
+
long capturedGeneration
|
|
2681
|
+
)
|
|
2318
2682
|
{
|
|
2319
2683
|
this.typedHandler = typedHandler;
|
|
2684
|
+
this.capturedGeneration = capturedGeneration;
|
|
2320
2685
|
}
|
|
2321
2686
|
|
|
2322
2687
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2328,6 +2693,14 @@ namespace DxMessaging.Core
|
|
|
2328
2693
|
long emissionId
|
|
2329
2694
|
)
|
|
2330
2695
|
{
|
|
2696
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2697
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2698
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2699
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2700
|
+
{
|
|
2701
|
+
return;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2331
2704
|
typedHandler.HandleSourcedBroadcast(ref source, ref message, priority, emissionId);
|
|
2332
2705
|
}
|
|
2333
2706
|
}
|
|
@@ -2336,10 +2709,15 @@ namespace DxMessaging.Core
|
|
|
2336
2709
|
where TMessage : IMessage
|
|
2337
2710
|
{
|
|
2338
2711
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2712
|
+
internal readonly long capturedGeneration;
|
|
2339
2713
|
|
|
2340
|
-
internal BroadcastPostDispatchLink(
|
|
2714
|
+
internal BroadcastPostDispatchLink(
|
|
2715
|
+
TypedHandler<TMessage> typedHandler,
|
|
2716
|
+
long capturedGeneration
|
|
2717
|
+
)
|
|
2341
2718
|
{
|
|
2342
2719
|
this.typedHandler = typedHandler;
|
|
2720
|
+
this.capturedGeneration = capturedGeneration;
|
|
2343
2721
|
}
|
|
2344
2722
|
|
|
2345
2723
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2351,6 +2729,14 @@ namespace DxMessaging.Core
|
|
|
2351
2729
|
long emissionId
|
|
2352
2730
|
)
|
|
2353
2731
|
{
|
|
2732
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2733
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2734
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2735
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2736
|
+
{
|
|
2737
|
+
return;
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2354
2740
|
typedHandler.HandleSourcedBroadcastPostProcessing(
|
|
2355
2741
|
ref source,
|
|
2356
2742
|
ref message,
|
|
@@ -2364,10 +2750,15 @@ namespace DxMessaging.Core
|
|
|
2364
2750
|
where TMessage : IMessage
|
|
2365
2751
|
{
|
|
2366
2752
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2753
|
+
internal readonly long capturedGeneration;
|
|
2367
2754
|
|
|
2368
|
-
internal BroadcastWithoutSourceDispatchLink(
|
|
2755
|
+
internal BroadcastWithoutSourceDispatchLink(
|
|
2756
|
+
TypedHandler<TMessage> typedHandler,
|
|
2757
|
+
long capturedGeneration
|
|
2758
|
+
)
|
|
2369
2759
|
{
|
|
2370
2760
|
this.typedHandler = typedHandler;
|
|
2761
|
+
this.capturedGeneration = capturedGeneration;
|
|
2371
2762
|
}
|
|
2372
2763
|
|
|
2373
2764
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2379,6 +2770,14 @@ namespace DxMessaging.Core
|
|
|
2379
2770
|
long emissionId
|
|
2380
2771
|
)
|
|
2381
2772
|
{
|
|
2773
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2774
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2775
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2776
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2777
|
+
{
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2382
2781
|
typedHandler.HandleSourcedBroadcastWithoutSource(
|
|
2383
2782
|
ref source,
|
|
2384
2783
|
ref message,
|
|
@@ -2392,10 +2791,15 @@ namespace DxMessaging.Core
|
|
|
2392
2791
|
where TMessage : IMessage
|
|
2393
2792
|
{
|
|
2394
2793
|
private readonly TypedHandler<TMessage> typedHandler;
|
|
2794
|
+
internal readonly long capturedGeneration;
|
|
2395
2795
|
|
|
2396
|
-
internal BroadcastWithoutSourcePostDispatchLink(
|
|
2796
|
+
internal BroadcastWithoutSourcePostDispatchLink(
|
|
2797
|
+
TypedHandler<TMessage> typedHandler,
|
|
2798
|
+
long capturedGeneration
|
|
2799
|
+
)
|
|
2397
2800
|
{
|
|
2398
2801
|
this.typedHandler = typedHandler;
|
|
2802
|
+
this.capturedGeneration = capturedGeneration;
|
|
2399
2803
|
}
|
|
2400
2804
|
|
|
2401
2805
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -2407,6 +2811,14 @@ namespace DxMessaging.Core
|
|
|
2407
2811
|
long emissionId
|
|
2408
2812
|
)
|
|
2409
2813
|
{
|
|
2814
|
+
// Generation guard: 1 field read + 1 compare per dispatch on the hot path.
|
|
2815
|
+
// Sits at the top of Invoke so reclaimed wrappers return before handler-slot
|
|
2816
|
+
// walks when the outer wrapper has been reclaimed.
|
|
2817
|
+
if (typedHandler._outerGeneration != capturedGeneration)
|
|
2818
|
+
{
|
|
2819
|
+
return;
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2410
2822
|
typedHandler.HandleBroadcastWithoutSourcePostProcessing(
|
|
2411
2823
|
ref source,
|
|
2412
2824
|
ref message,
|
|
@@ -2420,220 +2832,447 @@ namespace DxMessaging.Core
|
|
|
2420
2832
|
/// One-size-fits-all wrapper around all possible Messaging sinks for a particular MessageHandler & MessageType.
|
|
2421
2833
|
/// </summary>
|
|
2422
2834
|
/// <typeparam name="T">Message type that this Handler exists to serve.</typeparam>
|
|
2423
|
-
internal sealed class TypedHandler<T>
|
|
2835
|
+
internal sealed class TypedHandler<T> : ITypedHandlerSlotSweeper
|
|
2424
2836
|
where T : IMessage
|
|
2425
2837
|
{
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
>
|
|
2430
|
-
internal
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
> _broadcastHandlers;
|
|
2435
|
-
internal Dictionary<
|
|
2436
|
-
InstanceId,
|
|
2437
|
-
Dictionary<int, HandlerActionCache<Action<T>>>
|
|
2438
|
-
> _targetedPostProcessingHandlers;
|
|
2439
|
-
internal Dictionary<
|
|
2440
|
-
int,
|
|
2441
|
-
HandlerActionCache<Action<T>>
|
|
2442
|
-
> _untargetedPostProcessingHandlers;
|
|
2443
|
-
internal Dictionary<
|
|
2444
|
-
InstanceId,
|
|
2445
|
-
Dictionary<int, HandlerActionCache<Action<T>>>
|
|
2446
|
-
> _broadcastPostProcessingHandlers;
|
|
2447
|
-
internal Dictionary<
|
|
2448
|
-
InstanceId,
|
|
2449
|
-
Dictionary<int, HandlerActionCache<FastHandler<T>>>
|
|
2450
|
-
> _targetedFastHandlers;
|
|
2451
|
-
internal Dictionary<int, HandlerActionCache<FastHandler<T>>> _untargetedFastHandlers;
|
|
2452
|
-
internal Dictionary<
|
|
2453
|
-
InstanceId,
|
|
2454
|
-
Dictionary<int, HandlerActionCache<FastHandler<T>>>
|
|
2455
|
-
> _broadcastFastHandlers;
|
|
2456
|
-
internal Dictionary<
|
|
2457
|
-
InstanceId,
|
|
2458
|
-
Dictionary<int, HandlerActionCache<FastHandler<T>>>
|
|
2459
|
-
> _targetedPostProcessingFastHandlers;
|
|
2460
|
-
internal Dictionary<
|
|
2461
|
-
int,
|
|
2462
|
-
HandlerActionCache<FastHandler<T>>
|
|
2463
|
-
> _untargetedPostProcessingFastHandlers;
|
|
2464
|
-
internal Dictionary<
|
|
2465
|
-
InstanceId,
|
|
2466
|
-
Dictionary<int, HandlerActionCache<FastHandler<T>>>
|
|
2467
|
-
> _broadcastPostProcessingFastHandlers;
|
|
2468
|
-
|
|
2469
|
-
internal HandlerActionCache<Action<IUntargetedMessage>> _globalUntargetedHandlers;
|
|
2470
|
-
|
|
2471
|
-
internal HandlerActionCache<
|
|
2472
|
-
Action<InstanceId, ITargetedMessage>
|
|
2473
|
-
> _globalTargetedHandlers;
|
|
2838
|
+
// Typed storage: 20 typed slots + 6 global slots + 10 dispatch
|
|
2839
|
+
// links. The legacy named fields were deleted so new handler
|
|
2840
|
+
// variants must pick an explicit axis-indexed slot.
|
|
2841
|
+
internal readonly TypedSlot<T>[] _slots = new TypedSlot<T>[TypedSlotIndex.Length];
|
|
2842
|
+
internal readonly TypedGlobalSlot[] _globalSlots = new TypedGlobalSlot[
|
|
2843
|
+
TypedGlobalSlotIndex.Length
|
|
2844
|
+
];
|
|
2845
|
+
internal readonly object[] _dispatchLinks = new object[TypedDispatchLinkIndex.Length];
|
|
2474
2846
|
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2847
|
+
// Constructor exists solely so the [Conditional("DEBUG")]
|
|
2848
|
+
// validator below runs at construction time. In Release builds
|
|
2849
|
+
// the Conditional attribute strips the call site, leaving an
|
|
2850
|
+
// empty constructor body that the JIT collapses to the
|
|
2851
|
+
// equivalent of the implicit default. Mirrors the
|
|
2852
|
+
// MessageBus.ValidateSinkArrays() pattern.
|
|
2853
|
+
internal TypedHandler()
|
|
2854
|
+
{
|
|
2855
|
+
ValidateSlotArrays();
|
|
2856
|
+
}
|
|
2478
2857
|
|
|
2479
|
-
internal
|
|
2480
|
-
|
|
2481
|
-
> _globalUntargetedFastHandlers;
|
|
2858
|
+
internal long _outerGeneration;
|
|
2859
|
+
internal bool _markedForOuterRemoval;
|
|
2482
2860
|
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2861
|
+
int ITypedHandlerSlotSweeper.MessageTypeIndex
|
|
2862
|
+
{
|
|
2863
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2864
|
+
get => MessageHelperIndexer<T>.SequentialId;
|
|
2865
|
+
}
|
|
2486
2866
|
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
HandlerActionCache<Action<InstanceId, T>>
|
|
2493
|
-
> _targetedWithoutTargetingHandlers;
|
|
2494
|
-
internal Dictionary<
|
|
2495
|
-
int,
|
|
2496
|
-
HandlerActionCache<FastHandlerWithContext<T>>
|
|
2497
|
-
> _fastTargetedWithoutTargetingHandlers;
|
|
2498
|
-
internal Dictionary<
|
|
2499
|
-
int,
|
|
2500
|
-
HandlerActionCache<Action<InstanceId, T>>
|
|
2501
|
-
> _broadcastWithoutSourceHandlers;
|
|
2502
|
-
internal Dictionary<
|
|
2503
|
-
int,
|
|
2504
|
-
HandlerActionCache<FastHandlerWithContext<T>>
|
|
2505
|
-
> _fastBroadcastWithoutSourceHandlers;
|
|
2506
|
-
internal Dictionary<
|
|
2507
|
-
int,
|
|
2508
|
-
HandlerActionCache<Action<InstanceId, T>>
|
|
2509
|
-
> _targetedWithoutTargetingPostProcessingHandlers;
|
|
2510
|
-
internal Dictionary<
|
|
2511
|
-
int,
|
|
2512
|
-
HandlerActionCache<FastHandlerWithContext<T>>
|
|
2513
|
-
> _fastTargetedWithoutTargetingPostProcessingHandlers;
|
|
2514
|
-
internal Dictionary<
|
|
2515
|
-
int,
|
|
2516
|
-
HandlerActionCache<Action<InstanceId, T>>
|
|
2517
|
-
> _broadcastWithoutSourcePostProcessingHandlers;
|
|
2518
|
-
internal Dictionary<
|
|
2519
|
-
int,
|
|
2520
|
-
HandlerActionCache<FastHandlerWithContext<T>>
|
|
2521
|
-
> _fastBroadcastWithoutSourcePostProcessingHandlers;
|
|
2522
|
-
private UntargetedDispatchLink<T> _untargetedLink;
|
|
2523
|
-
private object _untargetedPostLink;
|
|
2524
|
-
private object _targetedLink;
|
|
2525
|
-
private object _targetedPostLink;
|
|
2526
|
-
private object _targetedWithoutTargetingLink;
|
|
2527
|
-
private object _targetedWithoutTargetingPostLink;
|
|
2528
|
-
private object _broadcastLink;
|
|
2529
|
-
private object _broadcastPostLink;
|
|
2530
|
-
private object _broadcastWithoutSourceLink;
|
|
2531
|
-
private object _broadcastWithoutSourcePostLink;
|
|
2867
|
+
bool ITypedHandlerSlotSweeper.MarkedForOuterRemoval
|
|
2868
|
+
{
|
|
2869
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2870
|
+
get => _markedForOuterRemoval;
|
|
2871
|
+
}
|
|
2532
2872
|
|
|
2533
|
-
[
|
|
2534
|
-
|
|
2873
|
+
[Conditional("DEBUG")]
|
|
2874
|
+
private void ValidateSlotArrays()
|
|
2535
2875
|
{
|
|
2536
|
-
|
|
2537
|
-
if (link == null)
|
|
2876
|
+
if (_slots.Length != TypedSlotIndex.Length)
|
|
2538
2877
|
{
|
|
2539
|
-
|
|
2540
|
-
|
|
2878
|
+
throw new InvalidOperationException(
|
|
2879
|
+
$"_slots length is {_slots.Length} but TypedSlotIndex.Length is {TypedSlotIndex.Length}."
|
|
2880
|
+
);
|
|
2881
|
+
}
|
|
2882
|
+
if (_globalSlots.Length != TypedGlobalSlotIndex.Length)
|
|
2883
|
+
{
|
|
2884
|
+
throw new InvalidOperationException(
|
|
2885
|
+
$"_globalSlots length is {_globalSlots.Length} but TypedGlobalSlotIndex.Length is {TypedGlobalSlotIndex.Length}."
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
if (_dispatchLinks.Length != TypedDispatchLinkIndex.Length)
|
|
2889
|
+
{
|
|
2890
|
+
throw new InvalidOperationException(
|
|
2891
|
+
$"_dispatchLinks length is {_dispatchLinks.Length} but TypedDispatchLinkIndex.Length is {TypedDispatchLinkIndex.Length}."
|
|
2892
|
+
);
|
|
2893
|
+
}
|
|
2894
|
+
// Lazy registration writers update the slot arrays; this assertion still
|
|
2895
|
+
// holds at construction (slots populate on first register,
|
|
2896
|
+
// not on construction). The invariant flips meaning -- not
|
|
2897
|
+
// the message -- when writers land.
|
|
2898
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
2899
|
+
{
|
|
2900
|
+
if (_slots[i] != null)
|
|
2901
|
+
{
|
|
2902
|
+
throw new InvalidOperationException(
|
|
2903
|
+
$"_slots[{i}] is non-null at construction; expected null per TypedSlotIndex because slots populate lazily on first registration."
|
|
2904
|
+
);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
for (int i = 0; i < _globalSlots.Length; ++i)
|
|
2908
|
+
{
|
|
2909
|
+
if (_globalSlots[i] != null)
|
|
2910
|
+
{
|
|
2911
|
+
throw new InvalidOperationException(
|
|
2912
|
+
$"_globalSlots[{i}] is non-null at construction; expected null per TypedGlobalSlotIndex because slots populate lazily on first registration."
|
|
2913
|
+
);
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
for (int i = 0; i < _dispatchLinks.Length; ++i)
|
|
2917
|
+
{
|
|
2918
|
+
if (_dispatchLinks[i] != null)
|
|
2919
|
+
{
|
|
2920
|
+
throw new InvalidOperationException(
|
|
2921
|
+
$"_dispatchLinks[{i}] is non-null at construction; expected null per TypedDispatchLinkIndex because links populate lazily on first dispatch-link request."
|
|
2922
|
+
);
|
|
2923
|
+
}
|
|
2541
2924
|
}
|
|
2542
|
-
|
|
2543
|
-
return link;
|
|
2544
2925
|
}
|
|
2545
2926
|
|
|
2546
2927
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2547
|
-
|
|
2928
|
+
private TypedSlot<T> GetOrCreateSlot(int index, bool requiresContext)
|
|
2548
2929
|
{
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
if (link == null)
|
|
2930
|
+
TypedSlot<T> slot = _slots[index];
|
|
2931
|
+
if (slot == null)
|
|
2552
2932
|
{
|
|
2553
|
-
|
|
2554
|
-
|
|
2933
|
+
slot = new TypedSlot<T>(requiresContext);
|
|
2934
|
+
_slots[index] = slot;
|
|
2555
2935
|
}
|
|
2556
2936
|
|
|
2557
|
-
return
|
|
2937
|
+
return slot;
|
|
2558
2938
|
}
|
|
2559
2939
|
|
|
2560
2940
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2561
|
-
internal
|
|
2941
|
+
internal Dictionary<int, IHandlerActionCache> GetOrCreatePriorityHandlers(
|
|
2942
|
+
int index,
|
|
2943
|
+
bool requiresContext
|
|
2944
|
+
)
|
|
2562
2945
|
{
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
{
|
|
2566
|
-
link = new TargetedDispatchLink<T>(this);
|
|
2567
|
-
_targetedLink = link;
|
|
2568
|
-
}
|
|
2946
|
+
return GetOrCreateSlot(index, requiresContext).byPriority;
|
|
2947
|
+
}
|
|
2569
2948
|
|
|
2570
|
-
|
|
2949
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2950
|
+
internal Dictionary<int, IHandlerActionCache> GetPriorityHandlers(int index)
|
|
2951
|
+
{
|
|
2952
|
+
return _slots[index]?.byPriority;
|
|
2571
2953
|
}
|
|
2572
2954
|
|
|
2573
2955
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2574
|
-
internal
|
|
2956
|
+
internal Dictionary<
|
|
2957
|
+
InstanceId,
|
|
2958
|
+
Dictionary<int, IHandlerActionCache>
|
|
2959
|
+
> GetOrCreateContextHandlers(int index)
|
|
2575
2960
|
{
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
_targetedPostLink = link;
|
|
2581
|
-
}
|
|
2961
|
+
TypedSlot<T> slot = GetOrCreateSlot(index, requiresContext: true);
|
|
2962
|
+
slot.byContext ??= DxPools.TypedHandlerContextDicts.Rent();
|
|
2963
|
+
return slot.byContext;
|
|
2964
|
+
}
|
|
2582
2965
|
|
|
2583
|
-
|
|
2966
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2967
|
+
internal Dictionary<
|
|
2968
|
+
InstanceId,
|
|
2969
|
+
Dictionary<int, IHandlerActionCache>
|
|
2970
|
+
> GetContextHandlers(int index)
|
|
2971
|
+
{
|
|
2972
|
+
return _slots[index]?.byContext;
|
|
2584
2973
|
}
|
|
2585
2974
|
|
|
2586
2975
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2587
|
-
internal
|
|
2976
|
+
internal TypedGlobalSlot GetOrCreateGlobalSlot(int index)
|
|
2588
2977
|
{
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
if (link == null)
|
|
2978
|
+
TypedGlobalSlot slot = _globalSlots[index];
|
|
2979
|
+
if (slot == null)
|
|
2592
2980
|
{
|
|
2593
|
-
|
|
2594
|
-
|
|
2981
|
+
slot = new TypedGlobalSlot();
|
|
2982
|
+
_globalSlots[index] = slot;
|
|
2595
2983
|
}
|
|
2596
2984
|
|
|
2597
|
-
return
|
|
2985
|
+
return slot;
|
|
2598
2986
|
}
|
|
2599
2987
|
|
|
2600
2988
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2601
|
-
internal
|
|
2989
|
+
internal HandlerActionCache<TU> GetGlobalCache<TU>(int index)
|
|
2602
2990
|
{
|
|
2603
|
-
|
|
2604
|
-
_targetedWithoutTargetingPostLink
|
|
2605
|
-
as TargetedWithoutTargetingPostDispatchLink<T>;
|
|
2606
|
-
if (link == null)
|
|
2607
|
-
{
|
|
2608
|
-
link = new TargetedWithoutTargetingPostDispatchLink<T>(this);
|
|
2609
|
-
_targetedWithoutTargetingPostLink = link;
|
|
2610
|
-
}
|
|
2611
|
-
|
|
2612
|
-
return link;
|
|
2991
|
+
return _globalSlots[index]?.cache as HandlerActionCache<TU>;
|
|
2613
2992
|
}
|
|
2614
2993
|
|
|
2615
2994
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2616
|
-
|
|
2995
|
+
private TypedSlot<T> FindPrioritySlot(Dictionary<int, IHandlerActionCache> handlers)
|
|
2617
2996
|
{
|
|
2618
|
-
|
|
2619
|
-
if (link == null)
|
|
2997
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
2620
2998
|
{
|
|
2621
|
-
|
|
2622
|
-
|
|
2999
|
+
TypedSlot<T> slot = _slots[i];
|
|
3000
|
+
if (slot != null && ReferenceEquals(slot.byPriority, handlers))
|
|
3001
|
+
{
|
|
3002
|
+
return slot;
|
|
3003
|
+
}
|
|
2623
3004
|
}
|
|
2624
3005
|
|
|
2625
|
-
return
|
|
3006
|
+
return null;
|
|
2626
3007
|
}
|
|
2627
3008
|
|
|
2628
3009
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
2629
|
-
|
|
3010
|
+
private TypedSlot<T> FindContextSlot(
|
|
3011
|
+
Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> handlersByContext
|
|
3012
|
+
)
|
|
2630
3013
|
{
|
|
2631
|
-
|
|
2632
|
-
|
|
3014
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
3015
|
+
{
|
|
3016
|
+
TypedSlot<T> slot = _slots[i];
|
|
3017
|
+
if (slot != null && ReferenceEquals(slot.byContext, handlersByContext))
|
|
3018
|
+
{
|
|
3019
|
+
return slot;
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
return null;
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
int ITypedHandlerSlotSweeper.ResetEmptySlotsForSweep()
|
|
3027
|
+
{
|
|
3028
|
+
_markedForOuterRemoval = false;
|
|
3029
|
+
int resetCount = 0;
|
|
3030
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
3031
|
+
{
|
|
3032
|
+
TypedSlot<T> slot = _slots[i];
|
|
3033
|
+
if (slot != null && slot.IsEmpty)
|
|
3034
|
+
{
|
|
3035
|
+
slot.Reset();
|
|
3036
|
+
_slots[i] = null;
|
|
3037
|
+
resetCount++;
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
for (int i = 0; i < _globalSlots.Length; ++i)
|
|
3042
|
+
{
|
|
3043
|
+
TypedGlobalSlot slot = _globalSlots[i];
|
|
3044
|
+
if (slot != null && slot.IsEmpty)
|
|
3045
|
+
{
|
|
3046
|
+
slot.Reset();
|
|
3047
|
+
_globalSlots[i] = null;
|
|
3048
|
+
resetCount++;
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
MarkForOuterRemovalIfEmpty();
|
|
3053
|
+
return resetCount;
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
int ITypedHandlerSlotSweeper.ResetAllSlotsForBusReset()
|
|
3057
|
+
{
|
|
3058
|
+
_markedForOuterRemoval = false;
|
|
3059
|
+
int resetCount = 0;
|
|
3060
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
3061
|
+
{
|
|
3062
|
+
TypedSlot<T> slot = _slots[i];
|
|
3063
|
+
if (slot != null)
|
|
3064
|
+
{
|
|
3065
|
+
slot.Reset();
|
|
3066
|
+
_slots[i] = null;
|
|
3067
|
+
resetCount++;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
for (int i = 0; i < _globalSlots.Length; ++i)
|
|
3072
|
+
{
|
|
3073
|
+
TypedGlobalSlot slot = _globalSlots[i];
|
|
3074
|
+
if (slot != null)
|
|
3075
|
+
{
|
|
3076
|
+
slot.Reset();
|
|
3077
|
+
_globalSlots[i] = null;
|
|
3078
|
+
resetCount++;
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
ClearDispatchLinks();
|
|
3083
|
+
unchecked
|
|
3084
|
+
{
|
|
3085
|
+
++_outerGeneration;
|
|
3086
|
+
}
|
|
3087
|
+
return resetCount;
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3090
|
+
int ITypedHandlerSlotSweeper.CountEmptySlotsForSweep()
|
|
3091
|
+
{
|
|
3092
|
+
int count = 0;
|
|
3093
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
3094
|
+
{
|
|
3095
|
+
TypedSlot<T> slot = _slots[i];
|
|
3096
|
+
if (slot != null && slot.IsEmpty)
|
|
3097
|
+
{
|
|
3098
|
+
count++;
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
for (int i = 0; i < _globalSlots.Length; ++i)
|
|
3103
|
+
{
|
|
3104
|
+
TypedGlobalSlot slot = _globalSlots[i];
|
|
3105
|
+
if (slot != null && slot.IsEmpty)
|
|
3106
|
+
{
|
|
3107
|
+
count++;
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
return count;
|
|
3112
|
+
}
|
|
3113
|
+
|
|
3114
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3115
|
+
private void MarkForOuterRemovalIfEmpty()
|
|
3116
|
+
{
|
|
3117
|
+
if (HasLiveSlots())
|
|
3118
|
+
{
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
|
|
3122
|
+
ClearDispatchLinks();
|
|
3123
|
+
_markedForOuterRemoval = true;
|
|
3124
|
+
unchecked
|
|
3125
|
+
{
|
|
3126
|
+
++_outerGeneration;
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3131
|
+
private bool HasLiveSlots()
|
|
3132
|
+
{
|
|
3133
|
+
for (int i = 0; i < _slots.Length; ++i)
|
|
3134
|
+
{
|
|
3135
|
+
if (_slots[i] != null)
|
|
3136
|
+
{
|
|
3137
|
+
return true;
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
for (int i = 0; i < _globalSlots.Length; ++i)
|
|
3142
|
+
{
|
|
3143
|
+
if (_globalSlots[i] != null)
|
|
3144
|
+
{
|
|
3145
|
+
return true;
|
|
3146
|
+
}
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
return false;
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3153
|
+
private void ClearDispatchLinks()
|
|
3154
|
+
{
|
|
3155
|
+
for (int i = 0; i < _dispatchLinks.Length; ++i)
|
|
3156
|
+
{
|
|
3157
|
+
_dispatchLinks[i] = null;
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3162
|
+
internal UntargetedDispatchLink<T> GetOrCreateUntargetedLink()
|
|
3163
|
+
{
|
|
3164
|
+
UntargetedDispatchLink<T> link =
|
|
3165
|
+
_dispatchLinks[TypedDispatchLinkIndex.UntargetedHandle]
|
|
3166
|
+
as UntargetedDispatchLink<T>;
|
|
3167
|
+
if (link == null)
|
|
3168
|
+
{
|
|
3169
|
+
link = new UntargetedDispatchLink<T>(this, _outerGeneration);
|
|
3170
|
+
_dispatchLinks[TypedDispatchLinkIndex.UntargetedHandle] = link;
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
return link;
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3177
|
+
internal UntargetedPostDispatchLink<T> GetOrCreateUntargetedPostLink()
|
|
3178
|
+
{
|
|
3179
|
+
UntargetedPostDispatchLink<T> link =
|
|
3180
|
+
_dispatchLinks[TypedDispatchLinkIndex.UntargetedPostProcess]
|
|
3181
|
+
as UntargetedPostDispatchLink<T>;
|
|
3182
|
+
if (link == null)
|
|
3183
|
+
{
|
|
3184
|
+
link = new UntargetedPostDispatchLink<T>(this, _outerGeneration);
|
|
3185
|
+
_dispatchLinks[TypedDispatchLinkIndex.UntargetedPostProcess] = link;
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
return link;
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3192
|
+
internal TargetedDispatchLink<T> GetOrCreateTargetedLink()
|
|
3193
|
+
{
|
|
3194
|
+
TargetedDispatchLink<T> link =
|
|
3195
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedHandle]
|
|
3196
|
+
as TargetedDispatchLink<T>;
|
|
3197
|
+
if (link == null)
|
|
3198
|
+
{
|
|
3199
|
+
link = new TargetedDispatchLink<T>(this, _outerGeneration);
|
|
3200
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedHandle] = link;
|
|
3201
|
+
}
|
|
3202
|
+
|
|
3203
|
+
return link;
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3206
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3207
|
+
internal TargetedPostDispatchLink<T> GetOrCreateTargetedPostLink()
|
|
3208
|
+
{
|
|
3209
|
+
TargetedPostDispatchLink<T> link =
|
|
3210
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedPostProcess]
|
|
3211
|
+
as TargetedPostDispatchLink<T>;
|
|
3212
|
+
if (link == null)
|
|
3213
|
+
{
|
|
3214
|
+
link = new TargetedPostDispatchLink<T>(this, _outerGeneration);
|
|
3215
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedPostProcess] = link;
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
return link;
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3222
|
+
internal TargetedWithoutTargetingDispatchLink<T> GetOrCreateTargetedWithoutTargetingLink()
|
|
3223
|
+
{
|
|
3224
|
+
TargetedWithoutTargetingDispatchLink<T> link =
|
|
3225
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedHandleWithoutContext]
|
|
3226
|
+
as TargetedWithoutTargetingDispatchLink<T>;
|
|
3227
|
+
if (link == null)
|
|
3228
|
+
{
|
|
3229
|
+
link = new TargetedWithoutTargetingDispatchLink<T>(this, _outerGeneration);
|
|
3230
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedHandleWithoutContext] = link;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
return link;
|
|
3234
|
+
}
|
|
3235
|
+
|
|
3236
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3237
|
+
internal TargetedWithoutTargetingPostDispatchLink<T> GetOrCreateTargetedWithoutTargetingPostLink()
|
|
3238
|
+
{
|
|
3239
|
+
TargetedWithoutTargetingPostDispatchLink<T> link =
|
|
3240
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedPostProcessWithoutContext]
|
|
3241
|
+
as TargetedWithoutTargetingPostDispatchLink<T>;
|
|
3242
|
+
if (link == null)
|
|
3243
|
+
{
|
|
3244
|
+
link = new TargetedWithoutTargetingPostDispatchLink<T>(this, _outerGeneration);
|
|
3245
|
+
_dispatchLinks[TypedDispatchLinkIndex.TargetedPostProcessWithoutContext] = link;
|
|
3246
|
+
}
|
|
3247
|
+
|
|
3248
|
+
return link;
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3252
|
+
internal BroadcastDispatchLink<T> GetOrCreateBroadcastLink()
|
|
3253
|
+
{
|
|
3254
|
+
BroadcastDispatchLink<T> link =
|
|
3255
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastHandle]
|
|
3256
|
+
as BroadcastDispatchLink<T>;
|
|
3257
|
+
if (link == null)
|
|
3258
|
+
{
|
|
3259
|
+
link = new BroadcastDispatchLink<T>(this, _outerGeneration);
|
|
3260
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastHandle] = link;
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
return link;
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
3267
|
+
internal BroadcastPostDispatchLink<T> GetOrCreateBroadcastPostLink()
|
|
3268
|
+
{
|
|
3269
|
+
BroadcastPostDispatchLink<T> link =
|
|
3270
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastPostProcess]
|
|
3271
|
+
as BroadcastPostDispatchLink<T>;
|
|
2633
3272
|
if (link == null)
|
|
2634
3273
|
{
|
|
2635
|
-
link = new BroadcastPostDispatchLink<T>(this);
|
|
2636
|
-
|
|
3274
|
+
link = new BroadcastPostDispatchLink<T>(this, _outerGeneration);
|
|
3275
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastPostProcess] = link;
|
|
2637
3276
|
}
|
|
2638
3277
|
|
|
2639
3278
|
return link;
|
|
@@ -2643,11 +3282,12 @@ namespace DxMessaging.Core
|
|
|
2643
3282
|
internal BroadcastWithoutSourceDispatchLink<T> GetOrCreateBroadcastWithoutSourceLink()
|
|
2644
3283
|
{
|
|
2645
3284
|
BroadcastWithoutSourceDispatchLink<T> link =
|
|
2646
|
-
|
|
3285
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastHandleWithoutContext]
|
|
3286
|
+
as BroadcastWithoutSourceDispatchLink<T>;
|
|
2647
3287
|
if (link == null)
|
|
2648
3288
|
{
|
|
2649
|
-
link = new BroadcastWithoutSourceDispatchLink<T>(this);
|
|
2650
|
-
|
|
3289
|
+
link = new BroadcastWithoutSourceDispatchLink<T>(this, _outerGeneration);
|
|
3290
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastHandleWithoutContext] = link;
|
|
2651
3291
|
}
|
|
2652
3292
|
|
|
2653
3293
|
return link;
|
|
@@ -2657,11 +3297,13 @@ namespace DxMessaging.Core
|
|
|
2657
3297
|
internal BroadcastWithoutSourcePostDispatchLink<T> GetOrCreateBroadcastWithoutSourcePostLink()
|
|
2658
3298
|
{
|
|
2659
3299
|
BroadcastWithoutSourcePostDispatchLink<T> link =
|
|
2660
|
-
|
|
3300
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastPostProcessWithoutContext]
|
|
3301
|
+
as BroadcastWithoutSourcePostDispatchLink<T>;
|
|
2661
3302
|
if (link == null)
|
|
2662
3303
|
{
|
|
2663
|
-
link = new BroadcastWithoutSourcePostDispatchLink<T>(this);
|
|
2664
|
-
|
|
3304
|
+
link = new BroadcastWithoutSourcePostDispatchLink<T>(this, _outerGeneration);
|
|
3305
|
+
_dispatchLinks[TypedDispatchLinkIndex.BroadcastPostProcessWithoutContext] =
|
|
3306
|
+
link;
|
|
2665
3307
|
}
|
|
2666
3308
|
|
|
2667
3309
|
return link;
|
|
@@ -2674,19 +3316,18 @@ namespace DxMessaging.Core
|
|
|
2674
3316
|
/// <param name="priority">Priority at which to run the handlers.</param>
|
|
2675
3317
|
public void HandleUntargeted(ref T message, int priority, long emissionId)
|
|
2676
3318
|
{
|
|
2677
|
-
|
|
2678
|
-
|
|
3319
|
+
RunFastHandlers(
|
|
3320
|
+
GetPriorityHandlers(TypedSlotIndex.UntargetedHandleFast),
|
|
3321
|
+
ref message,
|
|
2679
3322
|
priority,
|
|
2680
3323
|
emissionId
|
|
2681
3324
|
);
|
|
2682
|
-
|
|
2683
|
-
|
|
3325
|
+
RunHandlers(
|
|
3326
|
+
GetPriorityHandlers(TypedSlotIndex.UntargetedHandleDefault),
|
|
3327
|
+
ref message,
|
|
2684
3328
|
priority,
|
|
2685
3329
|
emissionId
|
|
2686
3330
|
);
|
|
2687
|
-
|
|
2688
|
-
RunFastHandlers(_untargetedFastHandlers, ref message, priority, emissionId);
|
|
2689
|
-
RunHandlers(_untargetedHandlers, ref message, priority, emissionId);
|
|
2690
3331
|
}
|
|
2691
3332
|
|
|
2692
3333
|
/// <summary>
|
|
@@ -2704,14 +3345,14 @@ namespace DxMessaging.Core
|
|
|
2704
3345
|
{
|
|
2705
3346
|
RunFastHandlersWithContext(
|
|
2706
3347
|
ref target,
|
|
2707
|
-
|
|
3348
|
+
GetContextHandlers(TypedSlotIndex.TargetedHandleFast),
|
|
2708
3349
|
ref message,
|
|
2709
3350
|
priority,
|
|
2710
3351
|
emissionId
|
|
2711
3352
|
);
|
|
2712
3353
|
RunHandlersWithContext(
|
|
2713
3354
|
ref target,
|
|
2714
|
-
|
|
3355
|
+
GetContextHandlers(TypedSlotIndex.TargetedHandleDefault),
|
|
2715
3356
|
ref message,
|
|
2716
3357
|
priority,
|
|
2717
3358
|
emissionId
|
|
@@ -2733,14 +3374,14 @@ namespace DxMessaging.Core
|
|
|
2733
3374
|
{
|
|
2734
3375
|
RunFastHandlers(
|
|
2735
3376
|
ref target,
|
|
2736
|
-
|
|
3377
|
+
GetPriorityHandlers(TypedSlotIndex.TargetedHandleWithoutContextFast),
|
|
2737
3378
|
ref message,
|
|
2738
3379
|
priority,
|
|
2739
3380
|
emissionId
|
|
2740
3381
|
);
|
|
2741
3382
|
RunHandlers(
|
|
2742
3383
|
ref target,
|
|
2743
|
-
|
|
3384
|
+
GetPriorityHandlers(TypedSlotIndex.TargetedHandleWithoutContext),
|
|
2744
3385
|
ref message,
|
|
2745
3386
|
priority,
|
|
2746
3387
|
emissionId
|
|
@@ -2762,14 +3403,14 @@ namespace DxMessaging.Core
|
|
|
2762
3403
|
{
|
|
2763
3404
|
RunFastHandlersWithContext(
|
|
2764
3405
|
ref source,
|
|
2765
|
-
|
|
3406
|
+
GetContextHandlers(TypedSlotIndex.BroadcastHandleFast),
|
|
2766
3407
|
ref message,
|
|
2767
3408
|
priority,
|
|
2768
3409
|
emissionId
|
|
2769
3410
|
);
|
|
2770
3411
|
RunHandlersWithContext(
|
|
2771
3412
|
ref source,
|
|
2772
|
-
|
|
3413
|
+
GetContextHandlers(TypedSlotIndex.BroadcastHandleDefault),
|
|
2773
3414
|
ref message,
|
|
2774
3415
|
priority,
|
|
2775
3416
|
emissionId
|
|
@@ -2791,14 +3432,14 @@ namespace DxMessaging.Core
|
|
|
2791
3432
|
{
|
|
2792
3433
|
RunFastHandlers(
|
|
2793
3434
|
ref source,
|
|
2794
|
-
|
|
3435
|
+
GetPriorityHandlers(TypedSlotIndex.BroadcastHandleWithoutContextFast),
|
|
2795
3436
|
ref message,
|
|
2796
3437
|
priority,
|
|
2797
3438
|
emissionId
|
|
2798
3439
|
);
|
|
2799
3440
|
RunHandlers(
|
|
2800
3441
|
ref source,
|
|
2801
|
-
|
|
3442
|
+
GetPriorityHandlers(TypedSlotIndex.BroadcastHandleWithoutContext),
|
|
2802
3443
|
ref message,
|
|
2803
3444
|
priority,
|
|
2804
3445
|
emissionId
|
|
@@ -2811,14 +3452,32 @@ namespace DxMessaging.Core
|
|
|
2811
3452
|
/// <param name="message">Message to emit.</param>
|
|
2812
3453
|
public void HandleGlobalUntargeted(ref IUntargetedMessage message, long emissionId)
|
|
2813
3454
|
{
|
|
2814
|
-
|
|
2815
|
-
|
|
3455
|
+
HandlerActionCache<FastHandler<IUntargetedMessage>> fastCache = GetGlobalCache<
|
|
3456
|
+
FastHandler<IUntargetedMessage>
|
|
3457
|
+
>(TypedGlobalSlotIndex.UntargetedFast);
|
|
3458
|
+
RunFastHandlers(fastCache, ref message, emissionId);
|
|
3459
|
+
HandlerActionCache<Action<IUntargetedMessage>> cache = GetGlobalCache<
|
|
3460
|
+
Action<IUntargetedMessage>
|
|
3461
|
+
>(TypedGlobalSlotIndex.UntargetedDefault);
|
|
3462
|
+
// Live-count fast path. Cross-handler in-flight snapshot
|
|
3463
|
+
// semantics do not apply to the global accept-all path: the
|
|
3464
|
+
// bus dispatch loop calls PrefreezeGlobalUntargetedForEmission
|
|
3465
|
+
// lazily per-entry inside InvokeGlobalUntargetedEntry, after
|
|
3466
|
+
// earlier-priority handlers have already run. A sibling
|
|
3467
|
+
// MessageHandler that removes this handler's entry mid-emit
|
|
3468
|
+
// drains cache.entries before the lazy prefreeze can capture
|
|
3469
|
+
// a snapshot, so cache.cache rebuilds from the now-empty
|
|
3470
|
+
// entries. Bailing on cache.entries.Count == 0 is therefore
|
|
3471
|
+
// equivalent to bailing after GetOrAddNewHandlerStack would
|
|
3472
|
+
// return an empty list, and is documented behavior for the
|
|
3473
|
+
// global path.
|
|
3474
|
+
if (cache?.entries is not { Count: > 0 })
|
|
2816
3475
|
{
|
|
2817
3476
|
return;
|
|
2818
3477
|
}
|
|
2819
3478
|
|
|
2820
3479
|
List<Action<IUntargetedMessage>> handlers = GetOrAddNewHandlerStack(
|
|
2821
|
-
|
|
3480
|
+
cache,
|
|
2822
3481
|
emissionId
|
|
2823
3482
|
);
|
|
2824
3483
|
int handlersCount = handlers.Count;
|
|
@@ -2839,15 +3498,25 @@ namespace DxMessaging.Core
|
|
|
2839
3498
|
long emissionId
|
|
2840
3499
|
)
|
|
2841
3500
|
{
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
3501
|
+
HandlerActionCache<FastHandlerWithContext<ITargetedMessage>> fastCache =
|
|
3502
|
+
GetGlobalCache<FastHandlerWithContext<ITargetedMessage>>(
|
|
3503
|
+
TypedGlobalSlotIndex.TargetedFast
|
|
3504
|
+
);
|
|
3505
|
+
RunFastHandlers(ref target, fastCache, ref message, emissionId);
|
|
3506
|
+
|
|
3507
|
+
HandlerActionCache<Action<InstanceId, ITargetedMessage>> cache = GetGlobalCache<
|
|
3508
|
+
Action<InstanceId, ITargetedMessage>
|
|
3509
|
+
>(TypedGlobalSlotIndex.TargetedDefault);
|
|
3510
|
+
// Live-count fast path. See comment in HandleGlobalUntargeted
|
|
3511
|
+
// for why the global accept-all path bails on
|
|
3512
|
+
// cache.entries.Count == 0 rather than reading the snapshot.
|
|
3513
|
+
if (cache?.entries is not { Count: > 0 })
|
|
2845
3514
|
{
|
|
2846
3515
|
return;
|
|
2847
3516
|
}
|
|
2848
3517
|
|
|
2849
3518
|
List<Action<InstanceId, ITargetedMessage>> handlers = GetOrAddNewHandlerStack(
|
|
2850
|
-
|
|
3519
|
+
cache,
|
|
2851
3520
|
emissionId
|
|
2852
3521
|
);
|
|
2853
3522
|
int handlersCount = handlers.Count;
|
|
@@ -2868,15 +3537,25 @@ namespace DxMessaging.Core
|
|
|
2868
3537
|
long emissionId
|
|
2869
3538
|
)
|
|
2870
3539
|
{
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
3540
|
+
HandlerActionCache<FastHandlerWithContext<IBroadcastMessage>> fastCache =
|
|
3541
|
+
GetGlobalCache<FastHandlerWithContext<IBroadcastMessage>>(
|
|
3542
|
+
TypedGlobalSlotIndex.BroadcastFast
|
|
3543
|
+
);
|
|
3544
|
+
RunFastHandlers(ref source, fastCache, ref message, emissionId);
|
|
3545
|
+
|
|
3546
|
+
HandlerActionCache<Action<InstanceId, IBroadcastMessage>> cache = GetGlobalCache<
|
|
3547
|
+
Action<InstanceId, IBroadcastMessage>
|
|
3548
|
+
>(TypedGlobalSlotIndex.BroadcastDefault);
|
|
3549
|
+
// Live-count fast path. See comment in HandleGlobalUntargeted
|
|
3550
|
+
// for why the global accept-all path bails on
|
|
3551
|
+
// cache.entries.Count == 0 rather than reading the snapshot.
|
|
3552
|
+
if (cache?.entries is not { Count: > 0 })
|
|
2874
3553
|
{
|
|
2875
3554
|
return;
|
|
2876
3555
|
}
|
|
2877
3556
|
|
|
2878
3557
|
List<Action<InstanceId, IBroadcastMessage>> handlers = GetOrAddNewHandlerStack(
|
|
2879
|
-
|
|
3558
|
+
cache,
|
|
2880
3559
|
emissionId
|
|
2881
3560
|
);
|
|
2882
3561
|
int handlersCount = handlers.Count;
|
|
@@ -2934,12 +3613,17 @@ namespace DxMessaging.Core
|
|
|
2934
3613
|
public void HandleUntargetedPostProcessing(ref T message, int priority, long emissionId)
|
|
2935
3614
|
{
|
|
2936
3615
|
RunFastHandlers(
|
|
2937
|
-
|
|
3616
|
+
GetPriorityHandlers(TypedSlotIndex.UntargetedPostProcessFast),
|
|
3617
|
+
ref message,
|
|
3618
|
+
priority,
|
|
3619
|
+
emissionId
|
|
3620
|
+
);
|
|
3621
|
+
RunHandlers(
|
|
3622
|
+
GetPriorityHandlers(TypedSlotIndex.UntargetedPostProcessDefault),
|
|
2938
3623
|
ref message,
|
|
2939
3624
|
priority,
|
|
2940
3625
|
emissionId
|
|
2941
3626
|
);
|
|
2942
|
-
RunHandlers(_untargetedPostProcessingHandlers, ref message, priority, emissionId);
|
|
2943
3627
|
}
|
|
2944
3628
|
|
|
2945
3629
|
/// <summary>
|
|
@@ -2958,14 +3642,14 @@ namespace DxMessaging.Core
|
|
|
2958
3642
|
{
|
|
2959
3643
|
RunFastHandlersWithContext(
|
|
2960
3644
|
ref target,
|
|
2961
|
-
|
|
3645
|
+
GetContextHandlers(TypedSlotIndex.TargetedPostProcessFast),
|
|
2962
3646
|
ref message,
|
|
2963
3647
|
priority,
|
|
2964
3648
|
emissionId
|
|
2965
3649
|
);
|
|
2966
3650
|
RunHandlersWithContext(
|
|
2967
3651
|
ref target,
|
|
2968
|
-
|
|
3652
|
+
GetContextHandlers(TypedSlotIndex.TargetedPostProcessDefault),
|
|
2969
3653
|
ref message,
|
|
2970
3654
|
priority,
|
|
2971
3655
|
emissionId
|
|
@@ -2988,14 +3672,14 @@ namespace DxMessaging.Core
|
|
|
2988
3672
|
{
|
|
2989
3673
|
RunFastHandlersWithContext(
|
|
2990
3674
|
ref target,
|
|
2991
|
-
|
|
3675
|
+
GetPriorityHandlers(TypedSlotIndex.TargetedPostProcessWithoutContextFast),
|
|
2992
3676
|
ref message,
|
|
2993
3677
|
priority,
|
|
2994
3678
|
emissionId
|
|
2995
3679
|
);
|
|
2996
3680
|
RunHandlers(
|
|
2997
3681
|
ref target,
|
|
2998
|
-
|
|
3682
|
+
GetPriorityHandlers(TypedSlotIndex.TargetedPostProcessWithoutContext),
|
|
2999
3683
|
ref message,
|
|
3000
3684
|
priority,
|
|
3001
3685
|
emissionId
|
|
@@ -3018,14 +3702,14 @@ namespace DxMessaging.Core
|
|
|
3018
3702
|
{
|
|
3019
3703
|
RunFastHandlersWithContext(
|
|
3020
3704
|
ref source,
|
|
3021
|
-
|
|
3705
|
+
GetContextHandlers(TypedSlotIndex.BroadcastPostProcessFast),
|
|
3022
3706
|
ref message,
|
|
3023
3707
|
priority,
|
|
3024
3708
|
emissionId
|
|
3025
3709
|
);
|
|
3026
3710
|
RunHandlersWithContext(
|
|
3027
3711
|
ref source,
|
|
3028
|
-
|
|
3712
|
+
GetContextHandlers(TypedSlotIndex.BroadcastPostProcessDefault),
|
|
3029
3713
|
ref message,
|
|
3030
3714
|
priority,
|
|
3031
3715
|
emissionId
|
|
@@ -3048,14 +3732,14 @@ namespace DxMessaging.Core
|
|
|
3048
3732
|
{
|
|
3049
3733
|
RunFastHandlersWithContext(
|
|
3050
3734
|
ref source,
|
|
3051
|
-
|
|
3735
|
+
GetPriorityHandlers(TypedSlotIndex.BroadcastPostProcessWithoutContextFast),
|
|
3052
3736
|
ref message,
|
|
3053
3737
|
priority,
|
|
3054
3738
|
emissionId
|
|
3055
3739
|
);
|
|
3056
3740
|
RunHandlers(
|
|
3057
3741
|
ref source,
|
|
3058
|
-
|
|
3742
|
+
GetPriorityHandlers(TypedSlotIndex.BroadcastPostProcessWithoutContext),
|
|
3059
3743
|
ref message,
|
|
3060
3744
|
priority,
|
|
3061
3745
|
emissionId
|
|
@@ -3076,17 +3760,17 @@ namespace DxMessaging.Core
|
|
|
3076
3760
|
Action<T> handler,
|
|
3077
3761
|
Action deregistration,
|
|
3078
3762
|
int priority,
|
|
3079
|
-
|
|
3763
|
+
IMessageBus messageBus
|
|
3080
3764
|
)
|
|
3081
3765
|
{
|
|
3082
|
-
return
|
|
3766
|
+
return AddHandlerPreservingPriorityKey(
|
|
3083
3767
|
target,
|
|
3084
|
-
|
|
3768
|
+
GetOrCreateContextHandlers(TypedSlotIndex.TargetedHandleDefault),
|
|
3085
3769
|
originalHandler,
|
|
3086
3770
|
handler,
|
|
3087
3771
|
deregistration,
|
|
3088
3772
|
priority,
|
|
3089
|
-
|
|
3773
|
+
messageBus
|
|
3090
3774
|
);
|
|
3091
3775
|
}
|
|
3092
3776
|
|
|
@@ -3104,17 +3788,17 @@ namespace DxMessaging.Core
|
|
|
3104
3788
|
FastHandler<T> handler,
|
|
3105
3789
|
Action deregistration,
|
|
3106
3790
|
int priority,
|
|
3107
|
-
|
|
3791
|
+
IMessageBus messageBus
|
|
3108
3792
|
)
|
|
3109
3793
|
{
|
|
3110
|
-
return
|
|
3794
|
+
return AddHandlerPreservingPriorityKey(
|
|
3111
3795
|
target,
|
|
3112
|
-
|
|
3796
|
+
GetOrCreateContextHandlers(TypedSlotIndex.TargetedHandleFast),
|
|
3113
3797
|
originalHandler,
|
|
3114
3798
|
handler,
|
|
3115
3799
|
deregistration,
|
|
3116
3800
|
priority,
|
|
3117
|
-
|
|
3801
|
+
messageBus
|
|
3118
3802
|
);
|
|
3119
3803
|
}
|
|
3120
3804
|
|
|
@@ -3130,16 +3814,19 @@ namespace DxMessaging.Core
|
|
|
3130
3814
|
Action<InstanceId, T> handler,
|
|
3131
3815
|
Action deregistration,
|
|
3132
3816
|
int priority,
|
|
3133
|
-
|
|
3817
|
+
IMessageBus messageBus
|
|
3134
3818
|
)
|
|
3135
3819
|
{
|
|
3136
3820
|
return AddHandlerPreservingPriorityKey(
|
|
3137
|
-
|
|
3821
|
+
GetOrCreatePriorityHandlers(
|
|
3822
|
+
TypedSlotIndex.TargetedHandleWithoutContext,
|
|
3823
|
+
requiresContext: false
|
|
3824
|
+
),
|
|
3138
3825
|
originalHandler,
|
|
3139
3826
|
handler,
|
|
3140
3827
|
deregistration,
|
|
3141
3828
|
priority,
|
|
3142
|
-
|
|
3829
|
+
messageBus
|
|
3143
3830
|
);
|
|
3144
3831
|
}
|
|
3145
3832
|
|
|
@@ -3155,16 +3842,19 @@ namespace DxMessaging.Core
|
|
|
3155
3842
|
FastHandlerWithContext<T> handler,
|
|
3156
3843
|
Action deregistration,
|
|
3157
3844
|
int priority,
|
|
3158
|
-
|
|
3845
|
+
IMessageBus messageBus
|
|
3159
3846
|
)
|
|
3160
3847
|
{
|
|
3161
3848
|
return AddHandlerPreservingPriorityKey(
|
|
3162
|
-
|
|
3849
|
+
GetOrCreatePriorityHandlers(
|
|
3850
|
+
TypedSlotIndex.TargetedHandleWithoutContextFast,
|
|
3851
|
+
requiresContext: false
|
|
3852
|
+
),
|
|
3163
3853
|
originalHandler,
|
|
3164
3854
|
handler,
|
|
3165
3855
|
deregistration,
|
|
3166
3856
|
priority,
|
|
3167
|
-
|
|
3857
|
+
messageBus
|
|
3168
3858
|
);
|
|
3169
3859
|
}
|
|
3170
3860
|
|
|
@@ -3180,16 +3870,19 @@ namespace DxMessaging.Core
|
|
|
3180
3870
|
Action<T> handler,
|
|
3181
3871
|
Action deregistration,
|
|
3182
3872
|
int priority,
|
|
3183
|
-
|
|
3873
|
+
IMessageBus messageBus
|
|
3184
3874
|
)
|
|
3185
3875
|
{
|
|
3186
|
-
return
|
|
3187
|
-
|
|
3876
|
+
return AddHandlerPreservingPriorityKey(
|
|
3877
|
+
GetOrCreatePriorityHandlers(
|
|
3878
|
+
TypedSlotIndex.UntargetedHandleDefault,
|
|
3879
|
+
requiresContext: false
|
|
3880
|
+
),
|
|
3188
3881
|
originalHandler,
|
|
3189
3882
|
handler,
|
|
3190
3883
|
deregistration,
|
|
3191
3884
|
priority,
|
|
3192
|
-
|
|
3885
|
+
messageBus
|
|
3193
3886
|
);
|
|
3194
3887
|
}
|
|
3195
3888
|
|
|
@@ -3205,16 +3898,19 @@ namespace DxMessaging.Core
|
|
|
3205
3898
|
FastHandler<T> handler,
|
|
3206
3899
|
Action deregistration,
|
|
3207
3900
|
int priority,
|
|
3208
|
-
|
|
3901
|
+
IMessageBus messageBus
|
|
3209
3902
|
)
|
|
3210
3903
|
{
|
|
3211
|
-
return
|
|
3212
|
-
|
|
3904
|
+
return AddHandlerPreservingPriorityKey(
|
|
3905
|
+
GetOrCreatePriorityHandlers(
|
|
3906
|
+
TypedSlotIndex.UntargetedHandleFast,
|
|
3907
|
+
requiresContext: false
|
|
3908
|
+
),
|
|
3213
3909
|
originalHandler,
|
|
3214
3910
|
handler,
|
|
3215
3911
|
deregistration,
|
|
3216
3912
|
priority,
|
|
3217
|
-
|
|
3913
|
+
messageBus
|
|
3218
3914
|
);
|
|
3219
3915
|
}
|
|
3220
3916
|
|
|
@@ -3232,17 +3928,17 @@ namespace DxMessaging.Core
|
|
|
3232
3928
|
Action<T> handler,
|
|
3233
3929
|
Action deregistration,
|
|
3234
3930
|
int priority,
|
|
3235
|
-
|
|
3931
|
+
IMessageBus messageBus
|
|
3236
3932
|
)
|
|
3237
3933
|
{
|
|
3238
|
-
return
|
|
3934
|
+
return AddHandlerPreservingPriorityKey(
|
|
3239
3935
|
source,
|
|
3240
|
-
|
|
3936
|
+
GetOrCreateContextHandlers(TypedSlotIndex.BroadcastHandleDefault),
|
|
3241
3937
|
originalHandler,
|
|
3242
3938
|
handler,
|
|
3243
3939
|
deregistration,
|
|
3244
3940
|
priority,
|
|
3245
|
-
|
|
3941
|
+
messageBus
|
|
3246
3942
|
);
|
|
3247
3943
|
}
|
|
3248
3944
|
|
|
@@ -3260,17 +3956,17 @@ namespace DxMessaging.Core
|
|
|
3260
3956
|
FastHandler<T> handler,
|
|
3261
3957
|
Action deregistration,
|
|
3262
3958
|
int priority,
|
|
3263
|
-
|
|
3959
|
+
IMessageBus messageBus
|
|
3264
3960
|
)
|
|
3265
3961
|
{
|
|
3266
|
-
return
|
|
3962
|
+
return AddHandlerPreservingPriorityKey(
|
|
3267
3963
|
source,
|
|
3268
|
-
|
|
3964
|
+
GetOrCreateContextHandlers(TypedSlotIndex.BroadcastHandleFast),
|
|
3269
3965
|
originalHandler,
|
|
3270
3966
|
handler,
|
|
3271
3967
|
deregistration,
|
|
3272
3968
|
priority,
|
|
3273
|
-
|
|
3969
|
+
messageBus
|
|
3274
3970
|
);
|
|
3275
3971
|
}
|
|
3276
3972
|
|
|
@@ -3286,17 +3982,20 @@ namespace DxMessaging.Core
|
|
|
3286
3982
|
Action<InstanceId, T> handler,
|
|
3287
3983
|
Action deregistration,
|
|
3288
3984
|
int priority,
|
|
3289
|
-
|
|
3985
|
+
IMessageBus messageBus
|
|
3290
3986
|
)
|
|
3291
3987
|
{
|
|
3292
3988
|
// Preserve the priority bucket during the current emission so frozen snapshots remain valid
|
|
3293
3989
|
return AddHandlerPreservingPriorityKey(
|
|
3294
|
-
|
|
3990
|
+
GetOrCreatePriorityHandlers(
|
|
3991
|
+
TypedSlotIndex.BroadcastHandleWithoutContext,
|
|
3992
|
+
requiresContext: false
|
|
3993
|
+
),
|
|
3295
3994
|
originalHandler,
|
|
3296
3995
|
handler,
|
|
3297
3996
|
deregistration,
|
|
3298
3997
|
priority,
|
|
3299
|
-
|
|
3998
|
+
messageBus
|
|
3300
3999
|
);
|
|
3301
4000
|
}
|
|
3302
4001
|
|
|
@@ -3312,17 +4011,20 @@ namespace DxMessaging.Core
|
|
|
3312
4011
|
FastHandlerWithContext<T> handler,
|
|
3313
4012
|
Action deregistration,
|
|
3314
4013
|
int priority,
|
|
3315
|
-
|
|
4014
|
+
IMessageBus messageBus
|
|
3316
4015
|
)
|
|
3317
4016
|
{
|
|
3318
4017
|
// Preserve the priority bucket during the current emission so frozen snapshots remain valid
|
|
3319
4018
|
return AddHandlerPreservingPriorityKey(
|
|
3320
|
-
|
|
4019
|
+
GetOrCreatePriorityHandlers(
|
|
4020
|
+
TypedSlotIndex.BroadcastHandleWithoutContextFast,
|
|
4021
|
+
requiresContext: false
|
|
4022
|
+
),
|
|
3321
4023
|
originalHandler,
|
|
3322
4024
|
handler,
|
|
3323
4025
|
deregistration,
|
|
3324
4026
|
priority,
|
|
3325
|
-
|
|
4027
|
+
messageBus
|
|
3326
4028
|
);
|
|
3327
4029
|
}
|
|
3328
4030
|
|
|
@@ -3335,14 +4037,16 @@ namespace DxMessaging.Core
|
|
|
3335
4037
|
public Action AddGlobalUntargetedHandler(
|
|
3336
4038
|
Action<IUntargetedMessage> originalHandler,
|
|
3337
4039
|
Action<IUntargetedMessage> handler,
|
|
3338
|
-
Action deregistration
|
|
4040
|
+
Action deregistration,
|
|
4041
|
+
IMessageBus messageBus
|
|
3339
4042
|
)
|
|
3340
4043
|
{
|
|
3341
4044
|
return AddHandler(
|
|
3342
|
-
|
|
4045
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.UntargetedDefault),
|
|
3343
4046
|
originalHandler,
|
|
3344
4047
|
handler,
|
|
3345
|
-
deregistration
|
|
4048
|
+
deregistration,
|
|
4049
|
+
messageBus
|
|
3346
4050
|
);
|
|
3347
4051
|
}
|
|
3348
4052
|
|
|
@@ -3355,14 +4059,16 @@ namespace DxMessaging.Core
|
|
|
3355
4059
|
public Action AddGlobalUntargetedHandler(
|
|
3356
4060
|
FastHandler<IUntargetedMessage> originalHandler,
|
|
3357
4061
|
FastHandler<IUntargetedMessage> handler,
|
|
3358
|
-
Action deregistration
|
|
4062
|
+
Action deregistration,
|
|
4063
|
+
IMessageBus messageBus
|
|
3359
4064
|
)
|
|
3360
4065
|
{
|
|
3361
4066
|
return AddHandler(
|
|
3362
|
-
|
|
4067
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.UntargetedFast),
|
|
3363
4068
|
originalHandler,
|
|
3364
4069
|
handler,
|
|
3365
|
-
deregistration
|
|
4070
|
+
deregistration,
|
|
4071
|
+
messageBus
|
|
3366
4072
|
);
|
|
3367
4073
|
}
|
|
3368
4074
|
|
|
@@ -3375,14 +4081,16 @@ namespace DxMessaging.Core
|
|
|
3375
4081
|
public Action AddGlobalTargetedHandler(
|
|
3376
4082
|
Action<InstanceId, ITargetedMessage> originalHandler,
|
|
3377
4083
|
Action<InstanceId, ITargetedMessage> handler,
|
|
3378
|
-
Action deregistration
|
|
4084
|
+
Action deregistration,
|
|
4085
|
+
IMessageBus messageBus
|
|
3379
4086
|
)
|
|
3380
4087
|
{
|
|
3381
4088
|
return AddHandler(
|
|
3382
|
-
|
|
4089
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.TargetedDefault),
|
|
3383
4090
|
originalHandler,
|
|
3384
4091
|
handler,
|
|
3385
|
-
deregistration
|
|
4092
|
+
deregistration,
|
|
4093
|
+
messageBus
|
|
3386
4094
|
);
|
|
3387
4095
|
}
|
|
3388
4096
|
|
|
@@ -3395,14 +4103,16 @@ namespace DxMessaging.Core
|
|
|
3395
4103
|
public Action AddGlobalTargetedHandler(
|
|
3396
4104
|
FastHandlerWithContext<ITargetedMessage> originalHandler,
|
|
3397
4105
|
FastHandlerWithContext<ITargetedMessage> handler,
|
|
3398
|
-
Action deregistration
|
|
4106
|
+
Action deregistration,
|
|
4107
|
+
IMessageBus messageBus
|
|
3399
4108
|
)
|
|
3400
4109
|
{
|
|
3401
4110
|
return AddHandler(
|
|
3402
|
-
|
|
4111
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.TargetedFast),
|
|
3403
4112
|
originalHandler,
|
|
3404
4113
|
handler,
|
|
3405
|
-
deregistration
|
|
4114
|
+
deregistration,
|
|
4115
|
+
messageBus
|
|
3406
4116
|
);
|
|
3407
4117
|
}
|
|
3408
4118
|
|
|
@@ -3415,14 +4125,16 @@ namespace DxMessaging.Core
|
|
|
3415
4125
|
public Action AddGlobalBroadcastHandler(
|
|
3416
4126
|
Action<InstanceId, IBroadcastMessage> originalHandler,
|
|
3417
4127
|
Action<InstanceId, IBroadcastMessage> handler,
|
|
3418
|
-
Action deregistration
|
|
4128
|
+
Action deregistration,
|
|
4129
|
+
IMessageBus messageBus
|
|
3419
4130
|
)
|
|
3420
4131
|
{
|
|
3421
4132
|
return AddHandler(
|
|
3422
|
-
|
|
4133
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.BroadcastDefault),
|
|
3423
4134
|
originalHandler,
|
|
3424
4135
|
handler,
|
|
3425
|
-
deregistration
|
|
4136
|
+
deregistration,
|
|
4137
|
+
messageBus
|
|
3426
4138
|
);
|
|
3427
4139
|
}
|
|
3428
4140
|
|
|
@@ -3435,14 +4147,16 @@ namespace DxMessaging.Core
|
|
|
3435
4147
|
public Action AddGlobalBroadcastHandler(
|
|
3436
4148
|
FastHandlerWithContext<IBroadcastMessage> originalHandler,
|
|
3437
4149
|
FastHandlerWithContext<IBroadcastMessage> handler,
|
|
3438
|
-
Action deregistration
|
|
4150
|
+
Action deregistration,
|
|
4151
|
+
IMessageBus messageBus
|
|
3439
4152
|
)
|
|
3440
4153
|
{
|
|
3441
4154
|
return AddHandler(
|
|
3442
|
-
|
|
4155
|
+
GetOrCreateGlobalSlot(TypedGlobalSlotIndex.BroadcastFast),
|
|
3443
4156
|
originalHandler,
|
|
3444
4157
|
handler,
|
|
3445
|
-
deregistration
|
|
4158
|
+
deregistration,
|
|
4159
|
+
messageBus
|
|
3446
4160
|
);
|
|
3447
4161
|
}
|
|
3448
4162
|
|
|
@@ -3458,16 +4172,19 @@ namespace DxMessaging.Core
|
|
|
3458
4172
|
Action<T> handler,
|
|
3459
4173
|
Action deregistration,
|
|
3460
4174
|
int priority,
|
|
3461
|
-
|
|
4175
|
+
IMessageBus messageBus
|
|
3462
4176
|
)
|
|
3463
4177
|
{
|
|
3464
4178
|
return AddHandlerPreservingPriorityKey(
|
|
3465
|
-
|
|
4179
|
+
GetOrCreatePriorityHandlers(
|
|
4180
|
+
TypedSlotIndex.UntargetedPostProcessDefault,
|
|
4181
|
+
requiresContext: false
|
|
4182
|
+
),
|
|
3466
4183
|
originalHandler,
|
|
3467
4184
|
handler,
|
|
3468
4185
|
deregistration,
|
|
3469
4186
|
priority,
|
|
3470
|
-
|
|
4187
|
+
messageBus
|
|
3471
4188
|
);
|
|
3472
4189
|
}
|
|
3473
4190
|
|
|
@@ -3483,16 +4200,19 @@ namespace DxMessaging.Core
|
|
|
3483
4200
|
FastHandler<T> handler,
|
|
3484
4201
|
Action deregistration,
|
|
3485
4202
|
int priority,
|
|
3486
|
-
|
|
4203
|
+
IMessageBus messageBus
|
|
3487
4204
|
)
|
|
3488
4205
|
{
|
|
3489
4206
|
return AddHandlerPreservingPriorityKey(
|
|
3490
|
-
|
|
4207
|
+
GetOrCreatePriorityHandlers(
|
|
4208
|
+
TypedSlotIndex.UntargetedPostProcessFast,
|
|
4209
|
+
requiresContext: false
|
|
4210
|
+
),
|
|
3491
4211
|
originalHandler,
|
|
3492
4212
|
handler,
|
|
3493
4213
|
deregistration,
|
|
3494
4214
|
priority,
|
|
3495
|
-
|
|
4215
|
+
messageBus
|
|
3496
4216
|
);
|
|
3497
4217
|
}
|
|
3498
4218
|
|
|
@@ -3510,17 +4230,17 @@ namespace DxMessaging.Core
|
|
|
3510
4230
|
Action<T> handler,
|
|
3511
4231
|
Action deregistration,
|
|
3512
4232
|
int priority,
|
|
3513
|
-
|
|
4233
|
+
IMessageBus messageBus
|
|
3514
4234
|
)
|
|
3515
4235
|
{
|
|
3516
4236
|
return AddHandlerPreservingPriorityKey(
|
|
3517
4237
|
target,
|
|
3518
|
-
|
|
4238
|
+
GetOrCreateContextHandlers(TypedSlotIndex.TargetedPostProcessDefault),
|
|
3519
4239
|
originalHandler,
|
|
3520
4240
|
handler,
|
|
3521
4241
|
deregistration,
|
|
3522
4242
|
priority,
|
|
3523
|
-
|
|
4243
|
+
messageBus
|
|
3524
4244
|
);
|
|
3525
4245
|
}
|
|
3526
4246
|
|
|
@@ -3538,17 +4258,17 @@ namespace DxMessaging.Core
|
|
|
3538
4258
|
FastHandler<T> handler,
|
|
3539
4259
|
Action deregistration,
|
|
3540
4260
|
int priority,
|
|
3541
|
-
|
|
4261
|
+
IMessageBus messageBus
|
|
3542
4262
|
)
|
|
3543
4263
|
{
|
|
3544
4264
|
return AddHandlerPreservingPriorityKey(
|
|
3545
4265
|
target,
|
|
3546
|
-
|
|
4266
|
+
GetOrCreateContextHandlers(TypedSlotIndex.TargetedPostProcessFast),
|
|
3547
4267
|
originalHandler,
|
|
3548
4268
|
handler,
|
|
3549
4269
|
deregistration,
|
|
3550
4270
|
priority,
|
|
3551
|
-
|
|
4271
|
+
messageBus
|
|
3552
4272
|
);
|
|
3553
4273
|
}
|
|
3554
4274
|
|
|
@@ -3564,16 +4284,19 @@ namespace DxMessaging.Core
|
|
|
3564
4284
|
Action<InstanceId, T> handler,
|
|
3565
4285
|
Action deregistration,
|
|
3566
4286
|
int priority,
|
|
3567
|
-
|
|
4287
|
+
IMessageBus messageBus
|
|
3568
4288
|
)
|
|
3569
4289
|
{
|
|
3570
4290
|
return AddHandlerPreservingPriorityKey(
|
|
3571
|
-
|
|
4291
|
+
GetOrCreatePriorityHandlers(
|
|
4292
|
+
TypedSlotIndex.TargetedPostProcessWithoutContext,
|
|
4293
|
+
requiresContext: false
|
|
4294
|
+
),
|
|
3572
4295
|
originalHandler,
|
|
3573
4296
|
handler,
|
|
3574
4297
|
deregistration,
|
|
3575
4298
|
priority,
|
|
3576
|
-
|
|
4299
|
+
messageBus
|
|
3577
4300
|
);
|
|
3578
4301
|
}
|
|
3579
4302
|
|
|
@@ -3589,16 +4312,19 @@ namespace DxMessaging.Core
|
|
|
3589
4312
|
FastHandlerWithContext<T> handler,
|
|
3590
4313
|
Action deregistration,
|
|
3591
4314
|
int priority,
|
|
3592
|
-
|
|
4315
|
+
IMessageBus messageBus
|
|
3593
4316
|
)
|
|
3594
4317
|
{
|
|
3595
4318
|
return AddHandlerPreservingPriorityKey(
|
|
3596
|
-
|
|
4319
|
+
GetOrCreatePriorityHandlers(
|
|
4320
|
+
TypedSlotIndex.TargetedPostProcessWithoutContextFast,
|
|
4321
|
+
requiresContext: false
|
|
4322
|
+
),
|
|
3597
4323
|
originalHandler,
|
|
3598
4324
|
handler,
|
|
3599
4325
|
deregistration,
|
|
3600
4326
|
priority,
|
|
3601
|
-
|
|
4327
|
+
messageBus
|
|
3602
4328
|
);
|
|
3603
4329
|
}
|
|
3604
4330
|
|
|
@@ -3616,17 +4342,17 @@ namespace DxMessaging.Core
|
|
|
3616
4342
|
Action<T> handler,
|
|
3617
4343
|
Action deregistration,
|
|
3618
4344
|
int priority,
|
|
3619
|
-
|
|
4345
|
+
IMessageBus messageBus
|
|
3620
4346
|
)
|
|
3621
4347
|
{
|
|
3622
4348
|
return AddHandlerPreservingPriorityKey(
|
|
3623
4349
|
source,
|
|
3624
|
-
|
|
4350
|
+
GetOrCreateContextHandlers(TypedSlotIndex.BroadcastPostProcessDefault),
|
|
3625
4351
|
originalHandler,
|
|
3626
4352
|
handler,
|
|
3627
4353
|
deregistration,
|
|
3628
4354
|
priority,
|
|
3629
|
-
|
|
4355
|
+
messageBus
|
|
3630
4356
|
);
|
|
3631
4357
|
}
|
|
3632
4358
|
|
|
@@ -3644,17 +4370,17 @@ namespace DxMessaging.Core
|
|
|
3644
4370
|
FastHandler<T> handler,
|
|
3645
4371
|
Action deregistration,
|
|
3646
4372
|
int priority,
|
|
3647
|
-
|
|
4373
|
+
IMessageBus messageBus
|
|
3648
4374
|
)
|
|
3649
4375
|
{
|
|
3650
4376
|
return AddHandlerPreservingPriorityKey(
|
|
3651
4377
|
source,
|
|
3652
|
-
|
|
4378
|
+
GetOrCreateContextHandlers(TypedSlotIndex.BroadcastPostProcessFast),
|
|
3653
4379
|
originalHandler,
|
|
3654
4380
|
handler,
|
|
3655
4381
|
deregistration,
|
|
3656
4382
|
priority,
|
|
3657
|
-
|
|
4383
|
+
messageBus
|
|
3658
4384
|
);
|
|
3659
4385
|
}
|
|
3660
4386
|
|
|
@@ -3670,16 +4396,19 @@ namespace DxMessaging.Core
|
|
|
3670
4396
|
Action<InstanceId, T> handler,
|
|
3671
4397
|
Action deregistration,
|
|
3672
4398
|
int priority,
|
|
3673
|
-
|
|
4399
|
+
IMessageBus messageBus
|
|
3674
4400
|
)
|
|
3675
4401
|
{
|
|
3676
4402
|
return AddHandlerPreservingPriorityKey(
|
|
3677
|
-
|
|
4403
|
+
GetOrCreatePriorityHandlers(
|
|
4404
|
+
TypedSlotIndex.BroadcastPostProcessWithoutContext,
|
|
4405
|
+
requiresContext: false
|
|
4406
|
+
),
|
|
3678
4407
|
originalHandler,
|
|
3679
4408
|
handler,
|
|
3680
4409
|
deregistration,
|
|
3681
4410
|
priority,
|
|
3682
|
-
|
|
4411
|
+
messageBus
|
|
3683
4412
|
);
|
|
3684
4413
|
}
|
|
3685
4414
|
|
|
@@ -3695,36 +4424,197 @@ namespace DxMessaging.Core
|
|
|
3695
4424
|
FastHandlerWithContext<T> handler,
|
|
3696
4425
|
Action deregistration,
|
|
3697
4426
|
int priority,
|
|
3698
|
-
|
|
4427
|
+
IMessageBus messageBus
|
|
3699
4428
|
)
|
|
3700
4429
|
{
|
|
3701
4430
|
return AddHandlerPreservingPriorityKey(
|
|
3702
|
-
|
|
4431
|
+
GetOrCreatePriorityHandlers(
|
|
4432
|
+
TypedSlotIndex.BroadcastPostProcessWithoutContextFast,
|
|
4433
|
+
requiresContext: false
|
|
4434
|
+
),
|
|
3703
4435
|
originalHandler,
|
|
3704
4436
|
handler,
|
|
3705
4437
|
deregistration,
|
|
3706
4438
|
priority,
|
|
3707
|
-
|
|
4439
|
+
messageBus
|
|
3708
4440
|
);
|
|
3709
4441
|
}
|
|
3710
4442
|
|
|
3711
|
-
// Context-aware variant that preserves the priority
|
|
3712
|
-
|
|
4443
|
+
// Context-aware variant that preserves the priority and context key
|
|
4444
|
+
// mappings on deregistration so frozen dispatch snapshots remain valid
|
|
4445
|
+
// for any in-flight emission. Trade-off: empty HandlerActionCache
|
|
4446
|
+
// entries (and their enclosing per-priority Dictionary) are not
|
|
4447
|
+
// reclaimed until either (a) a future registration at the same
|
|
4448
|
+
// (context, priority) pair reuses the cache, or (b) the owning
|
|
4449
|
+
// MessageHandler is destroyed. For typical Unity gameplay (a small
|
|
4450
|
+
// fixed set of priorities and a bounded set of long-lived target /
|
|
4451
|
+
// source InstanceIds) the residual footprint is on the order of
|
|
4452
|
+
// hundreds of bytes per MessageHandler. Code that interacts with
|
|
4453
|
+
// many transient InstanceIds (e.g. a global service that registers
|
|
4454
|
+
// handlers per ephemeral GameObject) should prefer recycling
|
|
4455
|
+
// MessageHandlers or routing through AddSourcedBroadcastWithoutSourceHandler /
|
|
4456
|
+
// AddTargetedWithoutTargetingHandler to avoid the per-(context,priority)
|
|
4457
|
+
// outer-dictionary growth.
|
|
4458
|
+
private Action AddHandlerPreservingPriorityKey<TU>(
|
|
3713
4459
|
InstanceId context,
|
|
3714
|
-
|
|
3715
|
-
InstanceId,
|
|
3716
|
-
Dictionary<int, HandlerActionCache<TU>>
|
|
3717
|
-
> handlersByContext,
|
|
4460
|
+
Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> handlersByContext,
|
|
3718
4461
|
TU originalHandler,
|
|
3719
4462
|
TU augmentedHandler,
|
|
3720
4463
|
Action deregistration,
|
|
3721
4464
|
int priority,
|
|
3722
|
-
|
|
4465
|
+
IMessageBus messageBus
|
|
3723
4466
|
)
|
|
3724
4467
|
{
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
4468
|
+
if (
|
|
4469
|
+
!handlersByContext.TryGetValue(
|
|
4470
|
+
context,
|
|
4471
|
+
out Dictionary<int, IHandlerActionCache> sortedHandlers
|
|
4472
|
+
)
|
|
4473
|
+
)
|
|
4474
|
+
{
|
|
4475
|
+
sortedHandlers = DxPools.TypedHandlerPriorityDicts.Rent();
|
|
4476
|
+
handlersByContext[context] = sortedHandlers;
|
|
4477
|
+
}
|
|
4478
|
+
|
|
4479
|
+
if (
|
|
4480
|
+
!sortedHandlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
4481
|
+
|| erasedCache is not HandlerActionCache<TU> cache
|
|
4482
|
+
)
|
|
4483
|
+
{
|
|
4484
|
+
cache = new HandlerActionCache<TU>();
|
|
4485
|
+
sortedHandlers[priority] = cache;
|
|
4486
|
+
}
|
|
4487
|
+
|
|
4488
|
+
if (
|
|
4489
|
+
!cache.entries.TryGetValue(
|
|
4490
|
+
originalHandler,
|
|
4491
|
+
out HandlerActionCache<TU>.Entry entry
|
|
4492
|
+
)
|
|
4493
|
+
)
|
|
4494
|
+
{
|
|
4495
|
+
entry = new HandlerActionCache<TU>.Entry(augmentedHandler, 0);
|
|
4496
|
+
}
|
|
4497
|
+
|
|
4498
|
+
bool firstRegistration = entry.count == 0;
|
|
4499
|
+
entry = firstRegistration
|
|
4500
|
+
? new HandlerActionCache<TU>.Entry(augmentedHandler, 1)
|
|
4501
|
+
: new HandlerActionCache<TU>.Entry(entry.handler, entry.count + 1);
|
|
4502
|
+
|
|
4503
|
+
cache.entries[originalHandler] = entry;
|
|
4504
|
+
cache.version++;
|
|
4505
|
+
TypedSlot<T> slot = FindContextSlot(handlersByContext);
|
|
4506
|
+
if (slot != null)
|
|
4507
|
+
{
|
|
4508
|
+
slot.lastTouchTicks =
|
|
4509
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(
|
|
4510
|
+
messageBus
|
|
4511
|
+
);
|
|
4512
|
+
}
|
|
4513
|
+
if (firstRegistration && slot != null)
|
|
4514
|
+
{
|
|
4515
|
+
slot.liveCount++;
|
|
4516
|
+
}
|
|
4517
|
+
|
|
4518
|
+
Dictionary<
|
|
4519
|
+
InstanceId,
|
|
4520
|
+
Dictionary<int, IHandlerActionCache>
|
|
4521
|
+
> localHandlersByContext = handlersByContext;
|
|
4522
|
+
TypedSlot<T> localSlot = slot;
|
|
4523
|
+
long localSlotVersion = slot?.version ?? 0;
|
|
4524
|
+
long localResetGeneration =
|
|
4525
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetResetGeneration(messageBus);
|
|
4526
|
+
|
|
4527
|
+
return () =>
|
|
4528
|
+
{
|
|
4529
|
+
if (
|
|
4530
|
+
!global::DxMessaging.Core.MessageBus.MessageBus.IsResetGenerationCurrent(
|
|
4531
|
+
messageBus,
|
|
4532
|
+
localResetGeneration
|
|
4533
|
+
)
|
|
4534
|
+
)
|
|
4535
|
+
{
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4539
|
+
if (localSlot != null && localSlot.version != localSlotVersion)
|
|
4540
|
+
{
|
|
4541
|
+
return;
|
|
4542
|
+
}
|
|
4543
|
+
|
|
4544
|
+
if (!localHandlersByContext.TryGetValue(context, out sortedHandlers))
|
|
4545
|
+
{
|
|
4546
|
+
return;
|
|
4547
|
+
}
|
|
4548
|
+
|
|
4549
|
+
if (
|
|
4550
|
+
!sortedHandlers.TryGetValue(
|
|
4551
|
+
priority,
|
|
4552
|
+
out IHandlerActionCache localErasedCache
|
|
4553
|
+
) || localErasedCache is not HandlerActionCache<TU> localCache
|
|
4554
|
+
)
|
|
4555
|
+
{
|
|
4556
|
+
return;
|
|
4557
|
+
}
|
|
4558
|
+
|
|
4559
|
+
if (
|
|
4560
|
+
!localCache.entries.TryGetValue(
|
|
4561
|
+
originalHandler,
|
|
4562
|
+
out HandlerActionCache<TU>.Entry localEntry
|
|
4563
|
+
)
|
|
4564
|
+
)
|
|
4565
|
+
{
|
|
4566
|
+
return;
|
|
4567
|
+
}
|
|
4568
|
+
|
|
4569
|
+
localCache.version++;
|
|
4570
|
+
|
|
4571
|
+
deregistration?.Invoke();
|
|
4572
|
+
if (localSlot != null)
|
|
4573
|
+
{
|
|
4574
|
+
localSlot.lastTouchTicks =
|
|
4575
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(
|
|
4576
|
+
messageBus
|
|
4577
|
+
);
|
|
4578
|
+
}
|
|
4579
|
+
|
|
4580
|
+
if (localEntry.count <= 1)
|
|
4581
|
+
{
|
|
4582
|
+
_ = localCache.entries.Remove(originalHandler);
|
|
4583
|
+
localCache.version++;
|
|
4584
|
+
if (localSlot != null)
|
|
4585
|
+
{
|
|
4586
|
+
localSlot.liveCount--;
|
|
4587
|
+
}
|
|
4588
|
+
// Deliberately keep the priority and context mappings to preserve
|
|
4589
|
+
// frozen snapshots for the current emission.
|
|
4590
|
+
return;
|
|
4591
|
+
}
|
|
4592
|
+
|
|
4593
|
+
localEntry = new HandlerActionCache<TU>.Entry(
|
|
4594
|
+
localEntry.handler,
|
|
4595
|
+
localEntry.count - 1
|
|
4596
|
+
);
|
|
4597
|
+
|
|
4598
|
+
localCache.entries[originalHandler] = localEntry;
|
|
4599
|
+
};
|
|
4600
|
+
}
|
|
4601
|
+
|
|
4602
|
+
private static Action AddHandlerPreservingPriorityKey<TU>(
|
|
4603
|
+
InstanceId context,
|
|
4604
|
+
ref Dictionary<
|
|
4605
|
+
InstanceId,
|
|
4606
|
+
Dictionary<int, HandlerActionCache<TU>>
|
|
4607
|
+
> handlersByContext,
|
|
4608
|
+
TU originalHandler,
|
|
4609
|
+
TU augmentedHandler,
|
|
4610
|
+
Action deregistration,
|
|
4611
|
+
int priority,
|
|
4612
|
+
IMessageBus messageBus
|
|
4613
|
+
)
|
|
4614
|
+
{
|
|
4615
|
+
handlersByContext ??=
|
|
4616
|
+
new Dictionary<InstanceId, Dictionary<int, HandlerActionCache<TU>>>();
|
|
4617
|
+
|
|
3728
4618
|
if (
|
|
3729
4619
|
!handlersByContext.TryGetValue(
|
|
3730
4620
|
context,
|
|
@@ -3811,6 +4701,41 @@ namespace DxMessaging.Core
|
|
|
3811
4701
|
};
|
|
3812
4702
|
}
|
|
3813
4703
|
|
|
4704
|
+
private static void RunFastHandlersWithContext<TMessage>(
|
|
4705
|
+
ref InstanceId context,
|
|
4706
|
+
Dictionary<int, IHandlerActionCache> fastHandlers,
|
|
4707
|
+
ref TMessage message,
|
|
4708
|
+
int priority,
|
|
4709
|
+
long emissionId
|
|
4710
|
+
)
|
|
4711
|
+
where TMessage : IMessage
|
|
4712
|
+
{
|
|
4713
|
+
RunFastHandlers(ref context, fastHandlers, ref message, priority, emissionId);
|
|
4714
|
+
}
|
|
4715
|
+
|
|
4716
|
+
private static void RunFastHandlersWithContext<TMessage>(
|
|
4717
|
+
ref InstanceId context,
|
|
4718
|
+
Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> fastHandlersByContext,
|
|
4719
|
+
ref TMessage message,
|
|
4720
|
+
int priority,
|
|
4721
|
+
long emissionId
|
|
4722
|
+
)
|
|
4723
|
+
where TMessage : IMessage
|
|
4724
|
+
{
|
|
4725
|
+
if (
|
|
4726
|
+
fastHandlersByContext is not { Count: > 0 }
|
|
4727
|
+
|| !fastHandlersByContext.TryGetValue(
|
|
4728
|
+
context,
|
|
4729
|
+
out Dictionary<int, IHandlerActionCache> cache
|
|
4730
|
+
)
|
|
4731
|
+
)
|
|
4732
|
+
{
|
|
4733
|
+
return;
|
|
4734
|
+
}
|
|
4735
|
+
|
|
4736
|
+
RunFastHandlers(cache, ref message, priority, emissionId);
|
|
4737
|
+
}
|
|
4738
|
+
|
|
3814
4739
|
private static void RunFastHandlersWithContext<TMessage>(
|
|
3815
4740
|
ref InstanceId context,
|
|
3816
4741
|
Dictionary<
|
|
@@ -3863,6 +4788,75 @@ namespace DxMessaging.Core
|
|
|
3863
4788
|
RunFastHandlers(cache, ref message, priority, emissionId);
|
|
3864
4789
|
}
|
|
3865
4790
|
|
|
4791
|
+
private static void RunFastHandlers<TMessage>(
|
|
4792
|
+
Dictionary<int, IHandlerActionCache> fastHandlers,
|
|
4793
|
+
ref TMessage message,
|
|
4794
|
+
int priority,
|
|
4795
|
+
long emissionId
|
|
4796
|
+
)
|
|
4797
|
+
where TMessage : IMessage
|
|
4798
|
+
{
|
|
4799
|
+
if (fastHandlers is not { Count: > 0 })
|
|
4800
|
+
{
|
|
4801
|
+
return;
|
|
4802
|
+
}
|
|
4803
|
+
|
|
4804
|
+
if (
|
|
4805
|
+
!fastHandlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
4806
|
+
|| erasedCache is not HandlerActionCache<FastHandler<T>> cache
|
|
4807
|
+
)
|
|
4808
|
+
{
|
|
4809
|
+
return;
|
|
4810
|
+
}
|
|
4811
|
+
|
|
4812
|
+
ref T typedMessage = ref Unsafe.As<TMessage, T>(ref message);
|
|
4813
|
+
List<FastHandler<T>> handlers = GetOrAddNewHandlerStack(cache, emissionId);
|
|
4814
|
+
int handlersCount = handlers.Count;
|
|
4815
|
+
switch (handlersCount)
|
|
4816
|
+
{
|
|
4817
|
+
case 1:
|
|
4818
|
+
{
|
|
4819
|
+
handlers[0](ref typedMessage);
|
|
4820
|
+
return;
|
|
4821
|
+
}
|
|
4822
|
+
case 2:
|
|
4823
|
+
{
|
|
4824
|
+
handlers[0](ref typedMessage);
|
|
4825
|
+
handlers[1](ref typedMessage);
|
|
4826
|
+
return;
|
|
4827
|
+
}
|
|
4828
|
+
case 3:
|
|
4829
|
+
{
|
|
4830
|
+
handlers[0](ref typedMessage);
|
|
4831
|
+
handlers[1](ref typedMessage);
|
|
4832
|
+
handlers[2](ref typedMessage);
|
|
4833
|
+
return;
|
|
4834
|
+
}
|
|
4835
|
+
case 4:
|
|
4836
|
+
{
|
|
4837
|
+
handlers[0](ref typedMessage);
|
|
4838
|
+
handlers[1](ref typedMessage);
|
|
4839
|
+
handlers[2](ref typedMessage);
|
|
4840
|
+
handlers[3](ref typedMessage);
|
|
4841
|
+
return;
|
|
4842
|
+
}
|
|
4843
|
+
case 5:
|
|
4844
|
+
{
|
|
4845
|
+
handlers[0](ref typedMessage);
|
|
4846
|
+
handlers[1](ref typedMessage);
|
|
4847
|
+
handlers[2](ref typedMessage);
|
|
4848
|
+
handlers[3](ref typedMessage);
|
|
4849
|
+
handlers[4](ref typedMessage);
|
|
4850
|
+
return;
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
|
|
4854
|
+
for (int i = 0; i < handlersCount; ++i)
|
|
4855
|
+
{
|
|
4856
|
+
handlers[i](ref typedMessage);
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
|
|
3866
4860
|
private static void RunFastHandlers<TMessage>(
|
|
3867
4861
|
Dictionary<int, HandlerActionCache<FastHandler<T>>> fastHandlers,
|
|
3868
4862
|
ref TMessage message,
|
|
@@ -3942,7 +4936,22 @@ namespace DxMessaging.Core
|
|
|
3942
4936
|
where TMessage : IMessage
|
|
3943
4937
|
where TU : IMessage
|
|
3944
4938
|
{
|
|
3945
|
-
|
|
4939
|
+
// Snapshot semantics: do not bail on the live entries dictionary
|
|
4940
|
+
// count. A mid-emit removal can drain entries while the pinned
|
|
4941
|
+
// emission snapshot in cache.cache still holds the handlers we
|
|
4942
|
+
// must invoke. Read the snapshot first and bail only if the
|
|
4943
|
+
// snapshot itself is empty.
|
|
4944
|
+
//
|
|
4945
|
+
// Perf note: GetOrAddNewHandlerStack is now invoked on every
|
|
4946
|
+
// call (including for empty caches that the previous fast-path
|
|
4947
|
+
// would have skipped). The cost is one dictionary
|
|
4948
|
+
// emission-id/version compare and -- only when the per-emission
|
|
4949
|
+
// snapshot has not been pinned yet -- a single pass over
|
|
4950
|
+
// cache.entries to materialise an empty list. The win is
|
|
4951
|
+
// correctness across cross-handler mid-emit removals where the
|
|
4952
|
+
// pinned snapshot in cache.cache still holds handlers the live
|
|
4953
|
+
// entries dictionary no longer reaches.
|
|
4954
|
+
if (cache == null)
|
|
3946
4955
|
{
|
|
3947
4956
|
return;
|
|
3948
4957
|
}
|
|
@@ -3950,6 +4959,10 @@ namespace DxMessaging.Core
|
|
|
3950
4959
|
ref TU typedMessage = ref Unsafe.As<TMessage, TU>(ref message);
|
|
3951
4960
|
List<FastHandler<TU>> handlers = GetOrAddNewHandlerStack(cache, emissionId);
|
|
3952
4961
|
int handlersCount = handlers.Count;
|
|
4962
|
+
if (handlersCount == 0)
|
|
4963
|
+
{
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
3953
4966
|
switch (handlersCount)
|
|
3954
4967
|
{
|
|
3955
4968
|
case 1:
|
|
@@ -4004,7 +5017,10 @@ namespace DxMessaging.Core
|
|
|
4004
5017
|
where TMessage : IMessage
|
|
4005
5018
|
where TU : IMessage
|
|
4006
5019
|
{
|
|
4007
|
-
|
|
5020
|
+
// Snapshot semantics: see comment on the FastHandler<TU> overload.
|
|
5021
|
+
// The pinned emission snapshot may still hold handlers even when
|
|
5022
|
+
// the live entries dictionary has been drained mid-emit.
|
|
5023
|
+
if (cache == null)
|
|
4008
5024
|
{
|
|
4009
5025
|
return;
|
|
4010
5026
|
}
|
|
@@ -4015,6 +5031,10 @@ namespace DxMessaging.Core
|
|
|
4015
5031
|
emissionId
|
|
4016
5032
|
);
|
|
4017
5033
|
int handlersCount = handlers.Count;
|
|
5034
|
+
if (handlersCount == 0)
|
|
5035
|
+
{
|
|
5036
|
+
return;
|
|
5037
|
+
}
|
|
4018
5038
|
switch (handlersCount)
|
|
4019
5039
|
{
|
|
4020
5040
|
case 1:
|
|
@@ -4060,6 +5080,57 @@ namespace DxMessaging.Core
|
|
|
4060
5080
|
}
|
|
4061
5081
|
}
|
|
4062
5082
|
|
|
5083
|
+
private static void RunFastHandlers<TMessage>(
|
|
5084
|
+
ref InstanceId context,
|
|
5085
|
+
Dictionary<int, IHandlerActionCache> fastHandlers,
|
|
5086
|
+
ref TMessage message,
|
|
5087
|
+
int priority,
|
|
5088
|
+
long emissionId
|
|
5089
|
+
)
|
|
5090
|
+
where TMessage : IMessage
|
|
5091
|
+
{
|
|
5092
|
+
if (fastHandlers is not { Count: > 0 })
|
|
5093
|
+
{
|
|
5094
|
+
return;
|
|
5095
|
+
}
|
|
5096
|
+
|
|
5097
|
+
if (
|
|
5098
|
+
!fastHandlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5099
|
+
|| erasedCache is not HandlerActionCache<FastHandlerWithContext<T>> cache
|
|
5100
|
+
)
|
|
5101
|
+
{
|
|
5102
|
+
return;
|
|
5103
|
+
}
|
|
5104
|
+
|
|
5105
|
+
RunFastHandlers(ref context, cache, ref message, emissionId);
|
|
5106
|
+
}
|
|
5107
|
+
|
|
5108
|
+
private static void RunFastHandlers<TMessage, TU>(
|
|
5109
|
+
ref InstanceId context,
|
|
5110
|
+
Dictionary<int, IHandlerActionCache> fastHandlers,
|
|
5111
|
+
ref TMessage message,
|
|
5112
|
+
int priority,
|
|
5113
|
+
long emissionId
|
|
5114
|
+
)
|
|
5115
|
+
where TMessage : IMessage
|
|
5116
|
+
where TU : IMessage
|
|
5117
|
+
{
|
|
5118
|
+
if (fastHandlers is not { Count: > 0 })
|
|
5119
|
+
{
|
|
5120
|
+
return;
|
|
5121
|
+
}
|
|
5122
|
+
|
|
5123
|
+
if (
|
|
5124
|
+
!fastHandlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5125
|
+
|| erasedCache is not HandlerActionCache<FastHandlerWithContext<TU>> cache
|
|
5126
|
+
)
|
|
5127
|
+
{
|
|
5128
|
+
return;
|
|
5129
|
+
}
|
|
5130
|
+
|
|
5131
|
+
RunFastHandlers(ref context, cache, ref message, emissionId);
|
|
5132
|
+
}
|
|
5133
|
+
|
|
4063
5134
|
private static void RunFastHandlers<TMessage, TU>(
|
|
4064
5135
|
ref InstanceId context,
|
|
4065
5136
|
Dictionary<int, HandlerActionCache<FastHandlerWithContext<TU>>> fastHandlers,
|
|
@@ -4136,6 +5207,29 @@ namespace DxMessaging.Core
|
|
|
4136
5207
|
}
|
|
4137
5208
|
}
|
|
4138
5209
|
|
|
5210
|
+
private static void RunHandlersWithContext<TMessage>(
|
|
5211
|
+
ref InstanceId context,
|
|
5212
|
+
Dictionary<InstanceId, Dictionary<int, IHandlerActionCache>> handlersByContext,
|
|
5213
|
+
ref TMessage message,
|
|
5214
|
+
int priority,
|
|
5215
|
+
long emissionId
|
|
5216
|
+
)
|
|
5217
|
+
where TMessage : IMessage
|
|
5218
|
+
{
|
|
5219
|
+
if (
|
|
5220
|
+
handlersByContext is not { Count: > 0 }
|
|
5221
|
+
|| !handlersByContext.TryGetValue(
|
|
5222
|
+
context,
|
|
5223
|
+
out Dictionary<int, IHandlerActionCache> cache
|
|
5224
|
+
)
|
|
5225
|
+
)
|
|
5226
|
+
{
|
|
5227
|
+
return;
|
|
5228
|
+
}
|
|
5229
|
+
|
|
5230
|
+
RunHandlers(cache, ref message, priority, emissionId);
|
|
5231
|
+
}
|
|
5232
|
+
|
|
4139
5233
|
private static void RunHandlersWithContext<TMessage>(
|
|
4140
5234
|
ref InstanceId context,
|
|
4141
5235
|
Dictionary<
|
|
@@ -4156,10 +5250,79 @@ namespace DxMessaging.Core
|
|
|
4156
5250
|
)
|
|
4157
5251
|
)
|
|
4158
5252
|
{
|
|
4159
|
-
return;
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5255
|
+
|
|
5256
|
+
RunHandlers(cache, ref message, priority, emissionId);
|
|
5257
|
+
}
|
|
5258
|
+
|
|
5259
|
+
private static void RunHandlers<TMessage>(
|
|
5260
|
+
Dictionary<int, IHandlerActionCache> sortedHandlers,
|
|
5261
|
+
ref TMessage message,
|
|
5262
|
+
int priority,
|
|
5263
|
+
long emissionId
|
|
5264
|
+
)
|
|
5265
|
+
where TMessage : IMessage
|
|
5266
|
+
{
|
|
5267
|
+
if (sortedHandlers is not { Count: > 0 })
|
|
5268
|
+
{
|
|
5269
|
+
return;
|
|
5270
|
+
}
|
|
5271
|
+
|
|
5272
|
+
if (
|
|
5273
|
+
!sortedHandlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5274
|
+
|| erasedCache is not HandlerActionCache<Action<T>> cache
|
|
5275
|
+
)
|
|
5276
|
+
{
|
|
5277
|
+
return;
|
|
5278
|
+
}
|
|
5279
|
+
|
|
5280
|
+
List<Action<T>> handlers = GetOrAddNewHandlerStack(cache, emissionId);
|
|
5281
|
+
ref T typedMessage = ref Unsafe.As<TMessage, T>(ref message);
|
|
5282
|
+
int handlersCount = handlers.Count;
|
|
5283
|
+
switch (handlersCount)
|
|
5284
|
+
{
|
|
5285
|
+
case 1:
|
|
5286
|
+
{
|
|
5287
|
+
handlers[0](typedMessage);
|
|
5288
|
+
return;
|
|
5289
|
+
}
|
|
5290
|
+
case 2:
|
|
5291
|
+
{
|
|
5292
|
+
handlers[0](typedMessage);
|
|
5293
|
+
handlers[1](typedMessage);
|
|
5294
|
+
return;
|
|
5295
|
+
}
|
|
5296
|
+
case 3:
|
|
5297
|
+
{
|
|
5298
|
+
handlers[0](typedMessage);
|
|
5299
|
+
handlers[1](typedMessage);
|
|
5300
|
+
handlers[2](typedMessage);
|
|
5301
|
+
return;
|
|
5302
|
+
}
|
|
5303
|
+
case 4:
|
|
5304
|
+
{
|
|
5305
|
+
handlers[0](typedMessage);
|
|
5306
|
+
handlers[1](typedMessage);
|
|
5307
|
+
handlers[2](typedMessage);
|
|
5308
|
+
handlers[3](typedMessage);
|
|
5309
|
+
return;
|
|
5310
|
+
}
|
|
5311
|
+
case 5:
|
|
5312
|
+
{
|
|
5313
|
+
handlers[0](typedMessage);
|
|
5314
|
+
handlers[1](typedMessage);
|
|
5315
|
+
handlers[2](typedMessage);
|
|
5316
|
+
handlers[3](typedMessage);
|
|
5317
|
+
handlers[4](typedMessage);
|
|
5318
|
+
return;
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5321
|
+
|
|
5322
|
+
for (int i = 0; i < handlersCount; ++i)
|
|
5323
|
+
{
|
|
5324
|
+
handlers[i](typedMessage);
|
|
4160
5325
|
}
|
|
4161
|
-
|
|
4162
|
-
RunHandlers(cache, ref message, priority, emissionId);
|
|
4163
5326
|
}
|
|
4164
5327
|
|
|
4165
5328
|
private static void RunHandlers<TMessage>(
|
|
@@ -4228,6 +5391,79 @@ namespace DxMessaging.Core
|
|
|
4228
5391
|
}
|
|
4229
5392
|
}
|
|
4230
5393
|
|
|
5394
|
+
private static void RunHandlers<TMessage>(
|
|
5395
|
+
ref InstanceId context,
|
|
5396
|
+
Dictionary<int, IHandlerActionCache> handlers,
|
|
5397
|
+
ref TMessage message,
|
|
5398
|
+
int priority,
|
|
5399
|
+
long emissionId
|
|
5400
|
+
)
|
|
5401
|
+
where TMessage : IMessage
|
|
5402
|
+
{
|
|
5403
|
+
if (handlers is not { Count: > 0 })
|
|
5404
|
+
{
|
|
5405
|
+
return;
|
|
5406
|
+
}
|
|
5407
|
+
|
|
5408
|
+
if (
|
|
5409
|
+
!handlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5410
|
+
|| erasedCache is not HandlerActionCache<Action<InstanceId, T>> cache
|
|
5411
|
+
)
|
|
5412
|
+
{
|
|
5413
|
+
return;
|
|
5414
|
+
}
|
|
5415
|
+
|
|
5416
|
+
List<Action<InstanceId, T>> typedHandlers = GetOrAddNewHandlerStack(
|
|
5417
|
+
cache,
|
|
5418
|
+
emissionId
|
|
5419
|
+
);
|
|
5420
|
+
ref T typedMessage = ref Unsafe.As<TMessage, T>(ref message);
|
|
5421
|
+
int handlersCount = typedHandlers.Count;
|
|
5422
|
+
switch (handlersCount)
|
|
5423
|
+
{
|
|
5424
|
+
case 1:
|
|
5425
|
+
{
|
|
5426
|
+
typedHandlers[0](context, typedMessage);
|
|
5427
|
+
return;
|
|
5428
|
+
}
|
|
5429
|
+
case 2:
|
|
5430
|
+
{
|
|
5431
|
+
typedHandlers[0](context, typedMessage);
|
|
5432
|
+
typedHandlers[1](context, typedMessage);
|
|
5433
|
+
return;
|
|
5434
|
+
}
|
|
5435
|
+
case 3:
|
|
5436
|
+
{
|
|
5437
|
+
typedHandlers[0](context, typedMessage);
|
|
5438
|
+
typedHandlers[1](context, typedMessage);
|
|
5439
|
+
typedHandlers[2](context, typedMessage);
|
|
5440
|
+
return;
|
|
5441
|
+
}
|
|
5442
|
+
case 4:
|
|
5443
|
+
{
|
|
5444
|
+
typedHandlers[0](context, typedMessage);
|
|
5445
|
+
typedHandlers[1](context, typedMessage);
|
|
5446
|
+
typedHandlers[2](context, typedMessage);
|
|
5447
|
+
typedHandlers[3](context, typedMessage);
|
|
5448
|
+
return;
|
|
5449
|
+
}
|
|
5450
|
+
case 5:
|
|
5451
|
+
{
|
|
5452
|
+
typedHandlers[0](context, typedMessage);
|
|
5453
|
+
typedHandlers[1](context, typedMessage);
|
|
5454
|
+
typedHandlers[2](context, typedMessage);
|
|
5455
|
+
typedHandlers[3](context, typedMessage);
|
|
5456
|
+
typedHandlers[4](context, typedMessage);
|
|
5457
|
+
return;
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
for (int i = 0; i < handlersCount; ++i)
|
|
5462
|
+
{
|
|
5463
|
+
typedHandlers[i](context, typedMessage);
|
|
5464
|
+
}
|
|
5465
|
+
}
|
|
5466
|
+
|
|
4231
5467
|
private static void RunHandlers<TMessage>(
|
|
4232
5468
|
ref InstanceId context,
|
|
4233
5469
|
Dictionary<int, HandlerActionCache<Action<InstanceId, T>>> handlers,
|
|
@@ -4330,6 +5566,23 @@ namespace DxMessaging.Core
|
|
|
4330
5566
|
return actionCache.cache;
|
|
4331
5567
|
}
|
|
4332
5568
|
|
|
5569
|
+
private static void PrefreezeHandlersForEmission<THandler>(
|
|
5570
|
+
Dictionary<int, IHandlerActionCache> handlers,
|
|
5571
|
+
int priority,
|
|
5572
|
+
long emissionId
|
|
5573
|
+
)
|
|
5574
|
+
{
|
|
5575
|
+
if (
|
|
5576
|
+
handlers != null
|
|
5577
|
+
&& handlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5578
|
+
&& erasedCache is HandlerActionCache<THandler> cache
|
|
5579
|
+
)
|
|
5580
|
+
{
|
|
5581
|
+
cache.prefreezeInvocationCount++;
|
|
5582
|
+
_ = GetOrAddNewHandlerStack(cache, emissionId);
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
|
|
4333
5586
|
private static void PrefreezeHandlersForEmission<THandler>(
|
|
4334
5587
|
Dictionary<int, HandlerActionCache<THandler>> handlers,
|
|
4335
5588
|
int priority,
|
|
@@ -4346,6 +5599,102 @@ namespace DxMessaging.Core
|
|
|
4346
5599
|
}
|
|
4347
5600
|
}
|
|
4348
5601
|
|
|
5602
|
+
private static Action AddHandler<TU>(
|
|
5603
|
+
TypedGlobalSlot slot,
|
|
5604
|
+
TU originalHandler,
|
|
5605
|
+
TU augmentedHandler,
|
|
5606
|
+
Action deregistration,
|
|
5607
|
+
IMessageBus messageBus
|
|
5608
|
+
)
|
|
5609
|
+
{
|
|
5610
|
+
slot.lastTouchTicks =
|
|
5611
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(messageBus);
|
|
5612
|
+
HandlerActionCache<TU> cache = slot.cache as HandlerActionCache<TU>;
|
|
5613
|
+
if (cache == null)
|
|
5614
|
+
{
|
|
5615
|
+
cache = new HandlerActionCache<TU>();
|
|
5616
|
+
slot.cache = cache;
|
|
5617
|
+
}
|
|
5618
|
+
|
|
5619
|
+
if (
|
|
5620
|
+
!cache.entries.TryGetValue(
|
|
5621
|
+
originalHandler,
|
|
5622
|
+
out HandlerActionCache<TU>.Entry entry
|
|
5623
|
+
)
|
|
5624
|
+
)
|
|
5625
|
+
{
|
|
5626
|
+
entry = new HandlerActionCache<TU>.Entry(augmentedHandler, 0);
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5629
|
+
bool firstRegistration = entry.count == 0;
|
|
5630
|
+
entry = firstRegistration
|
|
5631
|
+
? new HandlerActionCache<TU>.Entry(augmentedHandler, 1)
|
|
5632
|
+
: new HandlerActionCache<TU>.Entry(entry.handler, entry.count + 1);
|
|
5633
|
+
|
|
5634
|
+
cache.entries[originalHandler] = entry;
|
|
5635
|
+
cache.version++;
|
|
5636
|
+
if (firstRegistration)
|
|
5637
|
+
{
|
|
5638
|
+
slot.liveCount++;
|
|
5639
|
+
}
|
|
5640
|
+
|
|
5641
|
+
HandlerActionCache<TU> localCache = cache;
|
|
5642
|
+
TypedGlobalSlot localSlot = slot;
|
|
5643
|
+
long localSlotVersion = slot.version;
|
|
5644
|
+
long localResetGeneration =
|
|
5645
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetResetGeneration(messageBus);
|
|
5646
|
+
|
|
5647
|
+
return () =>
|
|
5648
|
+
{
|
|
5649
|
+
if (
|
|
5650
|
+
!global::DxMessaging.Core.MessageBus.MessageBus.IsResetGenerationCurrent(
|
|
5651
|
+
messageBus,
|
|
5652
|
+
localResetGeneration
|
|
5653
|
+
)
|
|
5654
|
+
)
|
|
5655
|
+
{
|
|
5656
|
+
return;
|
|
5657
|
+
}
|
|
5658
|
+
|
|
5659
|
+
if (localSlot.version != localSlotVersion)
|
|
5660
|
+
{
|
|
5661
|
+
return;
|
|
5662
|
+
}
|
|
5663
|
+
|
|
5664
|
+
if (
|
|
5665
|
+
!localCache.entries.TryGetValue(
|
|
5666
|
+
originalHandler,
|
|
5667
|
+
out HandlerActionCache<TU>.Entry localEntry
|
|
5668
|
+
)
|
|
5669
|
+
)
|
|
5670
|
+
{
|
|
5671
|
+
return;
|
|
5672
|
+
}
|
|
5673
|
+
|
|
5674
|
+
localCache.version++;
|
|
5675
|
+
|
|
5676
|
+
deregistration?.Invoke();
|
|
5677
|
+
localSlot.lastTouchTicks =
|
|
5678
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(
|
|
5679
|
+
messageBus
|
|
5680
|
+
);
|
|
5681
|
+
|
|
5682
|
+
if (localEntry.count <= 1)
|
|
5683
|
+
{
|
|
5684
|
+
_ = localCache.entries.Remove(originalHandler);
|
|
5685
|
+
localCache.version++;
|
|
5686
|
+
localSlot.liveCount--;
|
|
5687
|
+
return;
|
|
5688
|
+
}
|
|
5689
|
+
|
|
5690
|
+
localEntry = new HandlerActionCache<TU>.Entry(
|
|
5691
|
+
localEntry.handler,
|
|
5692
|
+
localEntry.count - 1
|
|
5693
|
+
);
|
|
5694
|
+
localCache.entries[originalHandler] = localEntry;
|
|
5695
|
+
};
|
|
5696
|
+
}
|
|
5697
|
+
|
|
4349
5698
|
private static Action AddHandler<TU>(
|
|
4350
5699
|
InstanceId context,
|
|
4351
5700
|
ref Dictionary<
|
|
@@ -4356,7 +5705,7 @@ namespace DxMessaging.Core
|
|
|
4356
5705
|
TU augmentedHandler,
|
|
4357
5706
|
Action deregistration,
|
|
4358
5707
|
int priority,
|
|
4359
|
-
|
|
5708
|
+
IMessageBus messageBus
|
|
4360
5709
|
)
|
|
4361
5710
|
{
|
|
4362
5711
|
handlersByContext ??=
|
|
@@ -4597,6 +5946,134 @@ namespace DxMessaging.Core
|
|
|
4597
5946
|
// Variant of AddHandler that preserves the priority key in the dictionary when the last entry is removed.
|
|
4598
5947
|
// This ensures that during an in-flight emission (where handler stacks are already frozen),
|
|
4599
5948
|
// subsequent removals do not cause lookups to fail for the current pass.
|
|
5949
|
+
private Action AddHandlerPreservingPriorityKey<TU>(
|
|
5950
|
+
Dictionary<int, IHandlerActionCache> handlers,
|
|
5951
|
+
TU originalHandler,
|
|
5952
|
+
TU augmentedHandler,
|
|
5953
|
+
Action deregistration,
|
|
5954
|
+
int priority,
|
|
5955
|
+
IMessageBus messageBus
|
|
5956
|
+
)
|
|
5957
|
+
{
|
|
5958
|
+
if (
|
|
5959
|
+
!handlers.TryGetValue(priority, out IHandlerActionCache erasedCache)
|
|
5960
|
+
|| erasedCache is not HandlerActionCache<TU> cache
|
|
5961
|
+
)
|
|
5962
|
+
{
|
|
5963
|
+
cache = new HandlerActionCache<TU>();
|
|
5964
|
+
handlers[priority] = cache;
|
|
5965
|
+
}
|
|
5966
|
+
|
|
5967
|
+
if (
|
|
5968
|
+
!cache.entries.TryGetValue(
|
|
5969
|
+
originalHandler,
|
|
5970
|
+
out HandlerActionCache<TU>.Entry entry
|
|
5971
|
+
)
|
|
5972
|
+
)
|
|
5973
|
+
{
|
|
5974
|
+
entry = new HandlerActionCache<TU>.Entry(augmentedHandler, 0);
|
|
5975
|
+
}
|
|
5976
|
+
|
|
5977
|
+
bool firstRegistration = entry.count == 0;
|
|
5978
|
+
entry = firstRegistration
|
|
5979
|
+
? new HandlerActionCache<TU>.Entry(augmentedHandler, 1)
|
|
5980
|
+
: new HandlerActionCache<TU>.Entry(entry.handler, entry.count + 1);
|
|
5981
|
+
|
|
5982
|
+
cache.entries[originalHandler] = entry;
|
|
5983
|
+
cache.version++;
|
|
5984
|
+
TypedSlot<T> slot = FindPrioritySlot(handlers);
|
|
5985
|
+
if (slot != null)
|
|
5986
|
+
{
|
|
5987
|
+
slot.lastTouchTicks =
|
|
5988
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(
|
|
5989
|
+
messageBus
|
|
5990
|
+
);
|
|
5991
|
+
}
|
|
5992
|
+
if (slot != null && !slot.orderedPriorities.Contains(priority))
|
|
5993
|
+
{
|
|
5994
|
+
slot.orderedPriorities.Add(priority);
|
|
5995
|
+
}
|
|
5996
|
+
if (firstRegistration && slot != null)
|
|
5997
|
+
{
|
|
5998
|
+
slot.liveCount++;
|
|
5999
|
+
}
|
|
6000
|
+
|
|
6001
|
+
Dictionary<int, IHandlerActionCache> localHandlers = handlers;
|
|
6002
|
+
TypedSlot<T> localSlot = slot;
|
|
6003
|
+
long localSlotVersion = slot?.version ?? 0;
|
|
6004
|
+
long localResetGeneration =
|
|
6005
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetResetGeneration(messageBus);
|
|
6006
|
+
|
|
6007
|
+
return () =>
|
|
6008
|
+
{
|
|
6009
|
+
if (
|
|
6010
|
+
!global::DxMessaging.Core.MessageBus.MessageBus.IsResetGenerationCurrent(
|
|
6011
|
+
messageBus,
|
|
6012
|
+
localResetGeneration
|
|
6013
|
+
)
|
|
6014
|
+
)
|
|
6015
|
+
{
|
|
6016
|
+
return;
|
|
6017
|
+
}
|
|
6018
|
+
|
|
6019
|
+
if (localSlot != null && localSlot.version != localSlotVersion)
|
|
6020
|
+
{
|
|
6021
|
+
return;
|
|
6022
|
+
}
|
|
6023
|
+
|
|
6024
|
+
if (
|
|
6025
|
+
!localHandlers.TryGetValue(
|
|
6026
|
+
priority,
|
|
6027
|
+
out IHandlerActionCache localErasedCache
|
|
6028
|
+
) || localErasedCache is not HandlerActionCache<TU> localCache
|
|
6029
|
+
)
|
|
6030
|
+
{
|
|
6031
|
+
return;
|
|
6032
|
+
}
|
|
6033
|
+
|
|
6034
|
+
if (
|
|
6035
|
+
!localCache.entries.TryGetValue(
|
|
6036
|
+
originalHandler,
|
|
6037
|
+
out HandlerActionCache<TU>.Entry localEntry
|
|
6038
|
+
)
|
|
6039
|
+
)
|
|
6040
|
+
{
|
|
6041
|
+
return;
|
|
6042
|
+
}
|
|
6043
|
+
|
|
6044
|
+
localCache.version++;
|
|
6045
|
+
|
|
6046
|
+
deregistration?.Invoke();
|
|
6047
|
+
if (localSlot != null)
|
|
6048
|
+
{
|
|
6049
|
+
localSlot.lastTouchTicks =
|
|
6050
|
+
global::DxMessaging.Core.MessageBus.MessageBus.GetCurrentTouchTick(
|
|
6051
|
+
messageBus
|
|
6052
|
+
);
|
|
6053
|
+
}
|
|
6054
|
+
|
|
6055
|
+
if (localEntry.count <= 1)
|
|
6056
|
+
{
|
|
6057
|
+
_ = localCache.entries.Remove(originalHandler);
|
|
6058
|
+
localCache.version++;
|
|
6059
|
+
if (localSlot != null)
|
|
6060
|
+
{
|
|
6061
|
+
localSlot.liveCount--;
|
|
6062
|
+
}
|
|
6063
|
+
// Intentionally DO NOT remove the priority key here to preserve
|
|
6064
|
+
// the cache handle during an in-flight emission.
|
|
6065
|
+
return;
|
|
6066
|
+
}
|
|
6067
|
+
|
|
6068
|
+
localEntry = new HandlerActionCache<TU>.Entry(
|
|
6069
|
+
localEntry.handler,
|
|
6070
|
+
localEntry.count - 1
|
|
6071
|
+
);
|
|
6072
|
+
|
|
6073
|
+
localCache.entries[originalHandler] = localEntry;
|
|
6074
|
+
};
|
|
6075
|
+
}
|
|
6076
|
+
|
|
4600
6077
|
private static Action AddHandlerPreservingPriorityKey<TU>(
|
|
4601
6078
|
ref Dictionary<int, HandlerActionCache<TU>> handlers,
|
|
4602
6079
|
TU originalHandler,
|