com.wallstop-studios.dxmessaging 2.1.2 → 2.1.4
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/.github/workflows/dotnet-tests.yml +3 -3
- package/.github/workflows/prettier-autofix.yml +0 -7
- package/.pre-commit-config.yaml +8 -5
- package/AGENTS.md +12 -12
- package/CONTRIBUTING.md +8 -2
- package/Docs/Comparisons.md +5 -5
- package/Docs/InterceptorsAndOrdering.md +1 -1
- package/Docs/Performance.md +13 -13
- package/Docs/QuickReference.md +1 -1
- package/Docs/Reference.md +5 -5
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +3 -0
- package/Editor/DxMessagingEditorInitializer.cs +58 -1
- package/Editor/DxMessagingMenu.cs +38 -0
- package/Editor/DxMessagingMenu.cs.meta +11 -0
- package/Editor/DxMessagingSceneBuildProcessor.cs +81 -0
- package/Editor/DxMessagingSceneBuildProcessor.cs.meta +11 -0
- package/Editor/Settings/DxMessagingSettings.cs +37 -6
- package/Editor/Settings/DxMessagingSettingsProvider.cs +45 -7
- package/README.md +1 -1
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +52 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +16 -0
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs +1 -1
- package/Runtime/Core/Diagnostics/MessageRegistrationType.cs +62 -0
- package/Runtime/Core/DxMessagingStaticState.cs +108 -0
- package/Runtime/Core/DxMessagingStaticState.cs.meta +11 -0
- package/Runtime/Core/Extensions/IListExtensions.cs +24 -0
- package/Runtime/Core/Extensions/MessageBusExtensions.cs +142 -0
- package/Runtime/Core/Helper/MessageCache.cs +16 -0
- package/Runtime/Core/Helper/MessageHelperIndexer.cs +77 -0
- package/Runtime/Core/InstanceId.cs +86 -0
- package/Runtime/Core/MessageBus/DiagnosticsTarget.cs +31 -0
- package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageBus.cs +44 -16
- package/Runtime/Core/MessageBus/MessageBus.cs +167 -180
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +44 -0
- package/Runtime/Core/MessageBus/MessagingRegistration.cs +60 -2
- package/Runtime/Core/MessageBus/RegistrationLog.cs +10 -0
- package/Runtime/Core/MessageHandler.cs +107 -6
- package/Runtime/Core/MessageRegistrationHandle.cs +59 -0
- package/Runtime/Core/MessageRegistrationToken.cs +18 -2
- package/Runtime/Core/Messages/ReflexiveMessage.cs +38 -0
- package/Runtime/Core/MessagingDebug.cs +16 -1
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +4 -0
- package/Runtime/Unity/DxMessagingRuntimeInitializer.cs +19 -0
- package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +11 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +4 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +17 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +8 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +12 -0
- package/Runtime/Unity/MessagingComponent.cs +93 -0
- package/Samples~/DI/README.md +13 -13
- package/Samples~/Mini Combat/README.md +15 -15
- package/Samples~/Mini Combat/Walkthrough.md +12 -12
- package/Samples~/UI Buttons + Inspector/README.md +4 -4
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +4 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +4 -0
- package/Tests/Runtime/Core/DiagnosticsTests.cs +3 -3
- package/Tests/Runtime/Core/DxMessagingStaticStateTests.cs +69 -0
- package/Tests/Runtime/Core/DxMessagingStaticStateTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs +12 -31
- package/Tests/Runtime/Core/OrderingManyRegistrationsTests.cs +683 -0
- package/Tests/Runtime/Core/OrderingManyRegistrationsTests.cs.meta +11 -0
- package/package.json +1 -1
- package/scripts/fix-eol.js +38 -3
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +0 -20
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj.meta +0 -7
|
@@ -99,6 +99,13 @@ namespace DxMessaging.Core.MessageBus
|
|
|
99
99
|
/// </remarks>
|
|
100
100
|
public readonly struct MessageRegistrationLifecycle
|
|
101
101
|
{
|
|
102
|
+
/// <summary>
|
|
103
|
+
/// Creates a lifecycle definition with the supplied callbacks.
|
|
104
|
+
/// </summary>
|
|
105
|
+
/// <param name="onBuild">Invoked immediately after the lease is constructed.</param>
|
|
106
|
+
/// <param name="onActivate">Invoked when the lease becomes active.</param>
|
|
107
|
+
/// <param name="onDeactivate">Invoked when the lease transitions from active to inactive.</param>
|
|
108
|
+
/// <param name="onDispose">Invoked during lease disposal.</param>
|
|
102
109
|
public MessageRegistrationLifecycle(
|
|
103
110
|
Action<MessageRegistrationToken> onBuild,
|
|
104
111
|
Action<MessageRegistrationToken> onActivate,
|
|
@@ -201,6 +208,9 @@ namespace DxMessaging.Core.MessageBus
|
|
|
201
208
|
_isActive = true;
|
|
202
209
|
}
|
|
203
210
|
|
|
211
|
+
/// <summary>
|
|
212
|
+
/// Deactivates the lease, unregistering staged handlers and invoking lifecycle hooks.
|
|
213
|
+
/// </summary>
|
|
204
214
|
public void Deactivate()
|
|
205
215
|
{
|
|
206
216
|
if (_disposed || !_isActive)
|
|
@@ -218,6 +228,9 @@ namespace DxMessaging.Core.MessageBus
|
|
|
218
228
|
_isActive = false;
|
|
219
229
|
}
|
|
220
230
|
|
|
231
|
+
/// <summary>
|
|
232
|
+
/// Disposes the lease, unregistering handlers and executing lifecycle callbacks once.
|
|
233
|
+
/// </summary>
|
|
221
234
|
public void Dispose()
|
|
222
235
|
{
|
|
223
236
|
if (_disposed)
|
|
@@ -259,11 +272,33 @@ namespace DxMessaging.Core.MessageBus
|
|
|
259
272
|
private readonly IMessageBusProvider _messageBusProvider;
|
|
260
273
|
private static int _syntheticOwnerCounter;
|
|
261
274
|
|
|
275
|
+
internal static int GetSyntheticOwnerCounter()
|
|
276
|
+
{
|
|
277
|
+
return Volatile.Read(ref _syntheticOwnerCounter);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
internal static void SetSyntheticOwnerCounter(int value)
|
|
281
|
+
{
|
|
282
|
+
_ = Interlocked.Exchange(ref _syntheticOwnerCounter, value);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
internal static void ResetSyntheticOwnerCounter()
|
|
286
|
+
{
|
|
287
|
+
SetSyntheticOwnerCounter(0);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/// <summary>
|
|
291
|
+
/// Initializes a builder that resolves buses from global state.
|
|
292
|
+
/// </summary>
|
|
262
293
|
public MessageRegistrationBuilder()
|
|
263
294
|
{
|
|
264
295
|
_messageBusProvider = null;
|
|
265
296
|
}
|
|
266
297
|
|
|
298
|
+
/// <summary>
|
|
299
|
+
/// Initializes a builder that uses a custom bus provider.
|
|
300
|
+
/// </summary>
|
|
301
|
+
/// <param name="messageBusProvider">Provider used to resolve message buses for new leases.</param>
|
|
267
302
|
public MessageRegistrationBuilder(IMessageBusProvider messageBusProvider)
|
|
268
303
|
{
|
|
269
304
|
_messageBusProvider = messageBusProvider;
|
|
@@ -370,11 +405,20 @@ namespace DxMessaging.Core.MessageBus
|
|
|
370
405
|
{
|
|
371
406
|
private readonly IMessageBus _messageBus;
|
|
372
407
|
|
|
408
|
+
/// <summary>
|
|
409
|
+
/// Creates a provider that always returns the supplied bus instance.
|
|
410
|
+
/// </summary>
|
|
411
|
+
/// <param name="messageBus">Bus instance to return when <see cref="Resolve"/> is invoked.</param>
|
|
412
|
+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="messageBus"/> is null.</exception>
|
|
373
413
|
public FixedMessageBusProvider(IMessageBus messageBus)
|
|
374
414
|
{
|
|
375
415
|
_messageBus = messageBus ?? throw new ArgumentNullException(nameof(messageBus));
|
|
376
416
|
}
|
|
377
417
|
|
|
418
|
+
/// <summary>
|
|
419
|
+
/// Resolves the configured message bus.
|
|
420
|
+
/// </summary>
|
|
421
|
+
/// <returns>The bus supplied during construction.</returns>
|
|
378
422
|
public IMessageBus Resolve()
|
|
379
423
|
{
|
|
380
424
|
return _messageBus;
|
|
@@ -4,30 +4,84 @@ namespace DxMessaging.Core.MessageBus
|
|
|
4
4
|
using System.Runtime.Serialization;
|
|
5
5
|
|
|
6
6
|
/// <summary>
|
|
7
|
-
///
|
|
7
|
+
/// Indicates whether a registration was added or removed.
|
|
8
8
|
/// </summary>
|
|
9
9
|
public enum RegistrationType
|
|
10
10
|
{
|
|
11
|
+
/// <summary>
|
|
12
|
+
/// The registration was added to the bus.
|
|
13
|
+
/// </summary>
|
|
11
14
|
Register,
|
|
15
|
+
|
|
16
|
+
/// <summary>
|
|
17
|
+
/// The registration was removed from the bus.
|
|
18
|
+
/// </summary>
|
|
12
19
|
Deregister,
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
/// <summary>
|
|
16
|
-
/// Exact
|
|
23
|
+
/// Exact registration category used when the handler was wired up.
|
|
17
24
|
/// </summary>
|
|
18
25
|
public enum RegistrationMethod
|
|
19
26
|
{
|
|
27
|
+
/// <summary>
|
|
28
|
+
/// Registered as a targeted handler bound to a specific recipient.
|
|
29
|
+
/// </summary>
|
|
20
30
|
Targeted,
|
|
31
|
+
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// Registered as a global untargeted handler.
|
|
34
|
+
/// </summary>
|
|
21
35
|
Untargeted,
|
|
36
|
+
|
|
37
|
+
/// <summary>
|
|
38
|
+
/// Registered as a broadcast handler bound to a specific source.
|
|
39
|
+
/// </summary>
|
|
22
40
|
Broadcast,
|
|
41
|
+
|
|
42
|
+
/// <summary>
|
|
43
|
+
/// Registered as a broadcast handler without an explicit source.
|
|
44
|
+
/// </summary>
|
|
23
45
|
BroadcastWithoutSource,
|
|
46
|
+
|
|
47
|
+
/// <summary>
|
|
48
|
+
/// Registered as a targeted handler that ignores the runtime target.
|
|
49
|
+
/// </summary>
|
|
24
50
|
TargetedWithoutTargeting,
|
|
51
|
+
|
|
52
|
+
/// <summary>
|
|
53
|
+
/// Registered as a global catch-all handler.
|
|
54
|
+
/// </summary>
|
|
25
55
|
GlobalAcceptAll,
|
|
56
|
+
|
|
57
|
+
/// <summary>
|
|
58
|
+
/// Registered as an interceptor (exact type recorded separately).
|
|
59
|
+
/// </summary>
|
|
26
60
|
Interceptor,
|
|
61
|
+
|
|
62
|
+
/// <summary>
|
|
63
|
+
/// Registered as a post-processor for untargeted messages.
|
|
64
|
+
/// </summary>
|
|
27
65
|
UntargetedPostProcessor,
|
|
66
|
+
|
|
67
|
+
/// <summary>
|
|
68
|
+
/// Registered as a post-processor for targeted messages.
|
|
69
|
+
/// </summary>
|
|
28
70
|
TargetedPostProcessor,
|
|
71
|
+
|
|
72
|
+
/// <summary>
|
|
73
|
+
/// Registered as a post-processor for broadcast messages.
|
|
74
|
+
/// </summary>
|
|
29
75
|
BroadcastPostProcessor,
|
|
76
|
+
|
|
77
|
+
/// <summary>
|
|
78
|
+
/// Registered as a post-processor for targeted messages that ignore the runtime target.
|
|
79
|
+
/// </summary>
|
|
30
80
|
TargetedWithoutTargetingPostProcessor,
|
|
81
|
+
|
|
82
|
+
/// <summary>
|
|
83
|
+
/// Registered as a post-processor for broadcasts without explicit source information.
|
|
84
|
+
/// </summary>
|
|
31
85
|
BroadcastWithoutSourcePostProcessor,
|
|
32
86
|
}
|
|
33
87
|
|
|
@@ -88,6 +142,10 @@ namespace DxMessaging.Core.MessageBus
|
|
|
88
142
|
#endif
|
|
89
143
|
}
|
|
90
144
|
|
|
145
|
+
/// <summary>
|
|
146
|
+
/// Returns a descriptive string that includes key registration metadata for diagnostics.
|
|
147
|
+
/// </summary>
|
|
148
|
+
/// <returns>Human-readable summary of this registration entry.</returns>
|
|
91
149
|
public override string ToString()
|
|
92
150
|
{
|
|
93
151
|
return new
|
|
@@ -26,6 +26,12 @@ namespace DxMessaging.Core.MessageBus
|
|
|
26
26
|
|
|
27
27
|
private bool _enabled;
|
|
28
28
|
|
|
29
|
+
/// <summary>
|
|
30
|
+
/// Creates a new registration log.
|
|
31
|
+
/// </summary>
|
|
32
|
+
/// <param name="enabled">
|
|
33
|
+
/// When <c>true</c>, logging starts immediately; otherwise call <see cref="Enabled"/> to enable later.
|
|
34
|
+
/// </param>
|
|
29
35
|
public RegistrationLog(bool enabled = false)
|
|
30
36
|
{
|
|
31
37
|
_enabled = enabled;
|
|
@@ -92,6 +98,10 @@ namespace DxMessaging.Core.MessageBus
|
|
|
92
98
|
return registrations.ToString();
|
|
93
99
|
}
|
|
94
100
|
|
|
101
|
+
/// <summary>
|
|
102
|
+
/// Serializes the log using the default formatter (<see cref="MessagingRegistration.ToString"/>).
|
|
103
|
+
/// </summary>
|
|
104
|
+
/// <returns>String containing all recorded registrations.</returns>
|
|
95
105
|
public override string ToString()
|
|
96
106
|
{
|
|
97
107
|
return ToString(null);
|
|
@@ -345,12 +345,14 @@ namespace DxMessaging.Core
|
|
|
345
345
|
)
|
|
346
346
|
where TMessage : IMessage;
|
|
347
347
|
|
|
348
|
+
private static readonly object GlobalResetLock = new object();
|
|
349
|
+
|
|
348
350
|
/// <summary>
|
|
349
351
|
/// Global message bus used when no explicit bus is provided.
|
|
350
352
|
/// </summary>
|
|
351
353
|
private static IMessageBus _globalMessageBus;
|
|
352
354
|
|
|
353
|
-
private static
|
|
355
|
+
private static MessageBus.MessageBus _defaultGlobalMessageBus = new MessageBus.MessageBus();
|
|
354
356
|
|
|
355
357
|
/// <summary>
|
|
356
358
|
/// Gets the process-wide <see cref="IMessageBus"/> used when no explicit bus is supplied.
|
|
@@ -363,16 +365,17 @@ namespace DxMessaging.Core
|
|
|
363
365
|
public static IMessageBus MessageBus => _globalMessageBus;
|
|
364
366
|
|
|
365
367
|
/// <summary>
|
|
366
|
-
/// Gets the
|
|
368
|
+
/// Gets the baseline global <see cref="IMessageBus"/> instance used when no custom bus is configured.
|
|
367
369
|
/// </summary>
|
|
368
370
|
/// <remarks>
|
|
369
|
-
///
|
|
371
|
+
/// The instance is recreated when <see cref="DxMessagingStaticState.Reset"/> runs so that domain-reload-disabled
|
|
372
|
+
/// environments can obtain a clean slate.
|
|
370
373
|
/// </remarks>
|
|
371
374
|
public static IMessageBus InitialGlobalMessageBus => _defaultGlobalMessageBus;
|
|
372
375
|
|
|
373
376
|
static MessageHandler()
|
|
374
377
|
{
|
|
375
|
-
|
|
378
|
+
ResetStatics();
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
/// <summary>
|
|
@@ -417,11 +420,14 @@ namespace DxMessaging.Core
|
|
|
417
420
|
/// Restores the global <see cref="MessageBus.MessageBus"/> to the built-in default instance.
|
|
418
421
|
/// </summary>
|
|
419
422
|
/// <remarks>
|
|
420
|
-
/// The default instance is
|
|
423
|
+
/// The default instance is recreated by <see cref="ResetStatics"/> when the static state reset utility runs.
|
|
421
424
|
/// </remarks>
|
|
422
425
|
public static void ResetGlobalMessageBus()
|
|
423
426
|
{
|
|
424
|
-
|
|
427
|
+
lock (GlobalResetLock)
|
|
428
|
+
{
|
|
429
|
+
_globalMessageBus = _defaultGlobalMessageBus;
|
|
430
|
+
}
|
|
425
431
|
}
|
|
426
432
|
|
|
427
433
|
/// <summary>
|
|
@@ -434,6 +440,21 @@ namespace DxMessaging.Core
|
|
|
434
440
|
return new GlobalMessageBusScope(messageBus);
|
|
435
441
|
}
|
|
436
442
|
|
|
443
|
+
/// <summary>
|
|
444
|
+
/// Recreates the built-in global <see cref="MessageBus.MessageBus"/> and assigns it as the active global bus.
|
|
445
|
+
/// </summary>
|
|
446
|
+
/// <remarks>
|
|
447
|
+
/// Invoked by <see cref="DxMessagingStaticState.Reset"/> to provide a clean slate when domain reloads are disabled.
|
|
448
|
+
/// </remarks>
|
|
449
|
+
internal static void ResetStatics()
|
|
450
|
+
{
|
|
451
|
+
lock (GlobalResetLock)
|
|
452
|
+
{
|
|
453
|
+
_defaultGlobalMessageBus.ResetState();
|
|
454
|
+
_globalMessageBus = _defaultGlobalMessageBus;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
437
458
|
/// <summary>
|
|
438
459
|
/// Represents a disposable override scope for the global message bus.
|
|
439
460
|
/// </summary>
|
|
@@ -462,6 +483,9 @@ namespace DxMessaging.Core
|
|
|
462
483
|
}
|
|
463
484
|
}
|
|
464
485
|
|
|
486
|
+
/// <summary>
|
|
487
|
+
/// Restores the previously active global message bus when the scope ends.
|
|
488
|
+
/// </summary>
|
|
465
489
|
public void Dispose()
|
|
466
490
|
{
|
|
467
491
|
if (_disposed)
|
|
@@ -514,6 +538,14 @@ namespace DxMessaging.Core
|
|
|
514
538
|
/// </remarks>
|
|
515
539
|
public IMessageBus DefaultMessageBus => _defaultMessageBus ?? MessageBus;
|
|
516
540
|
|
|
541
|
+
/// <summary>
|
|
542
|
+
/// Initializes a message handler bound to the specified owner and optional default bus.
|
|
543
|
+
/// </summary>
|
|
544
|
+
/// <param name="owner">Identity of the object that owns this handler.</param>
|
|
545
|
+
/// <param name="defaultMessageBus">
|
|
546
|
+
/// Preferred bus to use when registrations do not specify one. Falls back to
|
|
547
|
+
/// <see cref="MessageBus"/> if omitted.
|
|
548
|
+
/// </param>
|
|
517
549
|
public MessageHandler(InstanceId owner, IMessageBus defaultMessageBus = null)
|
|
518
550
|
{
|
|
519
551
|
this.owner = owner;
|
|
@@ -1832,11 +1864,21 @@ namespace DxMessaging.Core
|
|
|
1832
1864
|
return messageBus.RegisterTargetedInterceptor(interceptor, priority);
|
|
1833
1865
|
}
|
|
1834
1866
|
|
|
1867
|
+
/// <summary>
|
|
1868
|
+
/// Checks equality against another object.
|
|
1869
|
+
/// </summary>
|
|
1870
|
+
/// <param name="obj">Object to compare.</param>
|
|
1871
|
+
/// <returns><c>true</c> when <paramref name="obj"/> is a <see cref="MessageHandler"/> with the same owner.</returns>
|
|
1835
1872
|
public override bool Equals(object obj)
|
|
1836
1873
|
{
|
|
1837
1874
|
return Equals(obj as MessageHandler);
|
|
1838
1875
|
}
|
|
1839
1876
|
|
|
1877
|
+
/// <summary>
|
|
1878
|
+
/// Checks equality against another handler instance.
|
|
1879
|
+
/// </summary>
|
|
1880
|
+
/// <param name="other">Handler to compare.</param>
|
|
1881
|
+
/// <returns><c>true</c> when both handlers share the same <see cref="owner"/>.</returns>
|
|
1840
1882
|
public bool Equals(MessageHandler other)
|
|
1841
1883
|
{
|
|
1842
1884
|
if (other == null)
|
|
@@ -1852,11 +1894,20 @@ namespace DxMessaging.Core
|
|
|
1852
1894
|
return owner.Equals(other.owner);
|
|
1853
1895
|
}
|
|
1854
1896
|
|
|
1897
|
+
/// <summary>
|
|
1898
|
+
/// Produces a hash code based on the owning instance.
|
|
1899
|
+
/// </summary>
|
|
1900
|
+
/// <returns>Hash code derived from <see cref="owner"/>.</returns>
|
|
1855
1901
|
public override int GetHashCode()
|
|
1856
1902
|
{
|
|
1857
1903
|
return owner.GetHashCode();
|
|
1858
1904
|
}
|
|
1859
1905
|
|
|
1906
|
+
/// <summary>
|
|
1907
|
+
/// Compares this handler with another handler for ordering.
|
|
1908
|
+
/// </summary>
|
|
1909
|
+
/// <param name="other">Handler to compare.</param>
|
|
1910
|
+
/// <returns>Relative ordering based on <see cref="owner"/>.</returns>
|
|
1860
1911
|
public int CompareTo(MessageHandler other)
|
|
1861
1912
|
{
|
|
1862
1913
|
if (other == null)
|
|
@@ -1867,11 +1918,22 @@ namespace DxMessaging.Core
|
|
|
1867
1918
|
return owner.CompareTo(other.owner);
|
|
1868
1919
|
}
|
|
1869
1920
|
|
|
1921
|
+
/// <summary>
|
|
1922
|
+
/// Compares this handler with an arbitrary object.
|
|
1923
|
+
/// </summary>
|
|
1924
|
+
/// <param name="obj">Object to compare.</param>
|
|
1925
|
+
/// <returns>
|
|
1926
|
+
/// Relative ordering when <paramref name="obj"/> is a <see cref="MessageHandler"/>; otherwise <c>-1</c>.
|
|
1927
|
+
/// </returns>
|
|
1870
1928
|
public int CompareTo(object obj)
|
|
1871
1929
|
{
|
|
1872
1930
|
return CompareTo(obj as MessageHandler);
|
|
1873
1931
|
}
|
|
1874
1932
|
|
|
1933
|
+
/// <summary>
|
|
1934
|
+
/// Returns a human-readable representation containing the owner identifier.
|
|
1935
|
+
/// </summary>
|
|
1936
|
+
/// <returns>String describing the handler.</returns>
|
|
1875
1937
|
public override string ToString()
|
|
1876
1938
|
{
|
|
1877
1939
|
return new { OwnerId = owner }.ToString();
|
|
@@ -1965,6 +2027,11 @@ namespace DxMessaging.Core
|
|
|
1965
2027
|
{
|
|
1966
2028
|
internal readonly struct Entry
|
|
1967
2029
|
{
|
|
2030
|
+
/// <summary>
|
|
2031
|
+
/// Initializes an entry used to track handler invocation counts.
|
|
2032
|
+
/// </summary>
|
|
2033
|
+
/// <param name="handler">Handler delegate being tracked.</param>
|
|
2034
|
+
/// <param name="count">Number of times the handler has been cached.</param>
|
|
1968
2035
|
public Entry(T handler, int count)
|
|
1969
2036
|
{
|
|
1970
2037
|
this.handler = handler;
|
|
@@ -2345,6 +2412,12 @@ namespace DxMessaging.Core
|
|
|
2345
2412
|
}
|
|
2346
2413
|
}
|
|
2347
2414
|
|
|
2415
|
+
/// <summary>
|
|
2416
|
+
/// Runs untargeted post-processing handlers for the supplied message.
|
|
2417
|
+
/// </summary>
|
|
2418
|
+
/// <param name="message">Message being processed.</param>
|
|
2419
|
+
/// <param name="priority">Priority bucket currently executing.</param>
|
|
2420
|
+
/// <param name="emissionId">Emission identifier used to cache handler stacks.</param>
|
|
2348
2421
|
public void HandleUntargetedPostProcessing(ref T message, int priority, long emissionId)
|
|
2349
2422
|
{
|
|
2350
2423
|
RunFastHandlers(
|
|
@@ -2356,6 +2429,13 @@ namespace DxMessaging.Core
|
|
|
2356
2429
|
RunHandlers(_untargetedPostProcessingHandlers, ref message, priority, emissionId);
|
|
2357
2430
|
}
|
|
2358
2431
|
|
|
2432
|
+
/// <summary>
|
|
2433
|
+
/// Runs targeted post-processing handlers for the supplied message and recipient.
|
|
2434
|
+
/// </summary>
|
|
2435
|
+
/// <param name="target">Recipient of the message.</param>
|
|
2436
|
+
/// <param name="message">Message being processed.</param>
|
|
2437
|
+
/// <param name="priority">Priority bucket currently executing.</param>
|
|
2438
|
+
/// <param name="emissionId">Emission identifier used to cache handler stacks.</param>
|
|
2359
2439
|
public void HandleTargetedPostProcessing(
|
|
2360
2440
|
ref InstanceId target,
|
|
2361
2441
|
ref T message,
|
|
@@ -2379,6 +2459,13 @@ namespace DxMessaging.Core
|
|
|
2379
2459
|
);
|
|
2380
2460
|
}
|
|
2381
2461
|
|
|
2462
|
+
/// <summary>
|
|
2463
|
+
/// Runs targeted post-processing handlers that do not require a <see cref="InstanceId"/> target binding.
|
|
2464
|
+
/// </summary>
|
|
2465
|
+
/// <param name="target">Recipient of the message.</param>
|
|
2466
|
+
/// <param name="message">Message being processed.</param>
|
|
2467
|
+
/// <param name="priority">Priority bucket currently executing.</param>
|
|
2468
|
+
/// <param name="emissionId">Emission identifier used to cache handler stacks.</param>
|
|
2382
2469
|
public void HandleTargetedWithoutTargetingPostProcessing(
|
|
2383
2470
|
ref InstanceId target,
|
|
2384
2471
|
ref T message,
|
|
@@ -2402,6 +2489,13 @@ namespace DxMessaging.Core
|
|
|
2402
2489
|
);
|
|
2403
2490
|
}
|
|
2404
2491
|
|
|
2492
|
+
/// <summary>
|
|
2493
|
+
/// Runs broadcast post-processing handlers that expect a concrete source identifier.
|
|
2494
|
+
/// </summary>
|
|
2495
|
+
/// <param name="source">Origin of the message.</param>
|
|
2496
|
+
/// <param name="message">Message being processed.</param>
|
|
2497
|
+
/// <param name="priority">Priority bucket currently executing.</param>
|
|
2498
|
+
/// <param name="emissionId">Emission identifier used to cache handler stacks.</param>
|
|
2405
2499
|
public void HandleSourcedBroadcastPostProcessing(
|
|
2406
2500
|
ref InstanceId source,
|
|
2407
2501
|
ref T message,
|
|
@@ -2425,6 +2519,13 @@ namespace DxMessaging.Core
|
|
|
2425
2519
|
);
|
|
2426
2520
|
}
|
|
2427
2521
|
|
|
2522
|
+
/// <summary>
|
|
2523
|
+
/// Runs broadcast post-processing handlers that do not rely on a specific source identifier.
|
|
2524
|
+
/// </summary>
|
|
2525
|
+
/// <param name="source">Origin of the message.</param>
|
|
2526
|
+
/// <param name="message">Message being processed.</param>
|
|
2527
|
+
/// <param name="priority">Priority bucket currently executing.</param>
|
|
2528
|
+
/// <param name="emissionId">Emission identifier used to cache handler stacks.</param>
|
|
2428
2529
|
public void HandleBroadcastWithoutSourcePostProcessing(
|
|
2429
2530
|
ref InstanceId source,
|
|
2430
2531
|
ref T message,
|
|
@@ -19,6 +19,21 @@ namespace DxMessaging.Core
|
|
|
19
19
|
private readonly long _id;
|
|
20
20
|
private readonly int _hashCode;
|
|
21
21
|
|
|
22
|
+
internal static long GetCurrentIdSeed()
|
|
23
|
+
{
|
|
24
|
+
return Interlocked.Read(ref StaticIdCount);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
internal static void SetIdSeed(long value)
|
|
28
|
+
{
|
|
29
|
+
_ = Interlocked.Exchange(ref StaticIdCount, value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
internal static void ResetIdSeed()
|
|
33
|
+
{
|
|
34
|
+
SetIdSeed(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
22
37
|
/// <summary>
|
|
23
38
|
/// Creates a new unique handle.
|
|
24
39
|
/// </summary>
|
|
@@ -49,6 +64,12 @@ namespace DxMessaging.Core
|
|
|
49
64
|
return !left.Equals(right);
|
|
50
65
|
}
|
|
51
66
|
|
|
67
|
+
/// <summary>
|
|
68
|
+
/// Determines whether the left handle sorts after the right handle.
|
|
69
|
+
/// </summary>
|
|
70
|
+
/// <param name="left">Left-hand handle.</param>
|
|
71
|
+
/// <param name="right">Right-hand handle.</param>
|
|
72
|
+
/// <returns><c>true</c> when <paramref name="left"/> sorts after <paramref name="right"/>.</returns>
|
|
52
73
|
public static bool operator >(
|
|
53
74
|
MessageRegistrationHandle left,
|
|
54
75
|
MessageRegistrationHandle right
|
|
@@ -57,6 +78,12 @@ namespace DxMessaging.Core
|
|
|
57
78
|
return left.CompareTo(right) > 0;
|
|
58
79
|
}
|
|
59
80
|
|
|
81
|
+
/// <summary>
|
|
82
|
+
/// Determines whether the left handle sorts before the right handle.
|
|
83
|
+
/// </summary>
|
|
84
|
+
/// <param name="left">Left-hand handle.</param>
|
|
85
|
+
/// <param name="right">Right-hand handle.</param>
|
|
86
|
+
/// <returns><c>true</c> when <paramref name="left"/> sorts before <paramref name="right"/>.</returns>
|
|
60
87
|
public static bool operator <(
|
|
61
88
|
MessageRegistrationHandle left,
|
|
62
89
|
MessageRegistrationHandle right
|
|
@@ -81,11 +108,23 @@ namespace DxMessaging.Core
|
|
|
81
108
|
return left.CompareTo(right) >= 0;
|
|
82
109
|
}
|
|
83
110
|
|
|
111
|
+
/// <summary>
|
|
112
|
+
/// Compares this handle with another handle for ordering.
|
|
113
|
+
/// </summary>
|
|
114
|
+
/// <param name="other">Other handle to compare with.</param>
|
|
115
|
+
/// <returns>Relative ordering as defined by <see cref="IComparable{T}.CompareTo(T)"/>.</returns>
|
|
84
116
|
public int CompareTo(MessageRegistrationHandle other)
|
|
85
117
|
{
|
|
86
118
|
return _id.CompareTo(other._id);
|
|
87
119
|
}
|
|
88
120
|
|
|
121
|
+
/// <summary>
|
|
122
|
+
/// Compares this handle with an arbitrary object.
|
|
123
|
+
/// </summary>
|
|
124
|
+
/// <param name="obj">Object to compare with.</param>
|
|
125
|
+
/// <returns>
|
|
126
|
+
/// Relative ordering when <paramref name="obj"/> is a <see cref="MessageRegistrationHandle"/>; otherwise <c>-1</c>.
|
|
127
|
+
/// </returns>
|
|
89
128
|
public int CompareTo(object obj)
|
|
90
129
|
{
|
|
91
130
|
if (obj is MessageRegistrationHandle handle)
|
|
@@ -96,21 +135,41 @@ namespace DxMessaging.Core
|
|
|
96
135
|
return -1;
|
|
97
136
|
}
|
|
98
137
|
|
|
138
|
+
/// <summary>
|
|
139
|
+
/// Checks equality against another object.
|
|
140
|
+
/// </summary>
|
|
141
|
+
/// <param name="other">Object to compare.</param>
|
|
142
|
+
/// <returns>
|
|
143
|
+
/// <c>true</c> when <paramref name="other"/> is a <see cref="MessageRegistrationHandle"/> representing the same registration.
|
|
144
|
+
/// </returns>
|
|
99
145
|
public override bool Equals(object other)
|
|
100
146
|
{
|
|
101
147
|
return other is MessageRegistrationHandle handle && Equals(handle);
|
|
102
148
|
}
|
|
103
149
|
|
|
150
|
+
/// <summary>
|
|
151
|
+
/// Checks equality against another handle.
|
|
152
|
+
/// </summary>
|
|
153
|
+
/// <param name="other">Handle to compare.</param>
|
|
154
|
+
/// <returns><c>true</c> when both handles represent the same registration.</returns>
|
|
104
155
|
public bool Equals(MessageRegistrationHandle other)
|
|
105
156
|
{
|
|
106
157
|
return _id == other._id;
|
|
107
158
|
}
|
|
108
159
|
|
|
160
|
+
/// <summary>
|
|
161
|
+
/// Produces a hash code suitable for dictionary or set lookups.
|
|
162
|
+
/// </summary>
|
|
163
|
+
/// <returns>Hash code derived from the internal identifier.</returns>
|
|
109
164
|
public override int GetHashCode()
|
|
110
165
|
{
|
|
111
166
|
return _hashCode;
|
|
112
167
|
}
|
|
113
168
|
|
|
169
|
+
/// <summary>
|
|
170
|
+
/// Returns a string representation of the handle, including the underlying identifier.
|
|
171
|
+
/// </summary>
|
|
172
|
+
/// <returns>Human-readable representation of the handle.</returns>
|
|
114
173
|
public override string ToString()
|
|
115
174
|
{
|
|
116
175
|
return new { Id = _id }.ToString();
|
|
@@ -39,7 +39,7 @@ namespace DxMessaging.Core
|
|
|
39
39
|
/// }
|
|
40
40
|
/// </code>
|
|
41
41
|
/// </example>
|
|
42
|
-
public sealed class MessageRegistrationToken
|
|
42
|
+
public sealed class MessageRegistrationToken : IDisposable
|
|
43
43
|
{
|
|
44
44
|
/// <summary>
|
|
45
45
|
/// Whether the token is currently enabled (registrations are active).
|
|
@@ -71,7 +71,7 @@ namespace DxMessaging.Core
|
|
|
71
71
|
|
|
72
72
|
private IMessageBus _messageBus;
|
|
73
73
|
private bool _enabled;
|
|
74
|
-
private bool _diagnosticMode = IMessageBus.
|
|
74
|
+
private bool _diagnosticMode = IMessageBus.ShouldEnableDiagnostics();
|
|
75
75
|
|
|
76
76
|
private MessageRegistrationToken(MessageHandler messageHandler, IMessageBus messageBus)
|
|
77
77
|
{
|
|
@@ -1995,6 +1995,11 @@ namespace DxMessaging.Core
|
|
|
1995
1995
|
private readonly MessageRegistrationHandle _handle;
|
|
1996
1996
|
private bool _valid;
|
|
1997
1997
|
|
|
1998
|
+
/// <summary>
|
|
1999
|
+
/// Creates a disposable wrapper that removes a registration when disposed.
|
|
2000
|
+
/// </summary>
|
|
2001
|
+
/// <param name="token">Token that owns the registration.</param>
|
|
2002
|
+
/// <param name="handle">Handle to remove when disposed.</param>
|
|
1998
2003
|
public RegistrationDisposable(
|
|
1999
2004
|
MessageRegistrationToken token,
|
|
2000
2005
|
MessageRegistrationHandle handle
|
|
@@ -2005,6 +2010,9 @@ namespace DxMessaging.Core
|
|
|
2005
2010
|
_valid = true;
|
|
2006
2011
|
}
|
|
2007
2012
|
|
|
2013
|
+
/// <summary>
|
|
2014
|
+
/// Removes the wrapped registration the first time it is invoked.
|
|
2015
|
+
/// </summary>
|
|
2008
2016
|
public void Dispose()
|
|
2009
2017
|
{
|
|
2010
2018
|
// Best-effort idempotence; AsDisposable instances are short-lived and immutable
|
|
@@ -2035,5 +2043,13 @@ namespace DxMessaging.Core
|
|
|
2035
2043
|
|
|
2036
2044
|
return new MessageRegistrationToken(messageHandler, messageBus);
|
|
2037
2045
|
}
|
|
2046
|
+
|
|
2047
|
+
/// <summary>
|
|
2048
|
+
/// Removes all staged registrations and releases references to the handler.
|
|
2049
|
+
/// </summary>
|
|
2050
|
+
public void Dispose()
|
|
2051
|
+
{
|
|
2052
|
+
UnregisterAll();
|
|
2053
|
+
}
|
|
2038
2054
|
}
|
|
2039
2055
|
}
|