com.wallstop-studios.dxmessaging 3.1.0 → 3.2.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 +326 -0
- package/Editor/Analyzers/BaseCallLogMessageParser.cs.meta +3 -3
- package/Editor/Analyzers/BaseCallReportAggregator.cs.meta +3 -3
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +8 -8
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +171 -13
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +391 -96
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs +279 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs.meta +11 -0
- package/Editor/DxMessagingEditorPalette.cs +66 -0
- package/Editor/DxMessagingEditorPalette.cs.meta +11 -0
- package/Editor/DxMessagingEditorTheme.cs +200 -0
- package/Editor/DxMessagingEditorTheme.cs.meta +11 -0
- package/Editor/DxMessagingMenu.cs.meta +3 -3
- package/Editor/DxMessagingSceneBuildProcessor.cs.meta +3 -3
- package/Editor/Icons/dxmessaging-icon-256.png +0 -0
- package/Editor/Icons/dxmessaging-icon-256.png.meta +156 -0
- package/Editor/Icons/dxmessaging-icon-32.png +0 -0
- package/Editor/Icons/dxmessaging-icon-32.png.meta +156 -0
- package/Editor/Icons/dxmessaging-icon-48.png +0 -0
- package/Editor/Icons/dxmessaging-icon-48.png.meta +156 -0
- package/Editor/Icons.meta +8 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +2 -3
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs.meta +3 -3
- package/Editor/Settings/DxMessagingSettingsProvider.cs +368 -33
- package/Editor/SetupCscRsp.cs +232 -163
- package/Editor/Testing/MessagingComponentEditorHarness.cs +11 -4
- package/Editor/Theme/DxMessagingTheme.uss +255 -0
- package/Editor/Theme/DxMessagingTheme.uss.meta +11 -0
- package/Editor/Theme/DxTokens.uss +90 -0
- package/Editor/Theme/DxTokens.uss.meta +11 -0
- package/Editor/Theme.meta +8 -0
- package/Editor/Windows/DxMessagingFlowGraphWindow.cs +5513 -0
- package/Editor/Windows/DxMessagingFlowGraphWindow.cs.meta +11 -0
- package/Editor/Windows/DxMessagingMessageMonitorWindow.cs +2288 -0
- package/Editor/Windows/DxMessagingMessageMonitorWindow.cs.meta +11 -0
- package/Editor/Windows.meta +8 -0
- package/README.md +84 -35
- package/Runtime/Analyzers.meta +8 -0
- package/Runtime/AssemblyInfo.cs +1 -0
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs.meta +3 -3
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs +29 -1
- package/Runtime/Core/DxMessagingStaticState.cs.meta +3 -3
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +3 -3
- package/Runtime/Core/Extensions/MessageExtensions.cs +4 -5
- package/Runtime/Core/Extensions/MessageExtensions.cs.meta +3 -3
- package/Runtime/Core/Helper/MessageCache.cs +56 -23
- package/Runtime/Core/IMessage.cs.meta +3 -3
- package/Runtime/Core/InstanceId.cs.meta +3 -3
- package/Runtime/Core/Internal/FlatDispatch.cs +32 -0
- package/Runtime/Core/Internal/TypedSlots.cs +45 -7
- package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +3 -3
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageBus.cs +63 -28
- package/Runtime/Core/MessageBus/IMessageBus.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBus.cs +1135 -626
- package/Runtime/Core/MessageBus/MessageBus.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBusRegistration.cs +207 -0
- package/Runtime/Core/MessageBus/MessageBusRegistration.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +3 -3
- package/Runtime/Core/MessageBus/RegistrationLog.cs +25 -12
- package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +3 -3
- package/Runtime/Core/MessageHandler.cs +1886 -1082
- package/Runtime/Core/MessageHandler.cs.meta +3 -3
- package/Runtime/Core/MessageRegistrationHandle.cs +19 -5
- package/Runtime/Core/MessageRegistrationHandle.cs.meta +3 -3
- package/Runtime/Core/MessageRegistrationToken.cs +1932 -895
- package/Runtime/Core/MessageRegistrationToken.cs.meta +3 -3
- package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/ITargetedMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/SourcedStringMessage.cs.meta +3 -3
- package/Runtime/Core/MessagingDebug.cs.meta +3 -3
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +3 -3
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +3 -3
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +3 -3
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +3 -3
- package/Runtime/Unity/MessageAwareComponent.cs.meta +3 -3
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +3 -3
- package/Runtime/Unity/MessagingComponent.cs.meta +3 -3
- package/Runtime/Unity/MessagingComponentInstaller.cs.meta +3 -3
- package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +3 -3
- package/Samples~/DI/Reflex/SampleInstaller.cs.meta +3 -3
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +3 -3
- package/Samples~/DI/Zenject/SampleInstaller.cs.meta +3 -3
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs +173 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity +424 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs +185 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/Messages.cs +46 -0
- package/Samples~/Diagnostics Tooling Exerciser/Messages.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/README.md +53 -0
- package/Samples~/Diagnostics Tooling Exerciser/README.md.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef +13 -0
- package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser.meta +8 -0
- package/Samples~/Mini Combat/Boot.cs.meta +3 -3
- package/Samples~/Mini Combat/Enemy.cs.meta +3 -3
- package/Samples~/Mini Combat/Messages.cs.meta +3 -3
- package/Samples~/Mini Combat/Player.cs.meta +3 -3
- package/Samples~/Mini Combat/README.md +1 -1
- package/Samples~/Mini Combat/UIOverlay.cs.meta +3 -3
- package/Samples~/Mini Combat/Walkthrough.md +3 -3
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/Messages.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/MessagingObserver.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/UIButtonEmitter.cs.meta +3 -3
- package/SourceGenerators/Directory.Build.props +5 -5
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs.meta +3 -3
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +12 -11
- package/docs/images/DxMessaging-banner.svg +79 -0
- package/docs/images/DxMessaging-banner.svg.meta +53 -0
- package/docs/images.meta +8 -0
- package/docs.meta +8 -0
- package/package.json +17 -5
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +0 -0
|
@@ -58,32 +58,86 @@ namespace DxMessaging.Core
|
|
|
58
58
|
|
|
59
59
|
private readonly MessageHandler _messageHandler;
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// (
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
61
|
+
// Maps each staged registration handle to the unified per-handle Registration
|
|
62
|
+
// object the public Register* methods built. Calling Registration.Register()
|
|
63
|
+
// (re)registers the handler on the bus and returns the matching
|
|
64
|
+
// HandlerDeregistration. The Registration object IS the collapsed staging
|
|
65
|
+
// state: it replaces (a) the per-registration staging Func display class, (b)
|
|
66
|
+
// the staging Func delegate itself, and (c) the nested AugmentedHandler
|
|
67
|
+
// local-function delegate -- the captured target/source, user handler,
|
|
68
|
+
// priority, and kind are now plain fields, and the diagnostics-augmented
|
|
69
|
+
// invoker is an instance method bound to the object (the FastHandler<T> handed
|
|
70
|
+
// to MessageHandler is (FastHandler<T>)registration.AugmentedHandlerScalar).
|
|
71
|
+
// The registration also owns its common teardown state, eliminating the separate
|
|
72
|
+
// HandlerDeregistration object; an allocation-backed wrapper is created only for
|
|
73
|
+
// overlapping retry/recovery state. Net ~ -3 managed allocations per registration.
|
|
74
|
+
// The central replay loop pairs
|
|
75
|
+
// the Registration with its handle and performs the AddDeregistration. The
|
|
76
|
+
// re-entrancy snapshot semantics are unchanged: the replay queue captures the
|
|
77
|
+
// Registration reference (exactly as it previously captured the staging Func),
|
|
78
|
+
// so a registration removed mid-replay is still replayed if it was already
|
|
79
|
+
// snapshotted.
|
|
80
|
+
// Token-owned arena. A handle identifies a slot and the globally unique id that
|
|
81
|
+
// occupied it. Both are validated, so stale handles remain harmless after slot reuse.
|
|
82
|
+
// The doubly-linked live list preserves registration order while the singly-linked
|
|
83
|
+
// free list makes insertion and removal O(1).
|
|
84
|
+
private RegistrationSlot[] _slots = Array.Empty<RegistrationSlot>();
|
|
85
|
+
private int _registrationHead = -1;
|
|
86
|
+
private int _registrationTail = -1;
|
|
87
|
+
private int _freeSlotHead = -1;
|
|
88
|
+
private int _registrationCount;
|
|
89
|
+
private int _deregistrationCount;
|
|
90
|
+
|
|
91
|
+
// Lifecycle snapshots are exceptional-path storage and materialize only when a replay,
|
|
92
|
+
// teardown, or retarget actually needs them.
|
|
93
|
+
private List<StagedRegistration> _registrationReplayQueue;
|
|
94
|
+
private List<TeardownIdentity> _teardownQueue;
|
|
95
|
+
private Dictionary<MessageRegistrationHandle, int> _rollbackCounts;
|
|
96
|
+
private List<MessageRegistrationHandle> _activeRetargetHandles;
|
|
97
|
+
private Dictionary<MessageRegistrationHandle, object> _orphanDeregistrations;
|
|
98
|
+
|
|
99
|
+
internal RegistrationMetadataView _metadata => new RegistrationMetadataView(this);
|
|
100
|
+
|
|
101
|
+
// Diagnostics-only collections, allocated lazily on first use. A token whose
|
|
102
|
+
// owner never enables diagnostics (the default -- GlobalDiagnosticsTargets is
|
|
103
|
+
// Off -- and the common player case) never materializes them, saving the
|
|
104
|
+
// dictionary, the cyclic buffer, and the buffer's two backing lists per token.
|
|
105
|
+
// These are exposed as properties under their original field names so the
|
|
106
|
+
// inspector overlay and the diagnostics tests (which read token._callCounts /
|
|
107
|
+
// token._emissionBuffer) compile and behave unchanged; the getter caches into
|
|
108
|
+
// the backing field, so repeated reads return the same instance and an editor
|
|
109
|
+
// read simply materializes an empty collection. The only production writers are
|
|
110
|
+
// the dispatch-time AugmentedHandler bodies, all guarded by _diagnosticMode, so
|
|
111
|
+
// production-with-diagnostics-off never triggers the allocation. Teardown
|
|
112
|
+
// (ClearDiagnosticState / RemoveRegistrationState /
|
|
113
|
+
// PruneRegistrationStateToFailedDeregistrations) clears through the backing
|
|
114
|
+
// fields to avoid materializing a collection just to empty it.
|
|
115
|
+
private Dictionary<MessageRegistrationHandle, int> _callCountsBacking;
|
|
116
|
+
private CyclicBuffer<MessageEmissionData> _emissionBufferBacking;
|
|
117
|
+
|
|
118
|
+
internal Dictionary<MessageRegistrationHandle, int> _callCounts =>
|
|
119
|
+
_callCountsBacking ??= new Dictionary<MessageRegistrationHandle, int>();
|
|
120
|
+
|
|
121
|
+
internal CyclicBuffer<MessageEmissionData> _emissionBuffer =>
|
|
122
|
+
_emissionBufferBacking ??= new CyclicBuffer<MessageEmissionData>(
|
|
123
|
+
IMessageBus.GlobalMessageBufferSize
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
internal void RecordDiagnosticEmission(
|
|
127
|
+
MessageRegistrationHandle handle,
|
|
128
|
+
IMessageBus messageBus,
|
|
129
|
+
IMessage message,
|
|
130
|
+
InstanceId? context = null
|
|
131
|
+
)
|
|
132
|
+
{
|
|
133
|
+
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
134
|
+
long traceId =
|
|
135
|
+
messageBus is DxMessaging.Core.MessageBus.MessageBus concreteBus
|
|
136
|
+
&& concreteBus.IsDispatching
|
|
137
|
+
? concreteBus.EmissionId
|
|
138
|
+
: 0;
|
|
139
|
+
_emissionBuffer.Add(new MessageEmissionData(message, context, traceId, handle));
|
|
140
|
+
}
|
|
87
141
|
|
|
88
142
|
private IMessageBus _messageBus;
|
|
89
143
|
private bool _enabled;
|
|
@@ -109,33 +163,13 @@ namespace DxMessaging.Core
|
|
|
109
163
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
110
164
|
}
|
|
111
165
|
return InternalRegister(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
messageBus: _messageBus
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
void AugmentedHandler(T message)
|
|
123
|
-
{
|
|
124
|
-
targetedHandler(message);
|
|
125
|
-
if (_diagnosticMode)
|
|
126
|
-
{
|
|
127
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
128
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
() =>
|
|
133
|
-
new MessageRegistrationMetadata(
|
|
134
|
-
target,
|
|
135
|
-
typeof(T),
|
|
136
|
-
MessageRegistrationType.Targeted,
|
|
137
|
-
priority
|
|
138
|
-
)
|
|
166
|
+
new TargetedRegistration<T>(
|
|
167
|
+
this,
|
|
168
|
+
RegistrationKind.TargetedHandlerAction,
|
|
169
|
+
target,
|
|
170
|
+
targetedHandler,
|
|
171
|
+
priority
|
|
172
|
+
)
|
|
139
173
|
);
|
|
140
174
|
}
|
|
141
175
|
|
|
@@ -152,33 +186,13 @@ namespace DxMessaging.Core
|
|
|
152
186
|
}
|
|
153
187
|
|
|
154
188
|
return InternalRegister(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
messageBus: _messageBus
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
void AugmentedHandler(ref T message)
|
|
166
|
-
{
|
|
167
|
-
targetedHandler(ref message);
|
|
168
|
-
if (_diagnosticMode)
|
|
169
|
-
{
|
|
170
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
171
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
() =>
|
|
176
|
-
new MessageRegistrationMetadata(
|
|
177
|
-
target,
|
|
178
|
-
typeof(T),
|
|
179
|
-
MessageRegistrationType.Targeted,
|
|
180
|
-
priority
|
|
181
|
-
)
|
|
189
|
+
new TargetedRegistration<T>(
|
|
190
|
+
this,
|
|
191
|
+
RegistrationKind.TargetedHandlerFast,
|
|
192
|
+
target,
|
|
193
|
+
targetedHandler,
|
|
194
|
+
priority
|
|
195
|
+
)
|
|
182
196
|
);
|
|
183
197
|
}
|
|
184
198
|
|
|
@@ -300,33 +314,13 @@ namespace DxMessaging.Core
|
|
|
300
314
|
where T : ITargetedMessage
|
|
301
315
|
{
|
|
302
316
|
return InternalRegister(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
_messageBus
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
void AugmentedHandler(ref T message)
|
|
314
|
-
{
|
|
315
|
-
targetedPostProcessor(ref message);
|
|
316
|
-
if (_diagnosticMode)
|
|
317
|
-
{
|
|
318
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
319
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
() =>
|
|
324
|
-
new MessageRegistrationMetadata(
|
|
325
|
-
target,
|
|
326
|
-
typeof(T),
|
|
327
|
-
MessageRegistrationType.TargetedPostProcessor,
|
|
328
|
-
priority
|
|
329
|
-
)
|
|
317
|
+
new TargetedRegistration<T>(
|
|
318
|
+
this,
|
|
319
|
+
RegistrationKind.TargetedPostProcessorFast,
|
|
320
|
+
target,
|
|
321
|
+
targetedPostProcessor,
|
|
322
|
+
priority
|
|
323
|
+
)
|
|
330
324
|
);
|
|
331
325
|
}
|
|
332
326
|
|
|
@@ -346,33 +340,13 @@ namespace DxMessaging.Core
|
|
|
346
340
|
where T : ITargetedMessage
|
|
347
341
|
{
|
|
348
342
|
return InternalRegister(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
_messageBus
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
void AugmentedHandler(ref T message)
|
|
360
|
-
{
|
|
361
|
-
targetedPostProcessor(ref message);
|
|
362
|
-
if (_diagnosticMode)
|
|
363
|
-
{
|
|
364
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
365
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
},
|
|
369
|
-
() =>
|
|
370
|
-
new MessageRegistrationMetadata(
|
|
371
|
-
target,
|
|
372
|
-
typeof(T),
|
|
373
|
-
MessageRegistrationType.TargetedPostProcessor,
|
|
374
|
-
priority
|
|
375
|
-
)
|
|
343
|
+
new TargetedRegistration<T>(
|
|
344
|
+
this,
|
|
345
|
+
RegistrationKind.TargetedPostProcessorFast,
|
|
346
|
+
target,
|
|
347
|
+
targetedPostProcessor,
|
|
348
|
+
priority
|
|
349
|
+
)
|
|
376
350
|
);
|
|
377
351
|
}
|
|
378
352
|
#endif
|
|
@@ -435,33 +409,13 @@ namespace DxMessaging.Core
|
|
|
435
409
|
where T : ITargetedMessage
|
|
436
410
|
{
|
|
437
411
|
return InternalRegister(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
_messageBus
|
|
446
|
-
);
|
|
447
|
-
|
|
448
|
-
void AugmentedHandler(ref T message)
|
|
449
|
-
{
|
|
450
|
-
targetedPostProcessor(ref message);
|
|
451
|
-
if (_diagnosticMode)
|
|
452
|
-
{
|
|
453
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
454
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
},
|
|
458
|
-
() =>
|
|
459
|
-
new MessageRegistrationMetadata(
|
|
460
|
-
target,
|
|
461
|
-
typeof(T),
|
|
462
|
-
MessageRegistrationType.TargetedPostProcessor,
|
|
463
|
-
priority
|
|
464
|
-
)
|
|
412
|
+
new TargetedRegistration<T>(
|
|
413
|
+
this,
|
|
414
|
+
RegistrationKind.TargetedPostProcessorFast,
|
|
415
|
+
target,
|
|
416
|
+
targetedPostProcessor,
|
|
417
|
+
priority
|
|
418
|
+
)
|
|
465
419
|
);
|
|
466
420
|
}
|
|
467
421
|
|
|
@@ -481,33 +435,13 @@ namespace DxMessaging.Core
|
|
|
481
435
|
where T : ITargetedMessage
|
|
482
436
|
{
|
|
483
437
|
return InternalRegister(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
_messageBus
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
void AugmentedHandler(T message)
|
|
495
|
-
{
|
|
496
|
-
targetedPostProcessor(message);
|
|
497
|
-
if (_diagnosticMode)
|
|
498
|
-
{
|
|
499
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
500
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
},
|
|
504
|
-
() =>
|
|
505
|
-
new MessageRegistrationMetadata(
|
|
506
|
-
target,
|
|
507
|
-
typeof(T),
|
|
508
|
-
MessageRegistrationType.TargetedPostProcessor,
|
|
509
|
-
priority
|
|
510
|
-
)
|
|
438
|
+
new TargetedRegistration<T>(
|
|
439
|
+
this,
|
|
440
|
+
RegistrationKind.TargetedPostProcessorAction,
|
|
441
|
+
target,
|
|
442
|
+
targetedPostProcessor,
|
|
443
|
+
priority
|
|
444
|
+
)
|
|
511
445
|
);
|
|
512
446
|
}
|
|
513
447
|
|
|
@@ -532,32 +466,13 @@ namespace DxMessaging.Core
|
|
|
532
466
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
533
467
|
}
|
|
534
468
|
return InternalRegister(
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
);
|
|
543
|
-
|
|
544
|
-
void AugmentedHandler(InstanceId target, T message)
|
|
545
|
-
{
|
|
546
|
-
messageHandler(target, message);
|
|
547
|
-
if (_diagnosticMode)
|
|
548
|
-
{
|
|
549
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
550
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
},
|
|
554
|
-
() =>
|
|
555
|
-
new MessageRegistrationMetadata(
|
|
556
|
-
null,
|
|
557
|
-
typeof(T),
|
|
558
|
-
MessageRegistrationType.TargetedWithoutTargeting,
|
|
559
|
-
priority
|
|
560
|
-
)
|
|
469
|
+
new TargetedRegistration<T>(
|
|
470
|
+
this,
|
|
471
|
+
RegistrationKind.TargetedWithoutTargetingAction,
|
|
472
|
+
default,
|
|
473
|
+
messageHandler,
|
|
474
|
+
priority
|
|
475
|
+
)
|
|
561
476
|
);
|
|
562
477
|
}
|
|
563
478
|
|
|
@@ -582,32 +497,13 @@ namespace DxMessaging.Core
|
|
|
582
497
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
583
498
|
}
|
|
584
499
|
return InternalRegister(
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
);
|
|
593
|
-
|
|
594
|
-
void AugmentedHandler(ref InstanceId target, ref T message)
|
|
595
|
-
{
|
|
596
|
-
messageHandler(ref target, ref message);
|
|
597
|
-
if (_diagnosticMode)
|
|
598
|
-
{
|
|
599
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
600
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
},
|
|
604
|
-
() =>
|
|
605
|
-
new MessageRegistrationMetadata(
|
|
606
|
-
null,
|
|
607
|
-
typeof(T),
|
|
608
|
-
MessageRegistrationType.TargetedWithoutTargeting,
|
|
609
|
-
priority
|
|
610
|
-
)
|
|
500
|
+
new TargetedRegistration<T>(
|
|
501
|
+
this,
|
|
502
|
+
RegistrationKind.TargetedWithoutTargetingFast,
|
|
503
|
+
default,
|
|
504
|
+
messageHandler,
|
|
505
|
+
priority
|
|
506
|
+
)
|
|
611
507
|
);
|
|
612
508
|
}
|
|
613
509
|
|
|
@@ -632,32 +528,13 @@ namespace DxMessaging.Core
|
|
|
632
528
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
633
529
|
}
|
|
634
530
|
return InternalRegister(
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
);
|
|
643
|
-
|
|
644
|
-
void AugmentedHandler(InstanceId target, T message)
|
|
645
|
-
{
|
|
646
|
-
postProcessor(target, message);
|
|
647
|
-
if (_diagnosticMode)
|
|
648
|
-
{
|
|
649
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
650
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
},
|
|
654
|
-
() =>
|
|
655
|
-
new MessageRegistrationMetadata(
|
|
656
|
-
null,
|
|
657
|
-
typeof(T),
|
|
658
|
-
MessageRegistrationType.TargetedWithoutTargetingPostProcessor,
|
|
659
|
-
priority
|
|
660
|
-
)
|
|
531
|
+
new TargetedRegistration<T>(
|
|
532
|
+
this,
|
|
533
|
+
RegistrationKind.TargetedWithoutTargetingPostProcessorAction,
|
|
534
|
+
default,
|
|
535
|
+
postProcessor,
|
|
536
|
+
priority
|
|
537
|
+
)
|
|
661
538
|
);
|
|
662
539
|
}
|
|
663
540
|
|
|
@@ -682,32 +559,13 @@ namespace DxMessaging.Core
|
|
|
682
559
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
683
560
|
}
|
|
684
561
|
return InternalRegister(
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
);
|
|
693
|
-
|
|
694
|
-
void AugmentedHandler(ref InstanceId target, ref T message)
|
|
695
|
-
{
|
|
696
|
-
postProcessor(ref target, ref message);
|
|
697
|
-
if (_diagnosticMode)
|
|
698
|
-
{
|
|
699
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
700
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
},
|
|
704
|
-
() =>
|
|
705
|
-
new MessageRegistrationMetadata(
|
|
706
|
-
null,
|
|
707
|
-
typeof(T),
|
|
708
|
-
MessageRegistrationType.TargetedWithoutTargetingPostProcessor,
|
|
709
|
-
priority
|
|
710
|
-
)
|
|
562
|
+
new TargetedRegistration<T>(
|
|
563
|
+
this,
|
|
564
|
+
RegistrationKind.TargetedWithoutTargetingPostProcessorFast,
|
|
565
|
+
default,
|
|
566
|
+
postProcessor,
|
|
567
|
+
priority
|
|
568
|
+
)
|
|
711
569
|
);
|
|
712
570
|
}
|
|
713
571
|
|
|
@@ -739,32 +597,12 @@ namespace DxMessaging.Core
|
|
|
739
597
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
740
598
|
}
|
|
741
599
|
return InternalRegister(
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
messageBus: _messageBus
|
|
749
|
-
);
|
|
750
|
-
|
|
751
|
-
void AugmentedHandler(T message)
|
|
752
|
-
{
|
|
753
|
-
untargetedHandler(message);
|
|
754
|
-
if (_diagnosticMode)
|
|
755
|
-
{
|
|
756
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
757
|
-
_emissionBuffer.Add(new MessageEmissionData(message));
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
},
|
|
761
|
-
() =>
|
|
762
|
-
new MessageRegistrationMetadata(
|
|
763
|
-
null,
|
|
764
|
-
typeof(T),
|
|
765
|
-
MessageRegistrationType.Untargeted,
|
|
766
|
-
priority
|
|
767
|
-
)
|
|
600
|
+
new UntargetedRegistration<T>(
|
|
601
|
+
this,
|
|
602
|
+
RegistrationKind.UntargetedHandlerAction,
|
|
603
|
+
untargetedHandler,
|
|
604
|
+
priority
|
|
605
|
+
)
|
|
768
606
|
);
|
|
769
607
|
}
|
|
770
608
|
|
|
@@ -795,32 +633,12 @@ namespace DxMessaging.Core
|
|
|
795
633
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
796
634
|
}
|
|
797
635
|
return InternalRegister(
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
messageBus: _messageBus
|
|
805
|
-
);
|
|
806
|
-
|
|
807
|
-
void AugmentedHandler(ref T message)
|
|
808
|
-
{
|
|
809
|
-
untargetedHandler(ref message);
|
|
810
|
-
if (_diagnosticMode)
|
|
811
|
-
{
|
|
812
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
813
|
-
_emissionBuffer.Add(new MessageEmissionData(message));
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
},
|
|
817
|
-
() =>
|
|
818
|
-
new MessageRegistrationMetadata(
|
|
819
|
-
null,
|
|
820
|
-
typeof(T),
|
|
821
|
-
MessageRegistrationType.Untargeted,
|
|
822
|
-
priority
|
|
823
|
-
)
|
|
636
|
+
new UntargetedRegistration<T>(
|
|
637
|
+
this,
|
|
638
|
+
RegistrationKind.UntargetedHandlerFast,
|
|
639
|
+
untargetedHandler,
|
|
640
|
+
priority
|
|
641
|
+
)
|
|
824
642
|
);
|
|
825
643
|
}
|
|
826
644
|
|
|
@@ -842,32 +660,12 @@ namespace DxMessaging.Core
|
|
|
842
660
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
843
661
|
}
|
|
844
662
|
return InternalRegister(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
_messageBus
|
|
852
|
-
);
|
|
853
|
-
|
|
854
|
-
void AugmentedHandler(ref T message)
|
|
855
|
-
{
|
|
856
|
-
untargetedPostProcessor(ref message);
|
|
857
|
-
if (_diagnosticMode)
|
|
858
|
-
{
|
|
859
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
860
|
-
_emissionBuffer.Add(new MessageEmissionData(message));
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
},
|
|
864
|
-
() =>
|
|
865
|
-
new MessageRegistrationMetadata(
|
|
866
|
-
null,
|
|
867
|
-
typeof(T),
|
|
868
|
-
MessageRegistrationType.UntargetedPostProcessor,
|
|
869
|
-
priority
|
|
870
|
-
)
|
|
663
|
+
new UntargetedRegistration<T>(
|
|
664
|
+
this,
|
|
665
|
+
RegistrationKind.UntargetedPostProcessorFast,
|
|
666
|
+
untargetedPostProcessor,
|
|
667
|
+
priority
|
|
668
|
+
)
|
|
871
669
|
);
|
|
872
670
|
}
|
|
873
671
|
|
|
@@ -883,33 +681,13 @@ namespace DxMessaging.Core
|
|
|
883
681
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
884
682
|
}
|
|
885
683
|
return InternalRegister(
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
messageBus: _messageBus
|
|
894
|
-
);
|
|
895
|
-
|
|
896
|
-
void AugmentedHandler(T message)
|
|
897
|
-
{
|
|
898
|
-
broadcastHandler(message);
|
|
899
|
-
if (_diagnosticMode)
|
|
900
|
-
{
|
|
901
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
902
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
},
|
|
906
|
-
() =>
|
|
907
|
-
new MessageRegistrationMetadata(
|
|
908
|
-
source,
|
|
909
|
-
typeof(T),
|
|
910
|
-
MessageRegistrationType.Broadcast,
|
|
911
|
-
priority
|
|
912
|
-
)
|
|
684
|
+
new BroadcastRegistration<T>(
|
|
685
|
+
this,
|
|
686
|
+
RegistrationKind.BroadcastHandlerAction,
|
|
687
|
+
source,
|
|
688
|
+
broadcastHandler,
|
|
689
|
+
priority
|
|
690
|
+
)
|
|
913
691
|
);
|
|
914
692
|
}
|
|
915
693
|
|
|
@@ -925,33 +703,13 @@ namespace DxMessaging.Core
|
|
|
925
703
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
926
704
|
}
|
|
927
705
|
return InternalRegister(
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
messageBus: _messageBus
|
|
936
|
-
);
|
|
937
|
-
|
|
938
|
-
void AugmentedHandler(ref T message)
|
|
939
|
-
{
|
|
940
|
-
broadcastHandler(ref message);
|
|
941
|
-
if (_diagnosticMode)
|
|
942
|
-
{
|
|
943
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
944
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
},
|
|
948
|
-
() =>
|
|
949
|
-
new MessageRegistrationMetadata(
|
|
950
|
-
source,
|
|
951
|
-
typeof(T),
|
|
952
|
-
MessageRegistrationType.Broadcast,
|
|
953
|
-
priority
|
|
954
|
-
)
|
|
706
|
+
new BroadcastRegistration<T>(
|
|
707
|
+
this,
|
|
708
|
+
RegistrationKind.BroadcastHandlerFast,
|
|
709
|
+
source,
|
|
710
|
+
broadcastHandler,
|
|
711
|
+
priority
|
|
712
|
+
)
|
|
955
713
|
);
|
|
956
714
|
}
|
|
957
715
|
|
|
@@ -968,33 +726,13 @@ namespace DxMessaging.Core
|
|
|
968
726
|
}
|
|
969
727
|
|
|
970
728
|
return InternalRegister(
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
_messageBus
|
|
979
|
-
);
|
|
980
|
-
|
|
981
|
-
void AugmentedHandler(T message)
|
|
982
|
-
{
|
|
983
|
-
broadcastPostProcessor(message);
|
|
984
|
-
if (_diagnosticMode)
|
|
985
|
-
{
|
|
986
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
987
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
},
|
|
991
|
-
() =>
|
|
992
|
-
new MessageRegistrationMetadata(
|
|
993
|
-
source,
|
|
994
|
-
typeof(T),
|
|
995
|
-
MessageRegistrationType.BroadcastPostProcessor,
|
|
996
|
-
priority
|
|
997
|
-
)
|
|
729
|
+
new BroadcastRegistration<T>(
|
|
730
|
+
this,
|
|
731
|
+
RegistrationKind.BroadcastPostProcessorAction,
|
|
732
|
+
source,
|
|
733
|
+
broadcastPostProcessor,
|
|
734
|
+
priority
|
|
735
|
+
)
|
|
998
736
|
);
|
|
999
737
|
}
|
|
1000
738
|
|
|
@@ -1010,33 +748,13 @@ namespace DxMessaging.Core
|
|
|
1010
748
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1011
749
|
}
|
|
1012
750
|
return InternalRegister(
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
_messageBus
|
|
1021
|
-
);
|
|
1022
|
-
|
|
1023
|
-
void AugmentedHandler(ref T message)
|
|
1024
|
-
{
|
|
1025
|
-
broadcastPostProcessor(ref message);
|
|
1026
|
-
if (_diagnosticMode)
|
|
1027
|
-
{
|
|
1028
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1029
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
},
|
|
1033
|
-
() =>
|
|
1034
|
-
new MessageRegistrationMetadata(
|
|
1035
|
-
source,
|
|
1036
|
-
typeof(T),
|
|
1037
|
-
MessageRegistrationType.BroadcastPostProcessor,
|
|
1038
|
-
priority
|
|
1039
|
-
)
|
|
751
|
+
new BroadcastRegistration<T>(
|
|
752
|
+
this,
|
|
753
|
+
RegistrationKind.BroadcastPostProcessorFast,
|
|
754
|
+
source,
|
|
755
|
+
broadcastPostProcessor,
|
|
756
|
+
priority
|
|
757
|
+
)
|
|
1040
758
|
);
|
|
1041
759
|
}
|
|
1042
760
|
|
|
@@ -1181,33 +899,13 @@ namespace DxMessaging.Core
|
|
|
1181
899
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1182
900
|
}
|
|
1183
901
|
return InternalRegister(
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
_messageBus
|
|
1192
|
-
);
|
|
1193
|
-
|
|
1194
|
-
void AugmentedHandler(T message)
|
|
1195
|
-
{
|
|
1196
|
-
broadcastPostProcessor(message);
|
|
1197
|
-
if (_diagnosticMode)
|
|
1198
|
-
{
|
|
1199
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1200
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
},
|
|
1204
|
-
() =>
|
|
1205
|
-
new MessageRegistrationMetadata(
|
|
1206
|
-
source,
|
|
1207
|
-
typeof(T),
|
|
1208
|
-
MessageRegistrationType.BroadcastPostProcessor,
|
|
1209
|
-
priority
|
|
1210
|
-
)
|
|
902
|
+
new BroadcastRegistration<T>(
|
|
903
|
+
this,
|
|
904
|
+
RegistrationKind.BroadcastPostProcessorAction,
|
|
905
|
+
source,
|
|
906
|
+
broadcastPostProcessor,
|
|
907
|
+
priority
|
|
908
|
+
)
|
|
1211
909
|
);
|
|
1212
910
|
}
|
|
1213
911
|
|
|
@@ -1231,33 +929,13 @@ namespace DxMessaging.Core
|
|
|
1231
929
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1232
930
|
}
|
|
1233
931
|
return InternalRegister(
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
_messageBus
|
|
1242
|
-
);
|
|
1243
|
-
|
|
1244
|
-
void AugmentedHandler(ref T message)
|
|
1245
|
-
{
|
|
1246
|
-
broadcastPostProcessor(ref message);
|
|
1247
|
-
if (_diagnosticMode)
|
|
1248
|
-
{
|
|
1249
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1250
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
},
|
|
1254
|
-
() =>
|
|
1255
|
-
new MessageRegistrationMetadata(
|
|
1256
|
-
source,
|
|
1257
|
-
typeof(T),
|
|
1258
|
-
MessageRegistrationType.BroadcastPostProcessor,
|
|
1259
|
-
priority
|
|
1260
|
-
)
|
|
932
|
+
new BroadcastRegistration<T>(
|
|
933
|
+
this,
|
|
934
|
+
RegistrationKind.BroadcastPostProcessorFast,
|
|
935
|
+
source,
|
|
936
|
+
broadcastPostProcessor,
|
|
937
|
+
priority
|
|
938
|
+
)
|
|
1261
939
|
);
|
|
1262
940
|
}
|
|
1263
941
|
#endif
|
|
@@ -1373,32 +1051,13 @@ namespace DxMessaging.Core
|
|
|
1373
1051
|
}
|
|
1374
1052
|
|
|
1375
1053
|
return InternalRegister(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
);
|
|
1384
|
-
|
|
1385
|
-
void AugmentedHandler(InstanceId source, T message)
|
|
1386
|
-
{
|
|
1387
|
-
broadcastHandler(source, message);
|
|
1388
|
-
if (_diagnosticMode)
|
|
1389
|
-
{
|
|
1390
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1391
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
},
|
|
1395
|
-
() =>
|
|
1396
|
-
new MessageRegistrationMetadata(
|
|
1397
|
-
null,
|
|
1398
|
-
typeof(T),
|
|
1399
|
-
MessageRegistrationType.BroadcastWithoutSource,
|
|
1400
|
-
priority
|
|
1401
|
-
)
|
|
1054
|
+
new BroadcastRegistration<T>(
|
|
1055
|
+
this,
|
|
1056
|
+
RegistrationKind.BroadcastWithoutSourceAction,
|
|
1057
|
+
default,
|
|
1058
|
+
broadcastHandler,
|
|
1059
|
+
priority
|
|
1060
|
+
)
|
|
1402
1061
|
);
|
|
1403
1062
|
}
|
|
1404
1063
|
|
|
@@ -1424,32 +1083,13 @@ namespace DxMessaging.Core
|
|
|
1424
1083
|
}
|
|
1425
1084
|
|
|
1426
1085
|
return InternalRegister(
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
);
|
|
1435
|
-
|
|
1436
|
-
void AugmentedHandler(ref InstanceId source, ref T message)
|
|
1437
|
-
{
|
|
1438
|
-
broadcastHandler(ref source, ref message);
|
|
1439
|
-
if (_diagnosticMode)
|
|
1440
|
-
{
|
|
1441
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1442
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
},
|
|
1446
|
-
() =>
|
|
1447
|
-
new MessageRegistrationMetadata(
|
|
1448
|
-
null,
|
|
1449
|
-
typeof(T),
|
|
1450
|
-
MessageRegistrationType.BroadcastWithoutSource,
|
|
1451
|
-
priority
|
|
1452
|
-
)
|
|
1086
|
+
new BroadcastRegistration<T>(
|
|
1087
|
+
this,
|
|
1088
|
+
RegistrationKind.BroadcastWithoutSourceFast,
|
|
1089
|
+
default,
|
|
1090
|
+
broadcastHandler,
|
|
1091
|
+
priority
|
|
1092
|
+
)
|
|
1453
1093
|
);
|
|
1454
1094
|
}
|
|
1455
1095
|
|
|
@@ -1480,32 +1120,13 @@ namespace DxMessaging.Core
|
|
|
1480
1120
|
}
|
|
1481
1121
|
|
|
1482
1122
|
return InternalRegister(
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
);
|
|
1491
|
-
|
|
1492
|
-
void AugmentedHandler(InstanceId source, T message)
|
|
1493
|
-
{
|
|
1494
|
-
broadcastHandler(source, message);
|
|
1495
|
-
if (_diagnosticMode)
|
|
1496
|
-
{
|
|
1497
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1498
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
},
|
|
1502
|
-
() =>
|
|
1503
|
-
new MessageRegistrationMetadata(
|
|
1504
|
-
null,
|
|
1505
|
-
typeof(T),
|
|
1506
|
-
MessageRegistrationType.BroadcastWithoutSourcePostProcessor,
|
|
1507
|
-
priority
|
|
1508
|
-
)
|
|
1123
|
+
new BroadcastRegistration<T>(
|
|
1124
|
+
this,
|
|
1125
|
+
RegistrationKind.BroadcastWithoutSourcePostProcessorAction,
|
|
1126
|
+
default,
|
|
1127
|
+
broadcastHandler,
|
|
1128
|
+
priority
|
|
1129
|
+
)
|
|
1509
1130
|
);
|
|
1510
1131
|
}
|
|
1511
1132
|
|
|
@@ -1531,32 +1152,13 @@ namespace DxMessaging.Core
|
|
|
1531
1152
|
}
|
|
1532
1153
|
|
|
1533
1154
|
return InternalRegister(
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
);
|
|
1542
|
-
|
|
1543
|
-
void AugmentedHandler(ref InstanceId source, ref T message)
|
|
1544
|
-
{
|
|
1545
|
-
broadcastHandler(ref source, ref message);
|
|
1546
|
-
if (_diagnosticMode)
|
|
1547
|
-
{
|
|
1548
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1549
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
},
|
|
1553
|
-
() =>
|
|
1554
|
-
new MessageRegistrationMetadata(
|
|
1555
|
-
null,
|
|
1556
|
-
typeof(T),
|
|
1557
|
-
MessageRegistrationType.BroadcastWithoutSourcePostProcessor,
|
|
1558
|
-
priority
|
|
1559
|
-
)
|
|
1155
|
+
new BroadcastRegistration<T>(
|
|
1156
|
+
this,
|
|
1157
|
+
RegistrationKind.BroadcastWithoutSourcePostProcessorFast,
|
|
1158
|
+
default,
|
|
1159
|
+
broadcastHandler,
|
|
1160
|
+
priority
|
|
1161
|
+
)
|
|
1560
1162
|
);
|
|
1561
1163
|
}
|
|
1562
1164
|
|
|
@@ -1581,55 +1183,12 @@ namespace DxMessaging.Core
|
|
|
1581
1183
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1582
1184
|
}
|
|
1583
1185
|
return InternalRegister(
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
AugmentedTargeted,
|
|
1591
|
-
acceptAllBroadcast,
|
|
1592
|
-
AugmentedBroadcast,
|
|
1593
|
-
_messageBus
|
|
1594
|
-
);
|
|
1595
|
-
|
|
1596
|
-
void AugmentedUntargeted(IUntargetedMessage message)
|
|
1597
|
-
{
|
|
1598
|
-
acceptAllUntargeted(message);
|
|
1599
|
-
if (_diagnosticMode)
|
|
1600
|
-
{
|
|
1601
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1602
|
-
_emissionBuffer.Add(new MessageEmissionData(message));
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
void AugmentedTargeted(InstanceId target, ITargetedMessage message)
|
|
1607
|
-
{
|
|
1608
|
-
acceptAllTargeted(target, message);
|
|
1609
|
-
if (_diagnosticMode)
|
|
1610
|
-
{
|
|
1611
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1612
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
void AugmentedBroadcast(InstanceId source, IBroadcastMessage message)
|
|
1617
|
-
{
|
|
1618
|
-
acceptAllBroadcast(source, message);
|
|
1619
|
-
if (_diagnosticMode)
|
|
1620
|
-
{
|
|
1621
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1622
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
},
|
|
1626
|
-
() =>
|
|
1627
|
-
new MessageRegistrationMetadata(
|
|
1628
|
-
null,
|
|
1629
|
-
typeof(IMessage),
|
|
1630
|
-
MessageRegistrationType.GlobalAcceptAll,
|
|
1631
|
-
0
|
|
1632
|
-
)
|
|
1186
|
+
new GlobalAcceptAllRegistration(
|
|
1187
|
+
this,
|
|
1188
|
+
acceptAllUntargeted,
|
|
1189
|
+
acceptAllTargeted,
|
|
1190
|
+
acceptAllBroadcast
|
|
1191
|
+
)
|
|
1633
1192
|
);
|
|
1634
1193
|
}
|
|
1635
1194
|
|
|
@@ -1663,55 +1222,12 @@ namespace DxMessaging.Core
|
|
|
1663
1222
|
return MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1664
1223
|
}
|
|
1665
1224
|
return InternalRegister(
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
AugmentedTargeted,
|
|
1673
|
-
acceptAllBroadcast,
|
|
1674
|
-
AugmentedBroadcast,
|
|
1675
|
-
_messageBus
|
|
1676
|
-
);
|
|
1677
|
-
|
|
1678
|
-
void AugmentedUntargeted(ref IUntargetedMessage message)
|
|
1679
|
-
{
|
|
1680
|
-
acceptAllUntargeted(ref message);
|
|
1681
|
-
if (_diagnosticMode)
|
|
1682
|
-
{
|
|
1683
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1684
|
-
_emissionBuffer.Add(new MessageEmissionData(message));
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
void AugmentedTargeted(ref InstanceId target, ref ITargetedMessage message)
|
|
1689
|
-
{
|
|
1690
|
-
acceptAllTargeted(ref target, ref message);
|
|
1691
|
-
if (_diagnosticMode)
|
|
1692
|
-
{
|
|
1693
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1694
|
-
_emissionBuffer.Add(new MessageEmissionData(message, target));
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
|
|
1698
|
-
void AugmentedBroadcast(ref InstanceId source, ref IBroadcastMessage message)
|
|
1699
|
-
{
|
|
1700
|
-
acceptAllBroadcast(ref source, ref message);
|
|
1701
|
-
if (_diagnosticMode)
|
|
1702
|
-
{
|
|
1703
|
-
_callCounts[handle] = _callCounts.GetValueOrDefault(handle) + 1;
|
|
1704
|
-
_emissionBuffer.Add(new MessageEmissionData(message, source));
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
},
|
|
1708
|
-
() =>
|
|
1709
|
-
new MessageRegistrationMetadata(
|
|
1710
|
-
null,
|
|
1711
|
-
typeof(IMessage),
|
|
1712
|
-
MessageRegistrationType.GlobalAcceptAll,
|
|
1713
|
-
0
|
|
1714
|
-
)
|
|
1225
|
+
new GlobalAcceptAllRegistration(
|
|
1226
|
+
this,
|
|
1227
|
+
acceptAllUntargeted,
|
|
1228
|
+
acceptAllTargeted,
|
|
1229
|
+
acceptAllBroadcast
|
|
1230
|
+
)
|
|
1715
1231
|
);
|
|
1716
1232
|
}
|
|
1717
1233
|
|
|
@@ -1734,19 +1250,7 @@ namespace DxMessaging.Core
|
|
|
1734
1250
|
}
|
|
1735
1251
|
|
|
1736
1252
|
return InternalRegister(
|
|
1737
|
-
|
|
1738
|
-
_messageHandler.RegisterUntargetedInterceptor(
|
|
1739
|
-
interceptor,
|
|
1740
|
-
priority: priority,
|
|
1741
|
-
messageBus: _messageBus
|
|
1742
|
-
),
|
|
1743
|
-
() =>
|
|
1744
|
-
new MessageRegistrationMetadata(
|
|
1745
|
-
null,
|
|
1746
|
-
typeof(T),
|
|
1747
|
-
MessageRegistrationType.UntargetedInterceptor,
|
|
1748
|
-
priority
|
|
1749
|
-
)
|
|
1253
|
+
new UntargetedInterceptorRegistration<T>(this, interceptor, priority)
|
|
1750
1254
|
);
|
|
1751
1255
|
}
|
|
1752
1256
|
|
|
@@ -1769,19 +1273,7 @@ namespace DxMessaging.Core
|
|
|
1769
1273
|
}
|
|
1770
1274
|
|
|
1771
1275
|
return InternalRegister(
|
|
1772
|
-
|
|
1773
|
-
_messageHandler.RegisterBroadcastInterceptor(
|
|
1774
|
-
interceptor,
|
|
1775
|
-
priority: priority,
|
|
1776
|
-
messageBus: _messageBus
|
|
1777
|
-
),
|
|
1778
|
-
() =>
|
|
1779
|
-
new MessageRegistrationMetadata(
|
|
1780
|
-
null,
|
|
1781
|
-
typeof(T),
|
|
1782
|
-
MessageRegistrationType.BroadcastInterceptor,
|
|
1783
|
-
priority
|
|
1784
|
-
)
|
|
1276
|
+
new BroadcastInterceptorRegistration<T>(this, interceptor, priority)
|
|
1785
1277
|
);
|
|
1786
1278
|
}
|
|
1787
1279
|
|
|
@@ -1804,54 +1296,49 @@ namespace DxMessaging.Core
|
|
|
1804
1296
|
}
|
|
1805
1297
|
|
|
1806
1298
|
return InternalRegister(
|
|
1807
|
-
|
|
1808
|
-
_messageHandler.RegisterTargetedInterceptor(
|
|
1809
|
-
interceptor,
|
|
1810
|
-
priority: priority,
|
|
1811
|
-
messageBus: _messageBus
|
|
1812
|
-
),
|
|
1813
|
-
() =>
|
|
1814
|
-
new MessageRegistrationMetadata(
|
|
1815
|
-
null,
|
|
1816
|
-
typeof(T),
|
|
1817
|
-
MessageRegistrationType.TargetedInterceptor,
|
|
1818
|
-
priority
|
|
1819
|
-
)
|
|
1299
|
+
new TargetedInterceptorRegistration<T>(this, interceptor, priority)
|
|
1820
1300
|
);
|
|
1821
1301
|
}
|
|
1822
1302
|
|
|
1823
1303
|
/// <summary>
|
|
1824
1304
|
/// Handles the actual [de]registration wrapping and (potential) lazy execution.
|
|
1825
1305
|
/// </summary>
|
|
1826
|
-
/// <param name="
|
|
1827
|
-
/// <param name="metadataProducer">Opaque metadata producer function.</param>
|
|
1306
|
+
/// <param name="registration">The unified per-handle registration object the public Register* method built. Calling <see cref="Registration.Register"/> (re)registers the handler on the bus and returns the matching de-registration.</param>
|
|
1828
1307
|
/// <returns>A handle that allows for registration and de-registration.</returns>
|
|
1829
|
-
private MessageRegistrationHandle InternalRegister(
|
|
1830
|
-
Func<MessageRegistrationHandle, Action> registerAndGetDeregistration,
|
|
1831
|
-
Func<MessageRegistrationMetadata> metadataProducer
|
|
1832
|
-
)
|
|
1308
|
+
private MessageRegistrationHandle InternalRegister(Registration registration)
|
|
1833
1309
|
{
|
|
1310
|
+
int slotIndex = AllocateSlot();
|
|
1834
1311
|
MessageRegistrationHandle handle =
|
|
1835
|
-
MessageRegistrationHandle.CreateMessageRegistrationHandle();
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1312
|
+
MessageRegistrationHandle.CreateMessageRegistrationHandle(slotIndex);
|
|
1313
|
+
registration.Handle = handle;
|
|
1314
|
+
ref RegistrationSlot slot = ref _slots[slotIndex];
|
|
1315
|
+
slot.Id = handle.Id;
|
|
1316
|
+
slot.Registration = registration;
|
|
1317
|
+
slot.Previous = _registrationTail;
|
|
1318
|
+
slot.Next = -1;
|
|
1319
|
+
slot.NextFree = -1;
|
|
1320
|
+
if (_registrationTail >= 0)
|
|
1321
|
+
{
|
|
1322
|
+
_slots[_registrationTail].Next = slotIndex;
|
|
1323
|
+
}
|
|
1324
|
+
else
|
|
1325
|
+
{
|
|
1326
|
+
_registrationHead = slotIndex;
|
|
1327
|
+
}
|
|
1328
|
+
_registrationTail = slotIndex;
|
|
1329
|
+
++_registrationCount;
|
|
1330
|
+
// Generally, registrations should take place before all calls to enable.
|
|
1331
|
+
// Just in case, though, register immediately if already enabled. We do not
|
|
1332
|
+
// register at staging time when disabled (the owner might not be awake), so
|
|
1333
|
+
// the Registration object is retained in _registrations to lazily
|
|
1334
|
+
// (re)register on Enable().
|
|
1842
1335
|
if (_enabled)
|
|
1843
1336
|
{
|
|
1844
|
-
|
|
1337
|
+
MessageHandler.HandlerDeregistration actualDeregistration = registration.Register();
|
|
1338
|
+
AddDeregistration(slotIndex, handle.Id, actualDeregistration);
|
|
1845
1339
|
}
|
|
1846
1340
|
|
|
1847
1341
|
return handle;
|
|
1848
|
-
|
|
1849
|
-
// We don't want to actually register at this time (might not be awake/enabled) - so we wrap that shit up, to lazy register when we're enabled.
|
|
1850
|
-
void Registration()
|
|
1851
|
-
{
|
|
1852
|
-
Action actualDeregistration = registerAndGetDeregistration(handle);
|
|
1853
|
-
AddDeregistration(handle, actualDeregistration);
|
|
1854
|
-
}
|
|
1855
1342
|
}
|
|
1856
1343
|
|
|
1857
1344
|
/// <summary>
|
|
@@ -1873,14 +1360,14 @@ namespace DxMessaging.Core
|
|
|
1873
1360
|
return;
|
|
1874
1361
|
}
|
|
1875
1362
|
|
|
1876
|
-
if (
|
|
1363
|
+
if (_registrationCount > 0)
|
|
1877
1364
|
{
|
|
1878
1365
|
// Replay staged registrations in original registration order
|
|
1879
1366
|
// (via _registrationOrder) rather than in
|
|
1880
1367
|
// _registrations.Values enumeration order, which permutes
|
|
1881
1368
|
// after Remove/Add churn. This preserves the documented
|
|
1882
1369
|
// equal-priority "registration order" dispatch contract across
|
|
1883
|
-
// Disable()/Enable() cycles. Snapshot into
|
|
1370
|
+
// Disable()/Enable() cycles. Snapshot into _registrationReplayQueue first
|
|
1884
1371
|
// so replay tolerates re-entrant registration mutation.
|
|
1885
1372
|
QueueRegistrationsInOrder();
|
|
1886
1373
|
InvokeRegistrationQueueWithRollback();
|
|
@@ -1902,13 +1389,13 @@ namespace DxMessaging.Core
|
|
|
1902
1389
|
/// </example>
|
|
1903
1390
|
public void Disable()
|
|
1904
1391
|
{
|
|
1905
|
-
if (!_enabled &&
|
|
1392
|
+
if (!_enabled && _deregistrationCount == 0)
|
|
1906
1393
|
{
|
|
1907
1394
|
return;
|
|
1908
1395
|
}
|
|
1909
1396
|
|
|
1910
1397
|
Exception deregistrationException = InvokeDeregistrationQueue();
|
|
1911
|
-
_enabled =
|
|
1398
|
+
_enabled = _deregistrationCount > 0;
|
|
1912
1399
|
if (deregistrationException != null)
|
|
1913
1400
|
{
|
|
1914
1401
|
ExceptionDispatchInfo.Capture(deregistrationException).Throw();
|
|
@@ -1931,13 +1418,12 @@ namespace DxMessaging.Core
|
|
|
1931
1418
|
if (deregistrationException == null)
|
|
1932
1419
|
{
|
|
1933
1420
|
_enabled = false;
|
|
1934
|
-
|
|
1935
|
-
_registrationOrder?.Clear();
|
|
1421
|
+
ClearRegistrationArena();
|
|
1936
1422
|
ClearDiagnosticState();
|
|
1937
1423
|
return;
|
|
1938
1424
|
}
|
|
1939
1425
|
|
|
1940
|
-
_enabled =
|
|
1426
|
+
_enabled = _deregistrationCount > 0;
|
|
1941
1427
|
PruneRegistrationStateToFailedDeregistrations();
|
|
1942
1428
|
ExceptionDispatchInfo.Capture(deregistrationException).Throw();
|
|
1943
1429
|
}
|
|
@@ -1960,16 +1446,21 @@ namespace DxMessaging.Core
|
|
|
1960
1446
|
bool rebindActiveRegistrations =
|
|
1961
1447
|
effectiveMode == MessageBusRebindMode.RebindActive
|
|
1962
1448
|
&& _enabled
|
|
1963
|
-
&&
|
|
1449
|
+
&& _deregistrationCount > 0;
|
|
1964
1450
|
if (sameBus && !rebindActiveRegistrations)
|
|
1965
1451
|
{
|
|
1966
1452
|
return;
|
|
1967
1453
|
}
|
|
1968
1454
|
|
|
1969
1455
|
IMessageBus previousMessageBus = _messageBus;
|
|
1970
|
-
List<MessageRegistrationHandle> activeRetargetHandles =
|
|
1971
|
-
|
|
1972
|
-
|
|
1456
|
+
List<MessageRegistrationHandle> activeRetargetHandles = null;
|
|
1457
|
+
if (rebindActiveRegistrations)
|
|
1458
|
+
{
|
|
1459
|
+
activeRetargetHandles = _activeRetargetHandles ??=
|
|
1460
|
+
new List<MessageRegistrationHandle>();
|
|
1461
|
+
activeRetargetHandles.Clear();
|
|
1462
|
+
QueueActiveHandles(activeRetargetHandles);
|
|
1463
|
+
}
|
|
1973
1464
|
if (rebindActiveRegistrations)
|
|
1974
1465
|
{
|
|
1975
1466
|
Exception deregistrationException = InvokeDeregistrationQueue();
|
|
@@ -1979,7 +1470,7 @@ namespace DxMessaging.Core
|
|
|
1979
1470
|
previousMessageBus,
|
|
1980
1471
|
activeRetargetHandles
|
|
1981
1472
|
);
|
|
1982
|
-
_enabled =
|
|
1473
|
+
_enabled = _deregistrationCount > 0;
|
|
1983
1474
|
ExceptionDispatchInfo.Capture(deregistrationException).Throw();
|
|
1984
1475
|
}
|
|
1985
1476
|
|
|
@@ -1988,7 +1479,7 @@ namespace DxMessaging.Core
|
|
|
1988
1479
|
|
|
1989
1480
|
_messageBus = messageBus;
|
|
1990
1481
|
|
|
1991
|
-
if (rebindActiveRegistrations &&
|
|
1482
|
+
if (rebindActiveRegistrations && _registrationCount > 0)
|
|
1992
1483
|
{
|
|
1993
1484
|
// Mirror Enable(): rebind in original registration order so the
|
|
1994
1485
|
// equal-priority dispatch order survives a bus retarget.
|
|
@@ -2007,28 +1498,145 @@ namespace DxMessaging.Core
|
|
|
2007
1498
|
}
|
|
2008
1499
|
}
|
|
2009
1500
|
|
|
2010
|
-
private void AddDeregistration(
|
|
1501
|
+
private void AddDeregistration(
|
|
1502
|
+
int slotIndex,
|
|
1503
|
+
long id,
|
|
1504
|
+
MessageHandler.HandlerDeregistration deregistration
|
|
1505
|
+
)
|
|
1506
|
+
{
|
|
1507
|
+
if (!TryGetSlot(slotIndex, id, out RegistrationSlot slot))
|
|
1508
|
+
{
|
|
1509
|
+
// The staged registration was removed or its slot was reused while its replay
|
|
1510
|
+
// snapshot was executing. Preserve the returned teardown under the original
|
|
1511
|
+
// identity: consuming it here would lose a throwing teardown instead of keeping it
|
|
1512
|
+
// retryable, while attaching it to the slot would target the new occupant.
|
|
1513
|
+
AddOrphanDeregistration(
|
|
1514
|
+
MessageRegistrationHandle.FromIdentity(id, slotIndex),
|
|
1515
|
+
deregistration
|
|
1516
|
+
);
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
object existing = slot.Deregistration;
|
|
1521
|
+
if (existing == null)
|
|
1522
|
+
{
|
|
1523
|
+
_slots[slotIndex].Deregistration = deregistration;
|
|
1524
|
+
++_deregistrationCount;
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
if (existing is PendingDeregistration pending)
|
|
1529
|
+
{
|
|
1530
|
+
pending.Add(deregistration);
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
// A second de-registration accumulated on this handle: promote the inline object to a
|
|
1535
|
+
// PendingDeregistration holder that preserves the ordering / partial-failure / rollback
|
|
1536
|
+
// semantics for the multi-de-registration (retarget-recovery replay) case.
|
|
1537
|
+
PendingDeregistration promoted = new();
|
|
1538
|
+
promoted.Add((MessageHandler.HandlerDeregistration)existing);
|
|
1539
|
+
promoted.Add(deregistration);
|
|
1540
|
+
_slots[slotIndex].Deregistration = promoted;
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
private void AddOrphanDeregistration(
|
|
1544
|
+
MessageRegistrationHandle handle,
|
|
1545
|
+
MessageHandler.HandlerDeregistration deregistration
|
|
1546
|
+
)
|
|
1547
|
+
{
|
|
1548
|
+
Dictionary<MessageRegistrationHandle, object> orphans = _orphanDeregistrations ??=
|
|
1549
|
+
new Dictionary<MessageRegistrationHandle, object>();
|
|
1550
|
+
if (!orphans.TryGetValue(handle, out object existing))
|
|
1551
|
+
{
|
|
1552
|
+
orphans.Add(handle, deregistration);
|
|
1553
|
+
++_deregistrationCount;
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
if (existing is PendingDeregistration pending)
|
|
1558
|
+
{
|
|
1559
|
+
pending.Add(deregistration);
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
PendingDeregistration promoted = new();
|
|
1564
|
+
promoted.Add((MessageHandler.HandlerDeregistration)existing);
|
|
1565
|
+
promoted.Add(deregistration);
|
|
1566
|
+
orphans[handle] = promoted;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// Logical de-registration count for a _deregistrations value (inline object == 1).
|
|
1570
|
+
private static int DeregistrationCount(object value) =>
|
|
1571
|
+
value is PendingDeregistration pending ? pending.Count : 1;
|
|
1572
|
+
|
|
1573
|
+
// Invokes the de-registration tail [startIndex..) for a _deregistrations value. For the
|
|
1574
|
+
// inline object (logical Count 1, index 0): on success it is consumed (shouldRemove = true);
|
|
1575
|
+
// on throw it is KEPT (retryable, shouldRemove = false); a rollback pass (startIndex > 0)
|
|
1576
|
+
// leaves the baseline entry untouched. For a holder it delegates to InvokeFrom, mutating the
|
|
1577
|
+
// holder in place. Mirrors the prior PendingDeregistration-only semantics exactly.
|
|
1578
|
+
private static Exception InvokeDeregistration(
|
|
1579
|
+
object value,
|
|
1580
|
+
int startIndex,
|
|
1581
|
+
out bool shouldRemove
|
|
1582
|
+
)
|
|
2011
1583
|
{
|
|
2012
|
-
if (
|
|
1584
|
+
if (value is PendingDeregistration pending)
|
|
1585
|
+
{
|
|
1586
|
+
Exception holderException = pending.InvokeFrom(startIndex);
|
|
1587
|
+
shouldRemove = pending.Count == 0;
|
|
1588
|
+
return holderException;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
if (startIndex > 0)
|
|
2013
1592
|
{
|
|
2014
|
-
|
|
2015
|
-
|
|
1593
|
+
// Rollback baseline pass: the inline head (logical index 0) is below the requested
|
|
1594
|
+
// tail, so leave it untouched.
|
|
1595
|
+
shouldRemove = false;
|
|
1596
|
+
return null;
|
|
2016
1597
|
}
|
|
2017
1598
|
|
|
2018
|
-
|
|
1599
|
+
try
|
|
1600
|
+
{
|
|
1601
|
+
((MessageHandler.HandlerDeregistration)value)?.Deregister();
|
|
1602
|
+
shouldRemove = true;
|
|
1603
|
+
return null;
|
|
1604
|
+
}
|
|
1605
|
+
catch (Exception exception)
|
|
1606
|
+
{
|
|
1607
|
+
// Keep the failed de-registration (retryable), exactly as the holder form does.
|
|
1608
|
+
shouldRemove = false;
|
|
1609
|
+
return exception;
|
|
1610
|
+
}
|
|
2019
1611
|
}
|
|
2020
1612
|
|
|
2021
1613
|
private Dictionary<MessageRegistrationHandle, int> SnapshotDeregistrationCounts()
|
|
2022
1614
|
{
|
|
2023
|
-
Dictionary<MessageRegistrationHandle, int> snapshot =
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
1615
|
+
Dictionary<MessageRegistrationHandle, int> snapshot = _rollbackCounts ??=
|
|
1616
|
+
new Dictionary<MessageRegistrationHandle, int>();
|
|
1617
|
+
snapshot.Clear();
|
|
1618
|
+
for (
|
|
1619
|
+
int slotIndex = _registrationHead;
|
|
1620
|
+
slotIndex >= 0;
|
|
1621
|
+
slotIndex = _slots[slotIndex].Next
|
|
2029
1622
|
)
|
|
2030
1623
|
{
|
|
2031
|
-
|
|
1624
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
1625
|
+
if (slot.Deregistration != null)
|
|
1626
|
+
{
|
|
1627
|
+
snapshot[MessageRegistrationHandle.FromIdentity(slot.Id, slotIndex)] =
|
|
1628
|
+
DeregistrationCount(slot.Deregistration);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
if (_orphanDeregistrations != null)
|
|
1633
|
+
{
|
|
1634
|
+
foreach (
|
|
1635
|
+
KeyValuePair<MessageRegistrationHandle, object> entry in _orphanDeregistrations
|
|
1636
|
+
)
|
|
1637
|
+
{
|
|
1638
|
+
snapshot[entry.Key] = DeregistrationCount(entry.Value);
|
|
1639
|
+
}
|
|
2032
1640
|
}
|
|
2033
1641
|
|
|
2034
1642
|
return snapshot;
|
|
@@ -2066,9 +1674,9 @@ namespace DxMessaging.Core
|
|
|
2066
1674
|
private void RestoreRegistrationsAfterRetargetFailure(IMessageBus previousMessageBus)
|
|
2067
1675
|
{
|
|
2068
1676
|
_messageBus = previousMessageBus;
|
|
2069
|
-
if (
|
|
1677
|
+
if (_registrationCount == 0)
|
|
2070
1678
|
{
|
|
2071
|
-
_enabled =
|
|
1679
|
+
_enabled = _deregistrationCount > 0;
|
|
2072
1680
|
return;
|
|
2073
1681
|
}
|
|
2074
1682
|
|
|
@@ -2080,7 +1688,7 @@ namespace DxMessaging.Core
|
|
|
2080
1688
|
}
|
|
2081
1689
|
catch (Exception restoreException)
|
|
2082
1690
|
{
|
|
2083
|
-
_enabled =
|
|
1691
|
+
_enabled = _deregistrationCount > 0;
|
|
2084
1692
|
if (MessagingDebug.enabled)
|
|
2085
1693
|
{
|
|
2086
1694
|
MessagingDebug.Log(
|
|
@@ -2094,14 +1702,16 @@ namespace DxMessaging.Core
|
|
|
2094
1702
|
|
|
2095
1703
|
private void QueueRegistrationsInOrder()
|
|
2096
1704
|
{
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
for (
|
|
1705
|
+
List<StagedRegistration> queue = GetRegistrationReplayQueue();
|
|
1706
|
+
queue.Clear();
|
|
1707
|
+
for (
|
|
1708
|
+
int slotIndex = _registrationHead;
|
|
1709
|
+
slotIndex >= 0;
|
|
1710
|
+
slotIndex = _slots[slotIndex].Next
|
|
1711
|
+
)
|
|
2100
1712
|
{
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
_actionQueue.Add(registration);
|
|
2104
|
-
}
|
|
1713
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
1714
|
+
queue.Add(new StagedRegistration(slotIndex, slot.Id, slot.Registration));
|
|
2105
1715
|
}
|
|
2106
1716
|
}
|
|
2107
1717
|
|
|
@@ -2109,55 +1719,87 @@ namespace DxMessaging.Core
|
|
|
2109
1719
|
List<MessageRegistrationHandle> activeRetargetHandles
|
|
2110
1720
|
)
|
|
2111
1721
|
{
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
for (
|
|
1722
|
+
List<StagedRegistration> queue = GetRegistrationReplayQueue();
|
|
1723
|
+
queue.Clear();
|
|
1724
|
+
for (
|
|
1725
|
+
int slotIndex = _registrationHead;
|
|
1726
|
+
slotIndex >= 0;
|
|
1727
|
+
slotIndex = _slots[slotIndex].Next
|
|
1728
|
+
)
|
|
2115
1729
|
{
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|| _deregistrations.ContainsKey(handle)
|
|
2120
|
-
|| !_registrations.TryGetValue(handle, out Action registration)
|
|
2121
|
-
)
|
|
1730
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
1731
|
+
MessageRegistrationHandle handle = slot.Registration.Handle;
|
|
1732
|
+
if (!activeRetargetHandles.Contains(handle) || slot.Deregistration != null)
|
|
2122
1733
|
{
|
|
2123
1734
|
continue;
|
|
2124
1735
|
}
|
|
2125
1736
|
|
|
2126
|
-
|
|
1737
|
+
queue.Add(new StagedRegistration(slotIndex, slot.Id, slot.Registration));
|
|
2127
1738
|
}
|
|
2128
1739
|
}
|
|
2129
1740
|
|
|
2130
1741
|
private void QueueRegistrationsWithoutRetryableDeregistrationsInOrder()
|
|
2131
1742
|
{
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
for (
|
|
1743
|
+
List<StagedRegistration> queue = GetRegistrationReplayQueue();
|
|
1744
|
+
queue.Clear();
|
|
1745
|
+
for (
|
|
1746
|
+
int slotIndex = _registrationHead;
|
|
1747
|
+
slotIndex >= 0;
|
|
1748
|
+
slotIndex = _slots[slotIndex].Next
|
|
1749
|
+
)
|
|
2135
1750
|
{
|
|
2136
|
-
|
|
2137
|
-
if (
|
|
2138
|
-
_deregistrations.ContainsKey(handle)
|
|
2139
|
-
|| !_registrations.TryGetValue(handle, out Action registration)
|
|
2140
|
-
)
|
|
1751
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
1752
|
+
if (slot.Deregistration != null)
|
|
2141
1753
|
{
|
|
2142
1754
|
continue;
|
|
2143
1755
|
}
|
|
2144
1756
|
|
|
2145
|
-
|
|
1757
|
+
queue.Add(new StagedRegistration(slotIndex, slot.Id, slot.Registration));
|
|
2146
1758
|
}
|
|
2147
1759
|
}
|
|
2148
1760
|
|
|
2149
|
-
private void
|
|
1761
|
+
private void InvokeRegistrationReplayQueue()
|
|
2150
1762
|
{
|
|
2151
1763
|
try
|
|
2152
1764
|
{
|
|
2153
|
-
foreach (
|
|
1765
|
+
foreach (StagedRegistration staged in GetRegistrationReplayQueue())
|
|
2154
1766
|
{
|
|
2155
|
-
|
|
1767
|
+
Registration registration = staged.Registration;
|
|
1768
|
+
if (registration == null)
|
|
1769
|
+
{
|
|
1770
|
+
continue;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
MessageHandler.HandlerDeregistration actualDeregistration =
|
|
1774
|
+
registration.Register();
|
|
1775
|
+
AddDeregistration(staged.Slot, staged.Id, actualDeregistration);
|
|
2156
1776
|
}
|
|
2157
1777
|
}
|
|
2158
1778
|
finally
|
|
2159
1779
|
{
|
|
2160
|
-
|
|
1780
|
+
_registrationReplayQueue?.Clear();
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
/// <summary>
|
|
1785
|
+
/// A staged registration captured for replay: the handle plus the unified
|
|
1786
|
+
/// per-handle <see cref="Registration"/> object that (re)registers the handler
|
|
1787
|
+
/// and returns its <see cref="MessageHandler.HandlerDeregistration"/>.
|
|
1788
|
+
/// Snapshotting the object reference (rather than a per-registration wrapper
|
|
1789
|
+
/// closure) preserves the original re-entrancy semantics while keeping the
|
|
1790
|
+
/// staging state in a single object per registration.
|
|
1791
|
+
/// </summary>
|
|
1792
|
+
private readonly struct StagedRegistration
|
|
1793
|
+
{
|
|
1794
|
+
public readonly int Slot;
|
|
1795
|
+
public readonly long Id;
|
|
1796
|
+
public readonly Registration Registration;
|
|
1797
|
+
|
|
1798
|
+
public StagedRegistration(int slot, long id, Registration registration)
|
|
1799
|
+
{
|
|
1800
|
+
Slot = slot;
|
|
1801
|
+
Id = id;
|
|
1802
|
+
Registration = registration;
|
|
2161
1803
|
}
|
|
2162
1804
|
}
|
|
2163
1805
|
|
|
@@ -2165,22 +1807,76 @@ namespace DxMessaging.Core
|
|
|
2165
1807
|
Dictionary<MessageRegistrationHandle, int> baselineCounts = null
|
|
2166
1808
|
)
|
|
2167
1809
|
{
|
|
2168
|
-
if (
|
|
1810
|
+
if (_deregistrationCount == 0)
|
|
2169
1811
|
{
|
|
2170
1812
|
return null;
|
|
2171
1813
|
}
|
|
2172
1814
|
|
|
2173
1815
|
bool scopedToAddedDeregistrations = baselineCounts != null;
|
|
2174
|
-
|
|
2175
|
-
|
|
1816
|
+
List<TeardownIdentity> teardownQueue = _teardownQueue ??= new List<TeardownIdentity>();
|
|
1817
|
+
teardownQueue.Clear();
|
|
1818
|
+
for (
|
|
1819
|
+
int slotIndex = _registrationHead;
|
|
1820
|
+
slotIndex >= 0;
|
|
1821
|
+
slotIndex = _slots[slotIndex].Next
|
|
1822
|
+
)
|
|
1823
|
+
{
|
|
1824
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
1825
|
+
if (slot.Deregistration != null)
|
|
1826
|
+
{
|
|
1827
|
+
teardownQueue.Add(new TeardownIdentity(slotIndex, slot.Id, isOrphan: false));
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
bool hasOrphanSnapshot =
|
|
1832
|
+
_orphanDeregistrations != null && _orphanDeregistrations.Count > 0;
|
|
1833
|
+
if (hasOrphanSnapshot)
|
|
1834
|
+
{
|
|
1835
|
+
foreach (MessageRegistrationHandle handle in _orphanDeregistrations.Keys)
|
|
1836
|
+
{
|
|
1837
|
+
teardownQueue.Add(new TeardownIdentity(handle.Slot, handle.Id, isOrphan: true));
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
// Global handle ids are monotonic and therefore encode original registration order.
|
|
1842
|
+
// Capture and sort BEFORE invoking anything: reentrant teardown additions are deferred
|
|
1843
|
+
// to the next pass rather than joining this snapshot.
|
|
1844
|
+
if (hasOrphanSnapshot)
|
|
1845
|
+
{
|
|
1846
|
+
teardownQueue.Sort(TeardownIdentityComparer.Instance);
|
|
1847
|
+
}
|
|
2176
1848
|
Exception firstException = null;
|
|
2177
1849
|
try
|
|
2178
1850
|
{
|
|
2179
|
-
foreach (
|
|
1851
|
+
foreach (TeardownIdentity identity in teardownQueue)
|
|
2180
1852
|
{
|
|
2181
|
-
|
|
1853
|
+
MessageRegistrationHandle handle = MessageRegistrationHandle.FromIdentity(
|
|
1854
|
+
identity.Id,
|
|
1855
|
+
identity.Slot
|
|
1856
|
+
);
|
|
1857
|
+
object value;
|
|
1858
|
+
if (identity.IsOrphan)
|
|
2182
1859
|
{
|
|
2183
|
-
|
|
1860
|
+
if (
|
|
1861
|
+
_orphanDeregistrations == null
|
|
1862
|
+
|| !_orphanDeregistrations.TryGetValue(handle, out value)
|
|
1863
|
+
)
|
|
1864
|
+
{
|
|
1865
|
+
continue;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
else
|
|
1869
|
+
{
|
|
1870
|
+
if (!TryGetSlot(identity.Slot, identity.Id, out RegistrationSlot slot))
|
|
1871
|
+
{
|
|
1872
|
+
continue;
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
value = slot.Deregistration;
|
|
1876
|
+
if (value == null)
|
|
1877
|
+
{
|
|
1878
|
+
continue;
|
|
1879
|
+
}
|
|
2184
1880
|
}
|
|
2185
1881
|
|
|
2186
1882
|
int startIndex = 0;
|
|
@@ -2191,27 +1887,42 @@ namespace DxMessaging.Core
|
|
|
2191
1887
|
startIndex = baselineCount;
|
|
2192
1888
|
}
|
|
2193
1889
|
|
|
2194
|
-
if (startIndex >=
|
|
1890
|
+
if (startIndex >= DeregistrationCount(value))
|
|
2195
1891
|
{
|
|
2196
1892
|
continue;
|
|
2197
1893
|
}
|
|
2198
1894
|
}
|
|
2199
1895
|
|
|
2200
|
-
Exception exception =
|
|
1896
|
+
Exception exception = InvokeDeregistration(
|
|
1897
|
+
value,
|
|
1898
|
+
startIndex,
|
|
1899
|
+
out bool shouldRemove
|
|
1900
|
+
);
|
|
2201
1901
|
if (exception != null)
|
|
2202
1902
|
{
|
|
2203
1903
|
firstException ??= exception;
|
|
2204
1904
|
}
|
|
2205
1905
|
|
|
2206
|
-
if (
|
|
1906
|
+
if (shouldRemove)
|
|
2207
1907
|
{
|
|
2208
|
-
|
|
1908
|
+
if (identity.IsOrphan)
|
|
1909
|
+
{
|
|
1910
|
+
_orphanDeregistrations.Remove(handle);
|
|
1911
|
+
--_deregistrationCount;
|
|
1912
|
+
}
|
|
1913
|
+
else if (
|
|
1914
|
+
TryGetSlot(identity.Slot, identity.Id, out RegistrationSlot current)
|
|
1915
|
+
)
|
|
1916
|
+
{
|
|
1917
|
+
_slots[identity.Slot].Deregistration = null;
|
|
1918
|
+
--_deregistrationCount;
|
|
1919
|
+
}
|
|
2209
1920
|
}
|
|
2210
1921
|
}
|
|
2211
1922
|
}
|
|
2212
1923
|
finally
|
|
2213
1924
|
{
|
|
2214
|
-
|
|
1925
|
+
teardownQueue.Clear();
|
|
2215
1926
|
}
|
|
2216
1927
|
|
|
2217
1928
|
return firstException;
|
|
@@ -2223,12 +1934,12 @@ namespace DxMessaging.Core
|
|
|
2223
1934
|
SnapshotDeregistrationCounts();
|
|
2224
1935
|
try
|
|
2225
1936
|
{
|
|
2226
|
-
|
|
1937
|
+
InvokeRegistrationReplayQueue();
|
|
2227
1938
|
}
|
|
2228
1939
|
catch (Exception exception)
|
|
2229
1940
|
{
|
|
2230
1941
|
RollBackDeregistrationsAfterRegistrationFailure(rollbackBaseline);
|
|
2231
|
-
_enabled =
|
|
1942
|
+
_enabled = _deregistrationCount > 0;
|
|
2232
1943
|
ExceptionDispatchInfo.Capture(exception).Throw();
|
|
2233
1944
|
throw;
|
|
2234
1945
|
}
|
|
@@ -2238,7 +1949,7 @@ namespace DxMessaging.Core
|
|
|
2238
1949
|
Dictionary<MessageRegistrationHandle, int> rollbackBaseline
|
|
2239
1950
|
)
|
|
2240
1951
|
{
|
|
2241
|
-
if (
|
|
1952
|
+
if (_deregistrationCount == 0)
|
|
2242
1953
|
{
|
|
2243
1954
|
return;
|
|
2244
1955
|
}
|
|
@@ -2256,26 +1967,28 @@ namespace DxMessaging.Core
|
|
|
2256
1967
|
|
|
2257
1968
|
private void ClearDiagnosticState()
|
|
2258
1969
|
{
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
1970
|
+
// Clear through the backing fields so an inactive (never-materialized)
|
|
1971
|
+
// diagnostics collection is not allocated merely to be emptied.
|
|
1972
|
+
_callCountsBacking?.Clear();
|
|
1973
|
+
_emissionBufferBacking?.Clear();
|
|
2262
1974
|
}
|
|
2263
1975
|
|
|
2264
1976
|
private void PruneRegistrationStateToFailedDeregistrations()
|
|
2265
1977
|
{
|
|
2266
|
-
|
|
1978
|
+
int slotIndex = _registrationTail;
|
|
1979
|
+
while (slotIndex >= 0)
|
|
2267
1980
|
{
|
|
2268
|
-
|
|
2269
|
-
if (
|
|
1981
|
+
int previous = _slots[slotIndex].Previous;
|
|
1982
|
+
if (_slots[slotIndex].Deregistration == null)
|
|
2270
1983
|
{
|
|
2271
|
-
|
|
1984
|
+
RemoveRegistrationState(slotIndex, _slots[slotIndex].Id);
|
|
2272
1985
|
}
|
|
2273
1986
|
|
|
2274
|
-
|
|
1987
|
+
slotIndex = previous;
|
|
2275
1988
|
}
|
|
2276
1989
|
|
|
2277
|
-
|
|
2278
|
-
if (
|
|
1990
|
+
_emissionBufferBacking?.Clear();
|
|
1991
|
+
if (_registrationCount == 0)
|
|
2279
1992
|
{
|
|
2280
1993
|
ClearDiagnosticState();
|
|
2281
1994
|
}
|
|
@@ -2283,16 +1996,51 @@ namespace DxMessaging.Core
|
|
|
2283
1996
|
|
|
2284
1997
|
private bool RemoveRegistrationState(MessageRegistrationHandle handle)
|
|
2285
1998
|
{
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
1999
|
+
return RemoveRegistrationState(handle.Slot, handle.Id);
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
private bool RemoveRegistrationState(int slotIndex, long id)
|
|
2003
|
+
{
|
|
2004
|
+
if (!TryGetSlot(slotIndex, id, out RegistrationSlot slot))
|
|
2005
|
+
{
|
|
2006
|
+
return false;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
if (slot.Previous >= 0)
|
|
2010
|
+
{
|
|
2011
|
+
_slots[slot.Previous].Next = slot.Next;
|
|
2012
|
+
}
|
|
2013
|
+
else
|
|
2014
|
+
{
|
|
2015
|
+
_registrationHead = slot.Next;
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
if (slot.Next >= 0)
|
|
2019
|
+
{
|
|
2020
|
+
_slots[slot.Next].Previous = slot.Previous;
|
|
2021
|
+
}
|
|
2022
|
+
else
|
|
2023
|
+
{
|
|
2024
|
+
_registrationTail = slot.Previous;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
MessageRegistrationHandle handle = MessageRegistrationHandle.FromIdentity(
|
|
2028
|
+
id,
|
|
2029
|
+
slotIndex
|
|
2030
|
+
);
|
|
2031
|
+
_callCountsBacking?.Remove(handle);
|
|
2032
|
+
_slots[slotIndex] = default;
|
|
2033
|
+
_slots[slotIndex].Previous = -1;
|
|
2034
|
+
_slots[slotIndex].Next = -1;
|
|
2035
|
+
_slots[slotIndex].NextFree = _freeSlotHead;
|
|
2036
|
+
_freeSlotHead = slotIndex;
|
|
2037
|
+
--_registrationCount;
|
|
2038
|
+
if (_registrationCount == 0)
|
|
2291
2039
|
{
|
|
2292
2040
|
ClearDiagnosticState();
|
|
2293
2041
|
}
|
|
2294
2042
|
|
|
2295
|
-
return
|
|
2043
|
+
return true;
|
|
2296
2044
|
}
|
|
2297
2045
|
|
|
2298
2046
|
/// <summary>
|
|
@@ -2307,12 +2055,27 @@ namespace DxMessaging.Core
|
|
|
2307
2055
|
/// </example>
|
|
2308
2056
|
public void RemoveRegistration(MessageRegistrationHandle handle)
|
|
2309
2057
|
{
|
|
2310
|
-
if (
|
|
2058
|
+
if (!TryGetSlot(handle.Slot, handle.Id, out RegistrationSlot slot))
|
|
2311
2059
|
{
|
|
2312
|
-
|
|
2313
|
-
|
|
2060
|
+
RemoveOrphanDeregistration(handle);
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
object value = slot.Deregistration;
|
|
2065
|
+
if (value != null)
|
|
2066
|
+
{
|
|
2067
|
+
Exception deregistrationException = InvokeDeregistration(
|
|
2068
|
+
value,
|
|
2069
|
+
0,
|
|
2070
|
+
out bool shouldRemove
|
|
2071
|
+
);
|
|
2072
|
+
if (shouldRemove)
|
|
2314
2073
|
{
|
|
2315
|
-
|
|
2074
|
+
if (TryGetSlot(handle.Slot, handle.Id, out RegistrationSlot current))
|
|
2075
|
+
{
|
|
2076
|
+
_slots[handle.Slot].Deregistration = null;
|
|
2077
|
+
--_deregistrationCount;
|
|
2078
|
+
}
|
|
2316
2079
|
}
|
|
2317
2080
|
|
|
2318
2081
|
if (deregistrationException != null)
|
|
@@ -2327,15 +2090,292 @@ namespace DxMessaging.Core
|
|
|
2327
2090
|
RemoveRegistrationState(handle);
|
|
2328
2091
|
}
|
|
2329
2092
|
|
|
2093
|
+
private void RemoveOrphanDeregistration(MessageRegistrationHandle handle)
|
|
2094
|
+
{
|
|
2095
|
+
if (
|
|
2096
|
+
_orphanDeregistrations == null
|
|
2097
|
+
|| !_orphanDeregistrations.TryGetValue(handle, out object value)
|
|
2098
|
+
)
|
|
2099
|
+
{
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
Exception exception = InvokeDeregistration(value, 0, out bool shouldRemove);
|
|
2104
|
+
if (shouldRemove)
|
|
2105
|
+
{
|
|
2106
|
+
_orphanDeregistrations.Remove(handle);
|
|
2107
|
+
--_deregistrationCount;
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
if (exception != null)
|
|
2111
|
+
{
|
|
2112
|
+
ExceptionDispatchInfo.Capture(exception).Throw();
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
private int AllocateSlot()
|
|
2117
|
+
{
|
|
2118
|
+
if (_freeSlotHead < 0)
|
|
2119
|
+
{
|
|
2120
|
+
int oldLength = _slots.Length;
|
|
2121
|
+
int newLength = oldLength == 0 ? 4 : oldLength << 1;
|
|
2122
|
+
Array.Resize(ref _slots, newLength);
|
|
2123
|
+
for (int i = newLength - 1; i >= oldLength; --i)
|
|
2124
|
+
{
|
|
2125
|
+
_slots[i].Previous = -1;
|
|
2126
|
+
_slots[i].Next = -1;
|
|
2127
|
+
_slots[i].NextFree = _freeSlotHead;
|
|
2128
|
+
_freeSlotHead = i;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
int slotIndex = _freeSlotHead;
|
|
2133
|
+
_freeSlotHead = _slots[slotIndex].NextFree;
|
|
2134
|
+
return slotIndex;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
private bool TryGetSlot(int slotIndex, long id, out RegistrationSlot slot)
|
|
2138
|
+
{
|
|
2139
|
+
if ((uint)slotIndex < (uint)_slots.Length)
|
|
2140
|
+
{
|
|
2141
|
+
slot = _slots[slotIndex];
|
|
2142
|
+
if (slot.Registration != null && slot.Id == id)
|
|
2143
|
+
{
|
|
2144
|
+
return true;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
slot = default;
|
|
2149
|
+
return false;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
private void ClearRegistrationArena()
|
|
2153
|
+
{
|
|
2154
|
+
if (_slots.Length > 0)
|
|
2155
|
+
{
|
|
2156
|
+
Array.Clear(_slots, 0, _slots.Length);
|
|
2157
|
+
_freeSlotHead = -1;
|
|
2158
|
+
for (int i = _slots.Length - 1; i >= 0; --i)
|
|
2159
|
+
{
|
|
2160
|
+
_slots[i].Previous = -1;
|
|
2161
|
+
_slots[i].Next = -1;
|
|
2162
|
+
_slots[i].NextFree = _freeSlotHead;
|
|
2163
|
+
_freeSlotHead = i;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
else
|
|
2167
|
+
{
|
|
2168
|
+
_freeSlotHead = -1;
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
_registrationHead = -1;
|
|
2172
|
+
_registrationTail = -1;
|
|
2173
|
+
_registrationCount = 0;
|
|
2174
|
+
_deregistrationCount = 0;
|
|
2175
|
+
_registrationReplayQueue?.Clear();
|
|
2176
|
+
_teardownQueue?.Clear();
|
|
2177
|
+
_rollbackCounts?.Clear();
|
|
2178
|
+
_activeRetargetHandles?.Clear();
|
|
2179
|
+
_orphanDeregistrations?.Clear();
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
private List<StagedRegistration> GetRegistrationReplayQueue()
|
|
2183
|
+
{
|
|
2184
|
+
return _registrationReplayQueue ??= new List<StagedRegistration>();
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
private void QueueActiveHandles(List<MessageRegistrationHandle> destination)
|
|
2188
|
+
{
|
|
2189
|
+
for (
|
|
2190
|
+
int slotIndex = _registrationHead;
|
|
2191
|
+
slotIndex >= 0;
|
|
2192
|
+
slotIndex = _slots[slotIndex].Next
|
|
2193
|
+
)
|
|
2194
|
+
{
|
|
2195
|
+
RegistrationSlot slot = _slots[slotIndex];
|
|
2196
|
+
if (slot.Deregistration != null)
|
|
2197
|
+
{
|
|
2198
|
+
destination.Add(MessageRegistrationHandle.FromIdentity(slot.Id, slotIndex));
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
if (_orphanDeregistrations != null)
|
|
2203
|
+
{
|
|
2204
|
+
destination.AddRange(_orphanDeregistrations.Keys);
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
private struct RegistrationSlot
|
|
2209
|
+
{
|
|
2210
|
+
public Registration Registration;
|
|
2211
|
+
public object Deregistration;
|
|
2212
|
+
public long Id;
|
|
2213
|
+
public int Previous;
|
|
2214
|
+
public int Next;
|
|
2215
|
+
public int NextFree;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
private readonly struct TeardownIdentity
|
|
2219
|
+
{
|
|
2220
|
+
public readonly int Slot;
|
|
2221
|
+
public readonly long Id;
|
|
2222
|
+
public readonly bool IsOrphan;
|
|
2223
|
+
|
|
2224
|
+
public TeardownIdentity(int slot, long id, bool isOrphan)
|
|
2225
|
+
{
|
|
2226
|
+
Slot = slot;
|
|
2227
|
+
Id = id;
|
|
2228
|
+
IsOrphan = isOrphan;
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
private sealed class TeardownIdentityComparer : IComparer<TeardownIdentity>
|
|
2233
|
+
{
|
|
2234
|
+
internal static readonly TeardownIdentityComparer Instance = new();
|
|
2235
|
+
|
|
2236
|
+
public int Compare(TeardownIdentity left, TeardownIdentity right)
|
|
2237
|
+
{
|
|
2238
|
+
return left.Id.CompareTo(right.Id);
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
internal readonly struct RegistrationMetadataView
|
|
2243
|
+
: IEnumerable<KeyValuePair<MessageRegistrationHandle, MessageRegistrationMetadata>>
|
|
2244
|
+
{
|
|
2245
|
+
private readonly MessageRegistrationToken _token;
|
|
2246
|
+
|
|
2247
|
+
internal RegistrationMetadataView(MessageRegistrationToken token)
|
|
2248
|
+
{
|
|
2249
|
+
_token = token;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
public int Count => _token._registrationCount;
|
|
2253
|
+
|
|
2254
|
+
public bool ContainsKey(MessageRegistrationHandle handle)
|
|
2255
|
+
{
|
|
2256
|
+
return _token.TryGetSlot(handle.Slot, handle.Id, out RegistrationSlot slot);
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
public Enumerator GetEnumerator()
|
|
2260
|
+
{
|
|
2261
|
+
return new Enumerator(_token);
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
IEnumerator<
|
|
2265
|
+
KeyValuePair<MessageRegistrationHandle, MessageRegistrationMetadata>
|
|
2266
|
+
> IEnumerable<
|
|
2267
|
+
KeyValuePair<MessageRegistrationHandle, MessageRegistrationMetadata>
|
|
2268
|
+
>.GetEnumerator()
|
|
2269
|
+
{
|
|
2270
|
+
return GetEnumerator();
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
|
2274
|
+
{
|
|
2275
|
+
return GetEnumerator();
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
internal struct Enumerator
|
|
2279
|
+
: IEnumerator<KeyValuePair<MessageRegistrationHandle, MessageRegistrationMetadata>>
|
|
2280
|
+
{
|
|
2281
|
+
private readonly MessageRegistrationToken _token;
|
|
2282
|
+
private int _next;
|
|
2283
|
+
private KeyValuePair<
|
|
2284
|
+
MessageRegistrationHandle,
|
|
2285
|
+
MessageRegistrationMetadata
|
|
2286
|
+
> _current;
|
|
2287
|
+
|
|
2288
|
+
internal Enumerator(MessageRegistrationToken token)
|
|
2289
|
+
{
|
|
2290
|
+
_token = token;
|
|
2291
|
+
_next = token._registrationHead;
|
|
2292
|
+
_current = default;
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
public KeyValuePair<
|
|
2296
|
+
MessageRegistrationHandle,
|
|
2297
|
+
MessageRegistrationMetadata
|
|
2298
|
+
> Current => _current;
|
|
2299
|
+
|
|
2300
|
+
object System.Collections.IEnumerator.Current => _current;
|
|
2301
|
+
|
|
2302
|
+
public bool MoveNext()
|
|
2303
|
+
{
|
|
2304
|
+
if (_next < 0)
|
|
2305
|
+
{
|
|
2306
|
+
return false;
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
int slotIndex = _next;
|
|
2310
|
+
RegistrationSlot slot = _token._slots[slotIndex];
|
|
2311
|
+
_next = slot.Next;
|
|
2312
|
+
_current = new KeyValuePair<
|
|
2313
|
+
MessageRegistrationHandle,
|
|
2314
|
+
MessageRegistrationMetadata
|
|
2315
|
+
>(
|
|
2316
|
+
MessageRegistrationHandle.FromIdentity(slot.Id, slotIndex),
|
|
2317
|
+
slot.Registration.Metadata
|
|
2318
|
+
);
|
|
2319
|
+
return true;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
public void Reset()
|
|
2323
|
+
{
|
|
2324
|
+
_next = _token._registrationHead;
|
|
2325
|
+
_current = default;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
public void Dispose() { }
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
// Holds the live de-registration Actions for a single handle in the MULTI-de-registration
|
|
2333
|
+
// case (2+). The common case is EXACTLY ONE de-registration per handle (the existing
|
|
2334
|
+
// Registration object executes its embedded teardown state); that Registration is stored
|
|
2335
|
+
// INLINE as the slot value, so the common path allocates no
|
|
2336
|
+
// PendingDeregistration object at all (see AddDeregistration / InvokeDeregistration). This
|
|
2337
|
+
// holder is allocated only when a rare second de-registration accumulates on the same
|
|
2338
|
+
// handle -- a re-entrant retarget-recovery replay can stage one beyond the rollback
|
|
2339
|
+
// baseline -- at which point the inline Registration is promoted into this holder's head
|
|
2340
|
+
// and the second spills to a lazily-allocated overflow list. This stays a class (mutated in
|
|
2341
|
+
// place through the _deregistrations dictionary), so reference semantics and every
|
|
2342
|
+
// call site are unchanged; only the storage shape changed.
|
|
2343
|
+
//
|
|
2344
|
+
// Invariant: when Count > 0 the head lives in _hasHead/_head and is the LOGICAL
|
|
2345
|
+
// FIRST entry; any further entries follow in _overflow in insertion order. Add
|
|
2346
|
+
// appends to the logical tail; InvokeFrom invokes a contiguous logical tail
|
|
2347
|
+
// [startIndex..Count), removing each success and KEEPING each failure (retryable),
|
|
2348
|
+
// then promotes the first surviving overflow entry into the head slot if the head
|
|
2349
|
+
// was consumed -- preserving the exact ordering, partial-failure, and
|
|
2350
|
+
// rollback-baseline (startIndex) semantics the List<Action> form had.
|
|
2330
2351
|
private sealed class PendingDeregistration
|
|
2331
2352
|
{
|
|
2332
|
-
private
|
|
2353
|
+
private MessageHandler.HandlerDeregistration _head;
|
|
2354
|
+
private bool _hasHead;
|
|
2355
|
+
private List<MessageHandler.HandlerDeregistration> _overflow;
|
|
2333
2356
|
|
|
2334
|
-
internal int Count =>
|
|
2357
|
+
internal int Count => (_hasHead ? 1 : 0) + (_overflow?.Count ?? 0);
|
|
2335
2358
|
|
|
2336
|
-
internal void Add(
|
|
2359
|
+
internal void Add(MessageHandler.HandlerDeregistration action)
|
|
2337
2360
|
{
|
|
2338
|
-
|
|
2361
|
+
// Fill the inline head ONLY when nothing is stored. The empty-overflow
|
|
2362
|
+
// clause matters during the transient window inside InvokeFrom where the
|
|
2363
|
+
// head has been consumed but overflow survivors remain (before they are
|
|
2364
|
+
// promoted): a re-entrant Add then appends to the logical TAIL (overflow),
|
|
2365
|
+
// exactly as the List form did, rather than jumping the new entry ahead of
|
|
2366
|
+
// the survivors into the head slot. The overflow loop re-reads its Count,
|
|
2367
|
+
// so such a tail-appended entry is still invoked in the same pass -- the
|
|
2368
|
+
// List form's behavior preserved. (The stored Actions are pure bus
|
|
2369
|
+
// de-registration callbacks, so this re-entrancy is not reachable through
|
|
2370
|
+
// the public API today; the guard keeps the invariant honest regardless.)
|
|
2371
|
+
if (!_hasHead && (_overflow == null || _overflow.Count == 0))
|
|
2372
|
+
{
|
|
2373
|
+
_head = action;
|
|
2374
|
+
_hasHead = true;
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
(_overflow ??= new List<MessageHandler.HandlerDeregistration>()).Add(action);
|
|
2339
2379
|
}
|
|
2340
2380
|
|
|
2341
2381
|
internal Exception InvokeFrom(int startIndex)
|
|
@@ -2346,21 +2386,1018 @@ namespace DxMessaging.Core
|
|
|
2346
2386
|
}
|
|
2347
2387
|
|
|
2348
2388
|
Exception firstException = null;
|
|
2349
|
-
|
|
2389
|
+
|
|
2390
|
+
// Logical index 0 is the inline head; logical indices 1.. are _overflow.
|
|
2391
|
+
// Invoke the head only when it is within the requested tail (a rollback
|
|
2392
|
+
// pass with startIndex > 0 must leave the baseline head untouched).
|
|
2393
|
+
if (_hasHead && startIndex <= 0)
|
|
2350
2394
|
{
|
|
2351
2395
|
try
|
|
2352
2396
|
{
|
|
2353
|
-
|
|
2354
|
-
|
|
2397
|
+
_head?.Deregister();
|
|
2398
|
+
_head = null;
|
|
2399
|
+
_hasHead = false;
|
|
2355
2400
|
}
|
|
2356
2401
|
catch (Exception exception)
|
|
2357
2402
|
{
|
|
2403
|
+
// Keep the failed head (retryable), exactly as the List form did
|
|
2404
|
+
// by advancing past a throwing entry instead of removing it.
|
|
2358
2405
|
firstException ??= exception;
|
|
2359
|
-
++i;
|
|
2360
2406
|
}
|
|
2361
2407
|
}
|
|
2362
2408
|
|
|
2363
|
-
|
|
2409
|
+
if (_overflow is { Count: > 0 })
|
|
2410
|
+
{
|
|
2411
|
+
// Overflow entry j has logical index 1 + j; invoke those at or past
|
|
2412
|
+
// startIndex. Remove successes, keep failures (retryable).
|
|
2413
|
+
int overflowStart = startIndex <= 1 ? 0 : startIndex - 1;
|
|
2414
|
+
for (int j = overflowStart; j < _overflow.Count; )
|
|
2415
|
+
{
|
|
2416
|
+
try
|
|
2417
|
+
{
|
|
2418
|
+
_overflow[j]?.Deregister();
|
|
2419
|
+
_overflow.RemoveAt(j);
|
|
2420
|
+
}
|
|
2421
|
+
catch (Exception exception)
|
|
2422
|
+
{
|
|
2423
|
+
firstException ??= exception;
|
|
2424
|
+
++j;
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
// If the head was consumed but overflow survivors remain, promote the
|
|
2430
|
+
// first survivor into the head slot so the head is always the logical
|
|
2431
|
+
// first entry (keeping Count and future Adds consistent).
|
|
2432
|
+
if (!_hasHead && _overflow is { Count: > 0 })
|
|
2433
|
+
{
|
|
2434
|
+
_head = _overflow[0];
|
|
2435
|
+
_hasHead = true;
|
|
2436
|
+
_overflow.RemoveAt(0);
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
return firstException;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
// Discriminates the per-handle Registration object's behaviour. Each value
|
|
2444
|
+
// pins (a) which MessageHandler.Register* method the kind-switch in
|
|
2445
|
+
// Registration.Register() calls and (b) which augmented-invoker body shape
|
|
2446
|
+
// (user-delegate type + by-value vs by-ref call) the bound FastHandler/
|
|
2447
|
+
// FastHandlerWithContext delegate runs. The values map 1:1 onto the former
|
|
2448
|
+
// per-method staging lambdas; the *Action / *Fast suffix mirrors the two
|
|
2449
|
+
// public overloads (Action<T>/Action<InstanceId,T> vs FastHandler<T>/
|
|
2450
|
+
// FastHandlerWithContext<T>) that previously had distinct AugmentedHandler
|
|
2451
|
+
// local functions.
|
|
2452
|
+
private enum RegistrationKind
|
|
2453
|
+
{
|
|
2454
|
+
TargetedHandlerAction,
|
|
2455
|
+
TargetedHandlerFast,
|
|
2456
|
+
TargetedPostProcessorAction,
|
|
2457
|
+
TargetedPostProcessorFast,
|
|
2458
|
+
TargetedWithoutTargetingAction,
|
|
2459
|
+
TargetedWithoutTargetingFast,
|
|
2460
|
+
TargetedWithoutTargetingPostProcessorAction,
|
|
2461
|
+
TargetedWithoutTargetingPostProcessorFast,
|
|
2462
|
+
TargetedInterceptor,
|
|
2463
|
+
|
|
2464
|
+
UntargetedHandlerAction,
|
|
2465
|
+
UntargetedHandlerFast,
|
|
2466
|
+
UntargetedPostProcessorFast,
|
|
2467
|
+
UntargetedInterceptor,
|
|
2468
|
+
|
|
2469
|
+
BroadcastHandlerAction,
|
|
2470
|
+
BroadcastHandlerFast,
|
|
2471
|
+
BroadcastPostProcessorAction,
|
|
2472
|
+
BroadcastPostProcessorFast,
|
|
2473
|
+
BroadcastWithoutSourceAction,
|
|
2474
|
+
BroadcastWithoutSourceFast,
|
|
2475
|
+
BroadcastWithoutSourcePostProcessorAction,
|
|
2476
|
+
BroadcastWithoutSourcePostProcessorFast,
|
|
2477
|
+
BroadcastInterceptor,
|
|
2478
|
+
|
|
2479
|
+
GlobalAcceptAllAction,
|
|
2480
|
+
GlobalAcceptAllFast,
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
// The unified per-handle staging object. Replaces, per registration, the old
|
|
2484
|
+
// staging Func<handle, HandlerDeregistration> display class + delegate AND the
|
|
2485
|
+
// nested AugmentedHandler local-function delegate. The captured staging state
|
|
2486
|
+
// (owning token, handle, user handler delegate, target/source InstanceId,
|
|
2487
|
+
// priority, kind) lives in plain fields; the diagnostics-augmented invoker is
|
|
2488
|
+
// an instance method bound to this object (so MessageHandler still receives a
|
|
2489
|
+
// delegate on the hot path -- no virtual/interface call per dispatch).
|
|
2490
|
+
//
|
|
2491
|
+
// The base is non-generic so _registrations / the replay queue can hold every
|
|
2492
|
+
// registration polymorphically. The constrained MessageHandler.Register*<T>
|
|
2493
|
+
// calls each require T : ITargetedMessage / IUntargetedMessage /
|
|
2494
|
+
// IBroadcastMessage, which a single Registration<T> (T : IMessage) cannot
|
|
2495
|
+
// satisfy; the three concrete subclasses below carry the matching constraint
|
|
2496
|
+
// and each run a kind-SWITCH over only the kinds in their family (per the
|
|
2497
|
+
// user-accepted "unified object, accept the kind-switch" design -- NOT ~14
|
|
2498
|
+
// subclasses). GlobalAcceptAllRegistration is non-generic (its sub-handlers
|
|
2499
|
+
// are the fixed IMessage facades).
|
|
2500
|
+
private abstract class Registration : MessageHandler.HandlerDeregistration
|
|
2501
|
+
{
|
|
2502
|
+
protected readonly MessageRegistrationToken Token;
|
|
2503
|
+
public MessageRegistrationHandle Handle;
|
|
2504
|
+
private IMessageBus _registeredMessageBus;
|
|
2505
|
+
|
|
2506
|
+
protected Registration(MessageRegistrationToken token)
|
|
2507
|
+
{
|
|
2508
|
+
Token = token;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
// Kind-switch: (re)register on the bus and return the matching
|
|
2512
|
+
// HandlerDeregistration, exactly as the former staging lambda did. Reads
|
|
2513
|
+
// the token's CURRENT _messageBus (so Enable()/RetargetMessageBus replay
|
|
2514
|
+
// binds to the active bus, unchanged from when _messageBus was captured by
|
|
2515
|
+
// the staging closure at call time -- the staging closure also read the
|
|
2516
|
+
// field, not a snapshot).
|
|
2517
|
+
public abstract MessageHandler.HandlerDeregistration Register();
|
|
2518
|
+
|
|
2519
|
+
public abstract MessageRegistrationMetadata Metadata { get; }
|
|
2520
|
+
|
|
2521
|
+
protected static MessageRegistrationType GetRegistrationType(RegistrationKind kind)
|
|
2522
|
+
{
|
|
2523
|
+
switch (kind)
|
|
2524
|
+
{
|
|
2525
|
+
case RegistrationKind.TargetedHandlerAction:
|
|
2526
|
+
case RegistrationKind.TargetedHandlerFast:
|
|
2527
|
+
return MessageRegistrationType.Targeted;
|
|
2528
|
+
case RegistrationKind.TargetedPostProcessorAction:
|
|
2529
|
+
case RegistrationKind.TargetedPostProcessorFast:
|
|
2530
|
+
return MessageRegistrationType.TargetedPostProcessor;
|
|
2531
|
+
case RegistrationKind.TargetedWithoutTargetingAction:
|
|
2532
|
+
case RegistrationKind.TargetedWithoutTargetingFast:
|
|
2533
|
+
return MessageRegistrationType.TargetedWithoutTargeting;
|
|
2534
|
+
case RegistrationKind.TargetedWithoutTargetingPostProcessorAction:
|
|
2535
|
+
case RegistrationKind.TargetedWithoutTargetingPostProcessorFast:
|
|
2536
|
+
return MessageRegistrationType.TargetedWithoutTargetingPostProcessor;
|
|
2537
|
+
case RegistrationKind.TargetedInterceptor:
|
|
2538
|
+
return MessageRegistrationType.TargetedInterceptor;
|
|
2539
|
+
case RegistrationKind.UntargetedHandlerAction:
|
|
2540
|
+
case RegistrationKind.UntargetedHandlerFast:
|
|
2541
|
+
return MessageRegistrationType.Untargeted;
|
|
2542
|
+
case RegistrationKind.UntargetedPostProcessorFast:
|
|
2543
|
+
return MessageRegistrationType.UntargetedPostProcessor;
|
|
2544
|
+
case RegistrationKind.UntargetedInterceptor:
|
|
2545
|
+
return MessageRegistrationType.UntargetedInterceptor;
|
|
2546
|
+
case RegistrationKind.BroadcastHandlerAction:
|
|
2547
|
+
case RegistrationKind.BroadcastHandlerFast:
|
|
2548
|
+
return MessageRegistrationType.Broadcast;
|
|
2549
|
+
case RegistrationKind.BroadcastPostProcessorAction:
|
|
2550
|
+
case RegistrationKind.BroadcastPostProcessorFast:
|
|
2551
|
+
return MessageRegistrationType.BroadcastPostProcessor;
|
|
2552
|
+
case RegistrationKind.BroadcastWithoutSourceAction:
|
|
2553
|
+
case RegistrationKind.BroadcastWithoutSourceFast:
|
|
2554
|
+
return MessageRegistrationType.BroadcastWithoutSource;
|
|
2555
|
+
case RegistrationKind.BroadcastWithoutSourcePostProcessorAction:
|
|
2556
|
+
case RegistrationKind.BroadcastWithoutSourcePostProcessorFast:
|
|
2557
|
+
return MessageRegistrationType.BroadcastWithoutSourcePostProcessor;
|
|
2558
|
+
case RegistrationKind.BroadcastInterceptor:
|
|
2559
|
+
return MessageRegistrationType.BroadcastInterceptor;
|
|
2560
|
+
case RegistrationKind.GlobalAcceptAllAction:
|
|
2561
|
+
case RegistrationKind.GlobalAcceptAllFast:
|
|
2562
|
+
return MessageRegistrationType.GlobalAcceptAll;
|
|
2563
|
+
default:
|
|
2564
|
+
return MessageRegistrationType.None;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2568
|
+
protected IMessageBus ResolveRegistrationMessageBus()
|
|
2569
|
+
{
|
|
2570
|
+
IMessageBus messageBus = Token._messageBus;
|
|
2571
|
+
_registeredMessageBus = messageBus ?? Token._messageHandler?.DefaultMessageBus;
|
|
2572
|
+
return messageBus;
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
protected void RecordDiagnosticEmission(IMessage message, InstanceId? context = null)
|
|
2576
|
+
{
|
|
2577
|
+
Token.RecordDiagnosticEmission(Handle, _registeredMessageBus, message, context);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
private abstract class Registration<T> : Registration
|
|
2582
|
+
where T : IMessage
|
|
2583
|
+
{
|
|
2584
|
+
private MessageHandler.TypedHandler<T>.TypedHandlerDeregistrationState _typedDeregistration;
|
|
2585
|
+
private bool _hasInlineDeregistration;
|
|
2586
|
+
|
|
2587
|
+
protected Registration(MessageRegistrationToken token)
|
|
2588
|
+
: base(token) { }
|
|
2589
|
+
|
|
2590
|
+
protected MessageHandler.HandlerDeregistration StoreDeregistration(
|
|
2591
|
+
MessageHandler.TypedHandler<T>.TypedHandlerDeregistrationState deregistration
|
|
2592
|
+
)
|
|
2593
|
+
{
|
|
2594
|
+
if (_hasInlineDeregistration)
|
|
2595
|
+
{
|
|
2596
|
+
return deregistration;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
_typedDeregistration = deregistration;
|
|
2600
|
+
_hasInlineDeregistration = true;
|
|
2601
|
+
return this;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
internal override void Deregister()
|
|
2605
|
+
{
|
|
2606
|
+
if (!_hasInlineDeregistration)
|
|
2607
|
+
{
|
|
2608
|
+
return;
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
_typedDeregistration.Deregister();
|
|
2612
|
+
|
|
2613
|
+
// Clear only after successful teardown. If a custom bus throws, this
|
|
2614
|
+
// registration remains the retryable inline action and any recovery
|
|
2615
|
+
// registration spills into an independent compatibility wrapper.
|
|
2616
|
+
_hasInlineDeregistration = false;
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2620
|
+
private sealed class TargetedRegistration<T> : Registration<T>
|
|
2621
|
+
where T : ITargetedMessage
|
|
2622
|
+
{
|
|
2623
|
+
private readonly RegistrationKind _kind;
|
|
2624
|
+
private readonly InstanceId _context;
|
|
2625
|
+
private readonly object _userHandler;
|
|
2626
|
+
private readonly int _priority;
|
|
2627
|
+
|
|
2628
|
+
// Strongly-typed views of _userHandler, resolved ONCE at Register() time
|
|
2629
|
+
// (cold) so the per-dispatch augmented invoker calls a typed field directly
|
|
2630
|
+
// -- no per-dispatch castclass or kind-switch (which would add an O(handlers)
|
|
2631
|
+
// cost on the hot dispatch path). Exactly one is set per registration kind.
|
|
2632
|
+
private Action<T> _scalarAction;
|
|
2633
|
+
private MessageHandler.FastHandler<T> _scalarFast;
|
|
2634
|
+
private Action<InstanceId, T> _contextAction;
|
|
2635
|
+
private MessageHandler.FastHandlerWithContext<T> _contextFast;
|
|
2636
|
+
|
|
2637
|
+
internal TargetedRegistration(
|
|
2638
|
+
MessageRegistrationToken token,
|
|
2639
|
+
RegistrationKind kind,
|
|
2640
|
+
InstanceId context,
|
|
2641
|
+
object userHandler,
|
|
2642
|
+
int priority
|
|
2643
|
+
)
|
|
2644
|
+
: base(token)
|
|
2645
|
+
{
|
|
2646
|
+
_kind = kind;
|
|
2647
|
+
_context = context;
|
|
2648
|
+
_userHandler = userHandler;
|
|
2649
|
+
_priority = priority;
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
2653
|
+
new MessageRegistrationMetadata(
|
|
2654
|
+
_kind == RegistrationKind.TargetedHandlerAction
|
|
2655
|
+
|| _kind == RegistrationKind.TargetedHandlerFast
|
|
2656
|
+
|| _kind == RegistrationKind.TargetedPostProcessorAction
|
|
2657
|
+
|| _kind == RegistrationKind.TargetedPostProcessorFast
|
|
2658
|
+
? _context
|
|
2659
|
+
: (InstanceId?)null,
|
|
2660
|
+
typeof(T),
|
|
2661
|
+
GetRegistrationType(_kind),
|
|
2662
|
+
_priority
|
|
2663
|
+
);
|
|
2664
|
+
|
|
2665
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
2666
|
+
{
|
|
2667
|
+
MessageHandler messageHandler = Token._messageHandler;
|
|
2668
|
+
IMessageBus messageBus = ResolveRegistrationMessageBus();
|
|
2669
|
+
switch (_kind)
|
|
2670
|
+
{
|
|
2671
|
+
case RegistrationKind.TargetedHandlerAction:
|
|
2672
|
+
_scalarAction = (Action<T>)_userHandler;
|
|
2673
|
+
return StoreDeregistration(
|
|
2674
|
+
messageHandler.RegisterTargetedMessageHandler(
|
|
2675
|
+
_context,
|
|
2676
|
+
_scalarAction,
|
|
2677
|
+
AugmentedScalarAction,
|
|
2678
|
+
priority: _priority,
|
|
2679
|
+
messageBus: messageBus
|
|
2680
|
+
)
|
|
2681
|
+
);
|
|
2682
|
+
case RegistrationKind.TargetedHandlerFast:
|
|
2683
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2684
|
+
return StoreDeregistration(
|
|
2685
|
+
messageHandler.RegisterTargetedMessageHandler(
|
|
2686
|
+
_context,
|
|
2687
|
+
_scalarFast,
|
|
2688
|
+
AugmentedScalarFast,
|
|
2689
|
+
priority: _priority,
|
|
2690
|
+
messageBus: messageBus
|
|
2691
|
+
)
|
|
2692
|
+
);
|
|
2693
|
+
case RegistrationKind.TargetedPostProcessorAction:
|
|
2694
|
+
_scalarAction = (Action<T>)_userHandler;
|
|
2695
|
+
return StoreDeregistration(
|
|
2696
|
+
messageHandler.RegisterTargetedPostProcessor(
|
|
2697
|
+
_context,
|
|
2698
|
+
_scalarAction,
|
|
2699
|
+
AugmentedScalarAction,
|
|
2700
|
+
_priority,
|
|
2701
|
+
messageBus
|
|
2702
|
+
)
|
|
2703
|
+
);
|
|
2704
|
+
case RegistrationKind.TargetedPostProcessorFast:
|
|
2705
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2706
|
+
return StoreDeregistration(
|
|
2707
|
+
messageHandler.RegisterTargetedPostProcessor(
|
|
2708
|
+
_context,
|
|
2709
|
+
_scalarFast,
|
|
2710
|
+
AugmentedScalarFast,
|
|
2711
|
+
_priority,
|
|
2712
|
+
messageBus
|
|
2713
|
+
)
|
|
2714
|
+
);
|
|
2715
|
+
case RegistrationKind.TargetedWithoutTargetingAction:
|
|
2716
|
+
_contextAction = (Action<InstanceId, T>)_userHandler;
|
|
2717
|
+
return StoreDeregistration(
|
|
2718
|
+
messageHandler.RegisterTargetedWithoutTargeting(
|
|
2719
|
+
_contextAction,
|
|
2720
|
+
AugmentedContextAction,
|
|
2721
|
+
priority: _priority,
|
|
2722
|
+
messageBus: messageBus
|
|
2723
|
+
)
|
|
2724
|
+
);
|
|
2725
|
+
case RegistrationKind.TargetedWithoutTargetingFast:
|
|
2726
|
+
_contextFast = (MessageHandler.FastHandlerWithContext<T>)_userHandler;
|
|
2727
|
+
return StoreDeregistration(
|
|
2728
|
+
messageHandler.RegisterTargetedWithoutTargeting(
|
|
2729
|
+
_contextFast,
|
|
2730
|
+
AugmentedContextFast,
|
|
2731
|
+
priority: _priority,
|
|
2732
|
+
messageBus: messageBus
|
|
2733
|
+
)
|
|
2734
|
+
);
|
|
2735
|
+
case RegistrationKind.TargetedWithoutTargetingPostProcessorAction:
|
|
2736
|
+
_contextAction = (Action<InstanceId, T>)_userHandler;
|
|
2737
|
+
return StoreDeregistration(
|
|
2738
|
+
messageHandler.RegisterTargetedWithoutTargetingPostProcessor(
|
|
2739
|
+
_contextAction,
|
|
2740
|
+
AugmentedContextAction,
|
|
2741
|
+
_priority,
|
|
2742
|
+
messageBus
|
|
2743
|
+
)
|
|
2744
|
+
);
|
|
2745
|
+
case RegistrationKind.TargetedWithoutTargetingPostProcessorFast:
|
|
2746
|
+
_contextFast = (MessageHandler.FastHandlerWithContext<T>)_userHandler;
|
|
2747
|
+
return StoreDeregistration(
|
|
2748
|
+
messageHandler.RegisterTargetedWithoutTargetingPostProcessor(
|
|
2749
|
+
_contextFast,
|
|
2750
|
+
AugmentedContextFast,
|
|
2751
|
+
_priority,
|
|
2752
|
+
messageBus
|
|
2753
|
+
)
|
|
2754
|
+
);
|
|
2755
|
+
default:
|
|
2756
|
+
throw new InvalidOperationException(
|
|
2757
|
+
$"Unexpected registration kind {_kind} for TargetedRegistration<{typeof(T)}>."
|
|
2758
|
+
);
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
// Scalar invokers (targeted handler / post-processor). The user's handler is
|
|
2763
|
+
// the identity/dedup key; this flat invoker runs for the default slot. Calls
|
|
2764
|
+
// the typed field directly (no castclass) then records the (message, _context)
|
|
2765
|
+
// emission, matching the former AugmentedHandler bodies exactly.
|
|
2766
|
+
private void AugmentedScalarAction(ref T message)
|
|
2767
|
+
{
|
|
2768
|
+
_scalarAction(message);
|
|
2769
|
+
if (Token._diagnosticMode)
|
|
2770
|
+
{
|
|
2771
|
+
RecordDiagnosticEmission(message, _context);
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
private void AugmentedScalarFast(ref T message)
|
|
2776
|
+
{
|
|
2777
|
+
_scalarFast(ref message);
|
|
2778
|
+
if (Token._diagnosticMode)
|
|
2779
|
+
{
|
|
2780
|
+
RecordDiagnosticEmission(message, _context);
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
// Context invokers (without-targeting handler / post-processor). Emission data
|
|
2785
|
+
// uses the dispatch-supplied target (the ref param), not the stored _context
|
|
2786
|
+
// (default for these kinds), matching the former bodies exactly.
|
|
2787
|
+
private void AugmentedContextAction(ref InstanceId target, ref T message)
|
|
2788
|
+
{
|
|
2789
|
+
_contextAction(target, message);
|
|
2790
|
+
if (Token._diagnosticMode)
|
|
2791
|
+
{
|
|
2792
|
+
RecordDiagnosticEmission(message, target);
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
private void AugmentedContextFast(ref InstanceId target, ref T message)
|
|
2797
|
+
{
|
|
2798
|
+
_contextFast(ref target, ref message);
|
|
2799
|
+
if (Token._diagnosticMode)
|
|
2800
|
+
{
|
|
2801
|
+
RecordDiagnosticEmission(message, target);
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
private sealed class UntargetedRegistration<T> : Registration<T>
|
|
2807
|
+
where T : IUntargetedMessage
|
|
2808
|
+
{
|
|
2809
|
+
private readonly RegistrationKind _kind;
|
|
2810
|
+
private readonly object _userHandler;
|
|
2811
|
+
private readonly int _priority;
|
|
2812
|
+
|
|
2813
|
+
// Typed views of _userHandler, resolved once at Register() time (cold) so the
|
|
2814
|
+
// per-dispatch invoker calls a typed field directly -- no castclass/switch on
|
|
2815
|
+
// the hot path. Exactly one is set per registration kind.
|
|
2816
|
+
private Action<T> _scalarAction;
|
|
2817
|
+
private MessageHandler.FastHandler<T> _scalarFast;
|
|
2818
|
+
|
|
2819
|
+
internal UntargetedRegistration(
|
|
2820
|
+
MessageRegistrationToken token,
|
|
2821
|
+
RegistrationKind kind,
|
|
2822
|
+
object userHandler,
|
|
2823
|
+
int priority
|
|
2824
|
+
)
|
|
2825
|
+
: base(token)
|
|
2826
|
+
{
|
|
2827
|
+
_kind = kind;
|
|
2828
|
+
_userHandler = userHandler;
|
|
2829
|
+
_priority = priority;
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2832
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
2833
|
+
new MessageRegistrationMetadata(
|
|
2834
|
+
null,
|
|
2835
|
+
typeof(T),
|
|
2836
|
+
GetRegistrationType(_kind),
|
|
2837
|
+
_priority
|
|
2838
|
+
);
|
|
2839
|
+
|
|
2840
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
2841
|
+
{
|
|
2842
|
+
MessageHandler messageHandler = Token._messageHandler;
|
|
2843
|
+
IMessageBus messageBus = ResolveRegistrationMessageBus();
|
|
2844
|
+
switch (_kind)
|
|
2845
|
+
{
|
|
2846
|
+
case RegistrationKind.UntargetedHandlerAction:
|
|
2847
|
+
_scalarAction = (Action<T>)_userHandler;
|
|
2848
|
+
return StoreDeregistration(
|
|
2849
|
+
messageHandler.RegisterUntargetedMessageHandler(
|
|
2850
|
+
_scalarAction,
|
|
2851
|
+
AugmentedScalarAction,
|
|
2852
|
+
priority: _priority,
|
|
2853
|
+
messageBus: messageBus
|
|
2854
|
+
)
|
|
2855
|
+
);
|
|
2856
|
+
case RegistrationKind.UntargetedHandlerFast:
|
|
2857
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2858
|
+
return StoreDeregistration(
|
|
2859
|
+
messageHandler.RegisterUntargetedMessageHandler(
|
|
2860
|
+
_scalarFast,
|
|
2861
|
+
AugmentedScalarFast,
|
|
2862
|
+
priority: _priority,
|
|
2863
|
+
messageBus: messageBus
|
|
2864
|
+
)
|
|
2865
|
+
);
|
|
2866
|
+
case RegistrationKind.UntargetedPostProcessorFast:
|
|
2867
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2868
|
+
return StoreDeregistration(
|
|
2869
|
+
messageHandler.RegisterUntargetedPostProcessor(
|
|
2870
|
+
_scalarFast,
|
|
2871
|
+
AugmentedScalarFast,
|
|
2872
|
+
_priority,
|
|
2873
|
+
messageBus
|
|
2874
|
+
)
|
|
2875
|
+
);
|
|
2876
|
+
default:
|
|
2877
|
+
throw new InvalidOperationException(
|
|
2878
|
+
$"Unexpected registration kind {_kind} for UntargetedRegistration<{typeof(T)}>."
|
|
2879
|
+
);
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
// Untargeted scalar invokers. No context: emission data carries the message
|
|
2884
|
+
// only, matching the former AugmentedHandler bodies exactly.
|
|
2885
|
+
private void AugmentedScalarAction(ref T message)
|
|
2886
|
+
{
|
|
2887
|
+
_scalarAction(message);
|
|
2888
|
+
if (Token._diagnosticMode)
|
|
2889
|
+
{
|
|
2890
|
+
RecordDiagnosticEmission(message);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
private void AugmentedScalarFast(ref T message)
|
|
2895
|
+
{
|
|
2896
|
+
_scalarFast(ref message);
|
|
2897
|
+
if (Token._diagnosticMode)
|
|
2898
|
+
{
|
|
2899
|
+
RecordDiagnosticEmission(message);
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
private sealed class BroadcastRegistration<T> : Registration<T>
|
|
2905
|
+
where T : IBroadcastMessage
|
|
2906
|
+
{
|
|
2907
|
+
private readonly RegistrationKind _kind;
|
|
2908
|
+
private readonly InstanceId _context;
|
|
2909
|
+
private readonly object _userHandler;
|
|
2910
|
+
private readonly int _priority;
|
|
2911
|
+
|
|
2912
|
+
// Typed views of _userHandler, resolved once at Register() time (cold) so the
|
|
2913
|
+
// per-dispatch invoker calls a typed field directly -- no castclass/switch on
|
|
2914
|
+
// the hot path. Exactly one is set per registration kind.
|
|
2915
|
+
private Action<T> _scalarAction;
|
|
2916
|
+
private MessageHandler.FastHandler<T> _scalarFast;
|
|
2917
|
+
private Action<InstanceId, T> _contextAction;
|
|
2918
|
+
private MessageHandler.FastHandlerWithContext<T> _contextFast;
|
|
2919
|
+
|
|
2920
|
+
internal BroadcastRegistration(
|
|
2921
|
+
MessageRegistrationToken token,
|
|
2922
|
+
RegistrationKind kind,
|
|
2923
|
+
InstanceId context,
|
|
2924
|
+
object userHandler,
|
|
2925
|
+
int priority
|
|
2926
|
+
)
|
|
2927
|
+
: base(token)
|
|
2928
|
+
{
|
|
2929
|
+
_kind = kind;
|
|
2930
|
+
_context = context;
|
|
2931
|
+
_userHandler = userHandler;
|
|
2932
|
+
_priority = priority;
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
2936
|
+
new MessageRegistrationMetadata(
|
|
2937
|
+
_kind == RegistrationKind.BroadcastHandlerAction
|
|
2938
|
+
|| _kind == RegistrationKind.BroadcastHandlerFast
|
|
2939
|
+
|| _kind == RegistrationKind.BroadcastPostProcessorAction
|
|
2940
|
+
|| _kind == RegistrationKind.BroadcastPostProcessorFast
|
|
2941
|
+
? _context
|
|
2942
|
+
: (InstanceId?)null,
|
|
2943
|
+
typeof(T),
|
|
2944
|
+
GetRegistrationType(_kind),
|
|
2945
|
+
_priority
|
|
2946
|
+
);
|
|
2947
|
+
|
|
2948
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
2949
|
+
{
|
|
2950
|
+
MessageHandler messageHandler = Token._messageHandler;
|
|
2951
|
+
IMessageBus messageBus = ResolveRegistrationMessageBus();
|
|
2952
|
+
switch (_kind)
|
|
2953
|
+
{
|
|
2954
|
+
case RegistrationKind.BroadcastHandlerAction:
|
|
2955
|
+
_scalarAction = (Action<T>)_userHandler;
|
|
2956
|
+
return StoreDeregistration(
|
|
2957
|
+
messageHandler.RegisterSourcedBroadcastMessageHandler(
|
|
2958
|
+
_context,
|
|
2959
|
+
_scalarAction,
|
|
2960
|
+
AugmentedScalarAction,
|
|
2961
|
+
priority: _priority,
|
|
2962
|
+
messageBus: messageBus
|
|
2963
|
+
)
|
|
2964
|
+
);
|
|
2965
|
+
case RegistrationKind.BroadcastHandlerFast:
|
|
2966
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2967
|
+
return StoreDeregistration(
|
|
2968
|
+
messageHandler.RegisterSourcedBroadcastMessageHandler(
|
|
2969
|
+
_context,
|
|
2970
|
+
_scalarFast,
|
|
2971
|
+
AugmentedScalarFast,
|
|
2972
|
+
priority: _priority,
|
|
2973
|
+
messageBus: messageBus
|
|
2974
|
+
)
|
|
2975
|
+
);
|
|
2976
|
+
case RegistrationKind.BroadcastPostProcessorAction:
|
|
2977
|
+
_scalarAction = (Action<T>)_userHandler;
|
|
2978
|
+
return StoreDeregistration(
|
|
2979
|
+
messageHandler.RegisterSourcedBroadcastPostProcessor(
|
|
2980
|
+
_context,
|
|
2981
|
+
_scalarAction,
|
|
2982
|
+
AugmentedScalarAction,
|
|
2983
|
+
_priority,
|
|
2984
|
+
messageBus
|
|
2985
|
+
)
|
|
2986
|
+
);
|
|
2987
|
+
case RegistrationKind.BroadcastPostProcessorFast:
|
|
2988
|
+
_scalarFast = (MessageHandler.FastHandler<T>)_userHandler;
|
|
2989
|
+
return StoreDeregistration(
|
|
2990
|
+
messageHandler.RegisterSourcedBroadcastPostProcessor(
|
|
2991
|
+
_context,
|
|
2992
|
+
_scalarFast,
|
|
2993
|
+
AugmentedScalarFast,
|
|
2994
|
+
_priority,
|
|
2995
|
+
messageBus
|
|
2996
|
+
)
|
|
2997
|
+
);
|
|
2998
|
+
case RegistrationKind.BroadcastWithoutSourceAction:
|
|
2999
|
+
_contextAction = (Action<InstanceId, T>)_userHandler;
|
|
3000
|
+
return StoreDeregistration(
|
|
3001
|
+
messageHandler.RegisterSourcedBroadcastWithoutSource(
|
|
3002
|
+
_contextAction,
|
|
3003
|
+
AugmentedContextAction,
|
|
3004
|
+
priority: _priority,
|
|
3005
|
+
messageBus: messageBus
|
|
3006
|
+
)
|
|
3007
|
+
);
|
|
3008
|
+
case RegistrationKind.BroadcastWithoutSourceFast:
|
|
3009
|
+
_contextFast = (MessageHandler.FastHandlerWithContext<T>)_userHandler;
|
|
3010
|
+
return StoreDeregistration(
|
|
3011
|
+
messageHandler.RegisterSourcedBroadcastWithoutSource(
|
|
3012
|
+
_contextFast,
|
|
3013
|
+
AugmentedContextFast,
|
|
3014
|
+
priority: _priority,
|
|
3015
|
+
messageBus: messageBus
|
|
3016
|
+
)
|
|
3017
|
+
);
|
|
3018
|
+
case RegistrationKind.BroadcastWithoutSourcePostProcessorAction:
|
|
3019
|
+
_contextAction = (Action<InstanceId, T>)_userHandler;
|
|
3020
|
+
return StoreDeregistration(
|
|
3021
|
+
messageHandler.RegisterSourcedBroadcastWithoutSourcePostProcessor(
|
|
3022
|
+
_contextAction,
|
|
3023
|
+
AugmentedContextAction,
|
|
3024
|
+
priority: _priority,
|
|
3025
|
+
messageBus
|
|
3026
|
+
)
|
|
3027
|
+
);
|
|
3028
|
+
case RegistrationKind.BroadcastWithoutSourcePostProcessorFast:
|
|
3029
|
+
_contextFast = (MessageHandler.FastHandlerWithContext<T>)_userHandler;
|
|
3030
|
+
return StoreDeregistration(
|
|
3031
|
+
messageHandler.RegisterSourcedBroadcastWithoutSourcePostProcessor(
|
|
3032
|
+
_contextFast,
|
|
3033
|
+
AugmentedContextFast,
|
|
3034
|
+
priority: _priority,
|
|
3035
|
+
messageBus
|
|
3036
|
+
)
|
|
3037
|
+
);
|
|
3038
|
+
default:
|
|
3039
|
+
throw new InvalidOperationException(
|
|
3040
|
+
$"Unexpected registration kind {_kind} for BroadcastRegistration<{typeof(T)}>."
|
|
3041
|
+
);
|
|
3042
|
+
}
|
|
3043
|
+
}
|
|
3044
|
+
|
|
3045
|
+
// Broadcast scalar invokers. Emission data carries the stored source
|
|
3046
|
+
// (_context), matching the former AugmentedHandler bodies exactly.
|
|
3047
|
+
private void AugmentedScalarAction(ref T message)
|
|
3048
|
+
{
|
|
3049
|
+
_scalarAction(message);
|
|
3050
|
+
if (Token._diagnosticMode)
|
|
3051
|
+
{
|
|
3052
|
+
RecordDiagnosticEmission(message, _context);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
private void AugmentedScalarFast(ref T message)
|
|
3057
|
+
{
|
|
3058
|
+
_scalarFast(ref message);
|
|
3059
|
+
if (Token._diagnosticMode)
|
|
3060
|
+
{
|
|
3061
|
+
RecordDiagnosticEmission(message, _context);
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
// Broadcast context invokers for the without-source kinds. Emission data uses
|
|
3066
|
+
// the dispatch-supplied source (the ref param), not the stored _context
|
|
3067
|
+
// (default for these kinds), matching the former bodies exactly.
|
|
3068
|
+
private void AugmentedContextAction(ref InstanceId source, ref T message)
|
|
3069
|
+
{
|
|
3070
|
+
_contextAction(source, message);
|
|
3071
|
+
if (Token._diagnosticMode)
|
|
3072
|
+
{
|
|
3073
|
+
RecordDiagnosticEmission(message, source);
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
private void AugmentedContextFast(ref InstanceId source, ref T message)
|
|
3078
|
+
{
|
|
3079
|
+
_contextFast(ref source, ref message);
|
|
3080
|
+
if (Token._diagnosticMode)
|
|
3081
|
+
{
|
|
3082
|
+
RecordDiagnosticEmission(message, source);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
|
|
3087
|
+
private abstract class InterceptorRegistration<T> : Registration
|
|
3088
|
+
where T : IMessage
|
|
3089
|
+
{
|
|
3090
|
+
protected readonly int Priority;
|
|
3091
|
+
private MessageHandler.InterceptorDeregistrationState<T> _deregistration;
|
|
3092
|
+
private bool _hasInlineDeregistration;
|
|
3093
|
+
|
|
3094
|
+
protected InterceptorRegistration(MessageRegistrationToken token, int priority)
|
|
3095
|
+
: base(token)
|
|
3096
|
+
{
|
|
3097
|
+
Priority = priority;
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
protected MessageHandler.HandlerDeregistration StoreDeregistration(
|
|
3101
|
+
MessageHandler.InterceptorDeregistrationState<T> deregistration
|
|
3102
|
+
)
|
|
3103
|
+
{
|
|
3104
|
+
if (_hasInlineDeregistration)
|
|
3105
|
+
{
|
|
3106
|
+
return deregistration;
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3109
|
+
_deregistration = deregistration;
|
|
3110
|
+
_hasInlineDeregistration = true;
|
|
3111
|
+
return this;
|
|
3112
|
+
}
|
|
3113
|
+
|
|
3114
|
+
internal override void Deregister()
|
|
3115
|
+
{
|
|
3116
|
+
if (!_hasInlineDeregistration)
|
|
3117
|
+
{
|
|
3118
|
+
return;
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
_deregistration.Deregister();
|
|
3122
|
+
_hasInlineDeregistration = false;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
private sealed class UntargetedInterceptorRegistration<T> : InterceptorRegistration<T>
|
|
3127
|
+
where T : IUntargetedMessage
|
|
3128
|
+
{
|
|
3129
|
+
private readonly IMessageBus.UntargetedInterceptor<T> _interceptor;
|
|
3130
|
+
|
|
3131
|
+
internal UntargetedInterceptorRegistration(
|
|
3132
|
+
MessageRegistrationToken token,
|
|
3133
|
+
IMessageBus.UntargetedInterceptor<T> interceptor,
|
|
3134
|
+
int priority
|
|
3135
|
+
)
|
|
3136
|
+
: base(token, priority)
|
|
3137
|
+
{
|
|
3138
|
+
_interceptor = interceptor;
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
3142
|
+
new MessageRegistrationMetadata(
|
|
3143
|
+
null,
|
|
3144
|
+
typeof(T),
|
|
3145
|
+
MessageRegistrationType.UntargetedInterceptor,
|
|
3146
|
+
Priority
|
|
3147
|
+
);
|
|
3148
|
+
|
|
3149
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
3150
|
+
{
|
|
3151
|
+
return StoreDeregistration(
|
|
3152
|
+
Token._messageHandler.RegisterUntargetedInterceptor(
|
|
3153
|
+
_interceptor,
|
|
3154
|
+
Priority,
|
|
3155
|
+
ResolveRegistrationMessageBus()
|
|
3156
|
+
)
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
private sealed class TargetedInterceptorRegistration<T> : InterceptorRegistration<T>
|
|
3162
|
+
where T : ITargetedMessage
|
|
3163
|
+
{
|
|
3164
|
+
private readonly IMessageBus.TargetedInterceptor<T> _interceptor;
|
|
3165
|
+
|
|
3166
|
+
internal TargetedInterceptorRegistration(
|
|
3167
|
+
MessageRegistrationToken token,
|
|
3168
|
+
IMessageBus.TargetedInterceptor<T> interceptor,
|
|
3169
|
+
int priority
|
|
3170
|
+
)
|
|
3171
|
+
: base(token, priority)
|
|
3172
|
+
{
|
|
3173
|
+
_interceptor = interceptor;
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
3177
|
+
new MessageRegistrationMetadata(
|
|
3178
|
+
null,
|
|
3179
|
+
typeof(T),
|
|
3180
|
+
MessageRegistrationType.TargetedInterceptor,
|
|
3181
|
+
Priority
|
|
3182
|
+
);
|
|
3183
|
+
|
|
3184
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
3185
|
+
{
|
|
3186
|
+
return StoreDeregistration(
|
|
3187
|
+
Token._messageHandler.RegisterTargetedInterceptor(
|
|
3188
|
+
_interceptor,
|
|
3189
|
+
Priority,
|
|
3190
|
+
ResolveRegistrationMessageBus()
|
|
3191
|
+
)
|
|
3192
|
+
);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
private sealed class BroadcastInterceptorRegistration<T> : InterceptorRegistration<T>
|
|
3197
|
+
where T : IBroadcastMessage
|
|
3198
|
+
{
|
|
3199
|
+
private readonly IMessageBus.BroadcastInterceptor<T> _interceptor;
|
|
3200
|
+
|
|
3201
|
+
internal BroadcastInterceptorRegistration(
|
|
3202
|
+
MessageRegistrationToken token,
|
|
3203
|
+
IMessageBus.BroadcastInterceptor<T> interceptor,
|
|
3204
|
+
int priority
|
|
3205
|
+
)
|
|
3206
|
+
: base(token, priority)
|
|
3207
|
+
{
|
|
3208
|
+
_interceptor = interceptor;
|
|
3209
|
+
}
|
|
3210
|
+
|
|
3211
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
3212
|
+
new MessageRegistrationMetadata(
|
|
3213
|
+
null,
|
|
3214
|
+
typeof(T),
|
|
3215
|
+
MessageRegistrationType.BroadcastInterceptor,
|
|
3216
|
+
Priority
|
|
3217
|
+
);
|
|
3218
|
+
|
|
3219
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
3220
|
+
{
|
|
3221
|
+
return StoreDeregistration(
|
|
3222
|
+
Token._messageHandler.RegisterBroadcastInterceptor(
|
|
3223
|
+
_interceptor,
|
|
3224
|
+
Priority,
|
|
3225
|
+
ResolveRegistrationMessageBus()
|
|
3226
|
+
)
|
|
3227
|
+
);
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
// Global accept-all is non-generic: its three sub-handlers are the fixed
|
|
3232
|
+
// IMessage facades. Stores the three user delegates (as object, since the two
|
|
3233
|
+
// public overloads differ in delegate shape -- Action vs FastHandler/
|
|
3234
|
+
// FastHandlerWithContext) and exposes six augmented sub-invokers (three per
|
|
3235
|
+
// overload shape). The kind-switch picks the matching MessageHandler.
|
|
3236
|
+
// RegisterGlobalAcceptAll overload and binds the three augmented invokers.
|
|
3237
|
+
private sealed class GlobalAcceptAllRegistration : Registration
|
|
3238
|
+
{
|
|
3239
|
+
private readonly RegistrationKind _kind;
|
|
3240
|
+
|
|
3241
|
+
// Typed sub-handlers (one shape-trio is set per kind). The per-dispatch
|
|
3242
|
+
// invokers call these directly -- no castclass on the hot global-dispatch
|
|
3243
|
+
// path (the heaviest fan-out, so the castclass cost there was the worst).
|
|
3244
|
+
private readonly Action<IUntargetedMessage> _untargetedAction;
|
|
3245
|
+
private readonly Action<InstanceId, ITargetedMessage> _targetedAction;
|
|
3246
|
+
private readonly Action<InstanceId, IBroadcastMessage> _broadcastAction;
|
|
3247
|
+
private readonly MessageHandler.FastHandler<IUntargetedMessage> _untargetedFast;
|
|
3248
|
+
private readonly MessageHandler.FastHandlerWithContext<ITargetedMessage> _targetedFast;
|
|
3249
|
+
private readonly MessageHandler.FastHandlerWithContext<IBroadcastMessage> _broadcastFast;
|
|
3250
|
+
private MessageHandler.GlobalAcceptAllDeregistrationState _deregistration;
|
|
3251
|
+
private bool _hasInlineDeregistration;
|
|
3252
|
+
|
|
3253
|
+
public override MessageRegistrationMetadata Metadata =>
|
|
3254
|
+
new MessageRegistrationMetadata(
|
|
3255
|
+
null,
|
|
3256
|
+
typeof(IMessage),
|
|
3257
|
+
MessageRegistrationType.GlobalAcceptAll,
|
|
3258
|
+
0
|
|
3259
|
+
);
|
|
3260
|
+
|
|
3261
|
+
internal GlobalAcceptAllRegistration(
|
|
3262
|
+
MessageRegistrationToken token,
|
|
3263
|
+
Action<IUntargetedMessage> untargeted,
|
|
3264
|
+
Action<InstanceId, ITargetedMessage> targeted,
|
|
3265
|
+
Action<InstanceId, IBroadcastMessage> broadcast
|
|
3266
|
+
)
|
|
3267
|
+
: base(token)
|
|
3268
|
+
{
|
|
3269
|
+
_kind = RegistrationKind.GlobalAcceptAllAction;
|
|
3270
|
+
_untargetedAction = untargeted;
|
|
3271
|
+
_targetedAction = targeted;
|
|
3272
|
+
_broadcastAction = broadcast;
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
internal GlobalAcceptAllRegistration(
|
|
3276
|
+
MessageRegistrationToken token,
|
|
3277
|
+
MessageHandler.FastHandler<IUntargetedMessage> untargeted,
|
|
3278
|
+
MessageHandler.FastHandlerWithContext<ITargetedMessage> targeted,
|
|
3279
|
+
MessageHandler.FastHandlerWithContext<IBroadcastMessage> broadcast
|
|
3280
|
+
)
|
|
3281
|
+
: base(token)
|
|
3282
|
+
{
|
|
3283
|
+
_kind = RegistrationKind.GlobalAcceptAllFast;
|
|
3284
|
+
_untargetedFast = untargeted;
|
|
3285
|
+
_targetedFast = targeted;
|
|
3286
|
+
_broadcastFast = broadcast;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
public override MessageHandler.HandlerDeregistration Register()
|
|
3290
|
+
{
|
|
3291
|
+
MessageHandler messageHandler = Token._messageHandler;
|
|
3292
|
+
IMessageBus messageBus = ResolveRegistrationMessageBus();
|
|
3293
|
+
if (_kind == RegistrationKind.GlobalAcceptAllAction)
|
|
3294
|
+
{
|
|
3295
|
+
return StoreDeregistration(
|
|
3296
|
+
messageHandler.RegisterGlobalAcceptAll(
|
|
3297
|
+
_untargetedAction,
|
|
3298
|
+
AugmentedUntargetedAction,
|
|
3299
|
+
_targetedAction,
|
|
3300
|
+
AugmentedTargetedAction,
|
|
3301
|
+
_broadcastAction,
|
|
3302
|
+
AugmentedBroadcastAction,
|
|
3303
|
+
messageBus
|
|
3304
|
+
)
|
|
3305
|
+
);
|
|
3306
|
+
}
|
|
3307
|
+
|
|
3308
|
+
return StoreDeregistration(
|
|
3309
|
+
messageHandler.RegisterGlobalAcceptAll(
|
|
3310
|
+
_untargetedFast,
|
|
3311
|
+
AugmentedUntargetedFast,
|
|
3312
|
+
_targetedFast,
|
|
3313
|
+
AugmentedTargetedFast,
|
|
3314
|
+
_broadcastFast,
|
|
3315
|
+
AugmentedBroadcastFast,
|
|
3316
|
+
messageBus
|
|
3317
|
+
)
|
|
3318
|
+
);
|
|
3319
|
+
}
|
|
3320
|
+
|
|
3321
|
+
internal override void Deregister()
|
|
3322
|
+
{
|
|
3323
|
+
if (!_hasInlineDeregistration)
|
|
3324
|
+
{
|
|
3325
|
+
return;
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
_deregistration.Deregister();
|
|
3329
|
+
_hasInlineDeregistration = false;
|
|
3330
|
+
}
|
|
3331
|
+
|
|
3332
|
+
private MessageHandler.HandlerDeregistration StoreDeregistration(
|
|
3333
|
+
MessageHandler.GlobalAcceptAllDeregistrationState deregistration
|
|
3334
|
+
)
|
|
3335
|
+
{
|
|
3336
|
+
if (_hasInlineDeregistration)
|
|
3337
|
+
{
|
|
3338
|
+
return deregistration;
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3341
|
+
_deregistration = deregistration;
|
|
3342
|
+
_hasInlineDeregistration = true;
|
|
3343
|
+
return this;
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
private void AugmentedUntargetedAction(IUntargetedMessage message)
|
|
3347
|
+
{
|
|
3348
|
+
_untargetedAction(message);
|
|
3349
|
+
if (Token._diagnosticMode)
|
|
3350
|
+
{
|
|
3351
|
+
RecordDiagnosticEmission(message);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
private void AugmentedTargetedAction(InstanceId target, ITargetedMessage message)
|
|
3356
|
+
{
|
|
3357
|
+
_targetedAction(target, message);
|
|
3358
|
+
if (Token._diagnosticMode)
|
|
3359
|
+
{
|
|
3360
|
+
RecordDiagnosticEmission(message, target);
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
private void AugmentedBroadcastAction(InstanceId source, IBroadcastMessage message)
|
|
3365
|
+
{
|
|
3366
|
+
_broadcastAction(source, message);
|
|
3367
|
+
if (Token._diagnosticMode)
|
|
3368
|
+
{
|
|
3369
|
+
RecordDiagnosticEmission(message, source);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3373
|
+
private void AugmentedUntargetedFast(ref IUntargetedMessage message)
|
|
3374
|
+
{
|
|
3375
|
+
_untargetedFast(ref message);
|
|
3376
|
+
if (Token._diagnosticMode)
|
|
3377
|
+
{
|
|
3378
|
+
RecordDiagnosticEmission(message);
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
private void AugmentedTargetedFast(ref InstanceId target, ref ITargetedMessage message)
|
|
3383
|
+
{
|
|
3384
|
+
_targetedFast(ref target, ref message);
|
|
3385
|
+
if (Token._diagnosticMode)
|
|
3386
|
+
{
|
|
3387
|
+
RecordDiagnosticEmission(message, target);
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
|
|
3391
|
+
private void AugmentedBroadcastFast(
|
|
3392
|
+
ref InstanceId source,
|
|
3393
|
+
ref IBroadcastMessage message
|
|
3394
|
+
)
|
|
3395
|
+
{
|
|
3396
|
+
_broadcastFast(ref source, ref message);
|
|
3397
|
+
if (Token._diagnosticMode)
|
|
3398
|
+
{
|
|
3399
|
+
RecordDiagnosticEmission(message, source);
|
|
3400
|
+
}
|
|
2364
3401
|
}
|
|
2365
3402
|
}
|
|
2366
3403
|
|