com.wallstop-studios.dxmessaging 2.1.2 → 2.1.3
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 +1 -1
- package/AGENTS.md +12 -12
- 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 +92 -21
- 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/package.json +1 -1
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +0 -20
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj.meta +0 -7
|
@@ -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
|
}
|
|
@@ -17,10 +17,29 @@ namespace DxMessaging.Core.Messages
|
|
|
17
17
|
public enum ReflexiveSendMode
|
|
18
18
|
{
|
|
19
19
|
[Obsolete("Please use a valid Send Mode")]
|
|
20
|
+
/// <summary>
|
|
21
|
+
/// Legacy sentinel indicating no traversal; not supported.
|
|
22
|
+
/// </summary>
|
|
20
23
|
None = 0,
|
|
24
|
+
|
|
25
|
+
/// <summary>
|
|
26
|
+
/// Invoke matching methods only on the immediate GameObject.
|
|
27
|
+
/// </summary>
|
|
21
28
|
Flat = 1 << 0,
|
|
29
|
+
|
|
30
|
+
/// <summary>
|
|
31
|
+
/// Traverse into child GameObjects when invoking methods.
|
|
32
|
+
/// </summary>
|
|
22
33
|
Downwards = 1 << 1,
|
|
34
|
+
|
|
35
|
+
/// <summary>
|
|
36
|
+
/// Traverse up the parent chain when invoking methods.
|
|
37
|
+
/// </summary>
|
|
23
38
|
Upwards = 1 << 2,
|
|
39
|
+
|
|
40
|
+
/// <summary>
|
|
41
|
+
/// Skip disabled components during traversal.
|
|
42
|
+
/// </summary>
|
|
24
43
|
OnlyIncludeActive = 1 << 3,
|
|
25
44
|
}
|
|
26
45
|
|
|
@@ -34,6 +53,11 @@ namespace DxMessaging.Core.Messages
|
|
|
34
53
|
|
|
35
54
|
private readonly int _hashCode;
|
|
36
55
|
|
|
56
|
+
/// <summary>
|
|
57
|
+
/// Creates a lookup key for a reflected method signature.
|
|
58
|
+
/// </summary>
|
|
59
|
+
/// <param name="methodName">Name of the method.</param>
|
|
60
|
+
/// <param name="parameterTypes">Ordered parameter list expected by the method.</param>
|
|
37
61
|
public MethodSignatureKey(string methodName, Type[] parameterTypes)
|
|
38
62
|
: this()
|
|
39
63
|
{
|
|
@@ -54,16 +78,30 @@ namespace DxMessaging.Core.Messages
|
|
|
54
78
|
return hashCode;
|
|
55
79
|
}
|
|
56
80
|
|
|
81
|
+
/// <summary>
|
|
82
|
+
/// Gets a stable hash code for the method signature.
|
|
83
|
+
/// </summary>
|
|
84
|
+
/// <returns>Hash code derived from the name and parameter types.</returns>
|
|
57
85
|
public override int GetHashCode()
|
|
58
86
|
{
|
|
59
87
|
return _hashCode;
|
|
60
88
|
}
|
|
61
89
|
|
|
90
|
+
/// <summary>
|
|
91
|
+
/// Checks equality against an arbitrary object.
|
|
92
|
+
/// </summary>
|
|
93
|
+
/// <param name="obj">Object to compare.</param>
|
|
94
|
+
/// <returns><c>true</c> when <paramref name="obj"/> represents the same signature.</returns>
|
|
62
95
|
public override bool Equals(object obj)
|
|
63
96
|
{
|
|
64
97
|
return obj is MethodSignatureKey other && Equals(other);
|
|
65
98
|
}
|
|
66
99
|
|
|
100
|
+
/// <summary>
|
|
101
|
+
/// Checks equality against another method signature key.
|
|
102
|
+
/// </summary>
|
|
103
|
+
/// <param name="other">Signature key to compare with.</param>
|
|
104
|
+
/// <returns><c>true</c> when both keys describe the same method.</returns>
|
|
67
105
|
public bool Equals(MethodSignatureKey other)
|
|
68
106
|
{
|
|
69
107
|
if (
|
|
@@ -3,13 +3,28 @@ namespace DxMessaging.Core
|
|
|
3
3
|
using System;
|
|
4
4
|
|
|
5
5
|
/// <summary>
|
|
6
|
-
/// Severity of the log message
|
|
6
|
+
/// Severity of the log message.
|
|
7
7
|
/// </summary>
|
|
8
8
|
public enum LogLevel
|
|
9
9
|
{
|
|
10
|
+
/// <summary>
|
|
11
|
+
/// Verbose diagnostic information useful while developing or debugging.
|
|
12
|
+
/// </summary>
|
|
10
13
|
Debug = 0,
|
|
14
|
+
|
|
15
|
+
/// <summary>
|
|
16
|
+
/// Informational messages that describe normal operation.
|
|
17
|
+
/// </summary>
|
|
11
18
|
Info = 1,
|
|
19
|
+
|
|
20
|
+
/// <summary>
|
|
21
|
+
/// Non-fatal issues that should be investigated.
|
|
22
|
+
/// </summary>
|
|
12
23
|
Warn = 2,
|
|
24
|
+
|
|
25
|
+
/// <summary>
|
|
26
|
+
/// Errors indicating messaging failed or data may be lost.
|
|
27
|
+
/// </summary>
|
|
13
28
|
Error = 3,
|
|
14
29
|
}
|
|
15
30
|
|
|
@@ -24,6 +24,10 @@ namespace DxMessaging.Unity
|
|
|
24
24
|
)]
|
|
25
25
|
public sealed class CurrentGlobalMessageBusProvider : ScriptableMessageBusProvider
|
|
26
26
|
{
|
|
27
|
+
/// <summary>
|
|
28
|
+
/// Resolves the message bus currently set as the global bus via <see cref="MessageHandler.SetGlobalMessageBus(IMessageBus)"/>.
|
|
29
|
+
/// </summary>
|
|
30
|
+
/// <returns>The active global <see cref="IMessageBus"/> instance.</returns>
|
|
27
31
|
public override IMessageBus Resolve()
|
|
28
32
|
{
|
|
29
33
|
return MessageHandler.MessageBus;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#if UNITY_2021_3_OR_NEWER
|
|
2
|
+
namespace DxMessaging.Unity
|
|
3
|
+
{
|
|
4
|
+
using Core;
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Unity-specific hook that resets DxMessaging static state when domain reloads are skipped.
|
|
9
|
+
/// </summary>
|
|
10
|
+
internal static class DxMessagingRuntimeInitializer
|
|
11
|
+
{
|
|
12
|
+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
13
|
+
private static void ResetStatics()
|
|
14
|
+
{
|
|
15
|
+
DxMessagingStaticState.Reset();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
#endif
|
|
@@ -31,6 +31,10 @@ namespace DxMessaging.Unity
|
|
|
31
31
|
)]
|
|
32
32
|
public sealed class InitialGlobalMessageBusProvider : ScriptableMessageBusProvider
|
|
33
33
|
{
|
|
34
|
+
/// <summary>
|
|
35
|
+
/// Resolves the message bus captured during static initialization before any runtime overrides occur.
|
|
36
|
+
/// </summary>
|
|
37
|
+
/// <returns>The initial global <see cref="IMessageBus"/> instance.</returns>
|
|
34
38
|
public override IMessageBus Resolve()
|
|
35
39
|
{
|
|
36
40
|
return MessageHandler.InitialGlobalMessageBus;
|
|
@@ -11,6 +11,10 @@ namespace DxMessaging.Unity.Integrations.Reflex
|
|
|
11
11
|
/// </summary>
|
|
12
12
|
public sealed class DxMessagingRegistrationInstaller : IInstaller
|
|
13
13
|
{
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Registers the DxMessaging builder services within the Reflex container.
|
|
16
|
+
/// </summary>
|
|
17
|
+
/// <param name="containerBuilder">Container builder receiving the registrations.</param>
|
|
14
18
|
public void InstallBindings(ContainerBuilder containerBuilder)
|
|
15
19
|
{
|
|
16
20
|
containerBuilder.AddSingleton(
|
|
@@ -25,6 +29,11 @@ namespace DxMessaging.Unity.Integrations.Reflex
|
|
|
25
29
|
[Inject]
|
|
26
30
|
private Container _container;
|
|
27
31
|
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// Builds a leasing wrapper using the container-aware provider resolution logic.
|
|
34
|
+
/// </summary>
|
|
35
|
+
/// <param name="options">Build options provided by the caller.</param>
|
|
36
|
+
/// <returns>Lease produced by the underlying <see cref="MessageRegistrationBuilder"/>.</returns>
|
|
28
37
|
public MessageRegistrationLease Build(MessageRegistrationBuildOptions options)
|
|
29
38
|
{
|
|
30
39
|
MessageRegistrationBuilder innerBuilder = ResolveInnerBuilder();
|
|
@@ -59,11 +68,19 @@ namespace DxMessaging.Unity.Integrations.Reflex
|
|
|
59
68
|
{
|
|
60
69
|
private readonly Container _container;
|
|
61
70
|
|
|
71
|
+
/// <summary>
|
|
72
|
+
/// Wraps a Reflex container as an <see cref="IMessageBusProvider"/>.
|
|
73
|
+
/// </summary>
|
|
74
|
+
/// <param name="container">Container used to resolve <see cref="IMessageBus"/> instances.</param>
|
|
62
75
|
public ContainerMessageBusProvider(Container container)
|
|
63
76
|
{
|
|
64
77
|
_container = container;
|
|
65
78
|
}
|
|
66
79
|
|
|
80
|
+
/// <summary>
|
|
81
|
+
/// Resolves an <see cref="IMessageBus"/> from the underlying container.
|
|
82
|
+
/// </summary>
|
|
83
|
+
/// <returns>Message bus resolved from Reflex.</returns>
|
|
67
84
|
public IMessageBus Resolve()
|
|
68
85
|
{
|
|
69
86
|
return _container.Resolve<IMessageBus>();
|
|
@@ -32,11 +32,19 @@ namespace DxMessaging.Unity.Integrations.VContainer
|
|
|
32
32
|
{
|
|
33
33
|
private readonly IObjectResolver _resolver;
|
|
34
34
|
|
|
35
|
+
/// <summary>
|
|
36
|
+
/// Wraps a VContainer resolver as an <see cref="IMessageBusProvider"/>.
|
|
37
|
+
/// </summary>
|
|
38
|
+
/// <param name="resolver">Resolver used to obtain <see cref="IMessageBus"/> instances.</param>
|
|
35
39
|
public ResolverMessageBusProvider(IObjectResolver resolver)
|
|
36
40
|
{
|
|
37
41
|
_resolver = resolver;
|
|
38
42
|
}
|
|
39
43
|
|
|
44
|
+
/// <summary>
|
|
45
|
+
/// Resolves an <see cref="IMessageBus"/> from the current VContainer scope.
|
|
46
|
+
/// </summary>
|
|
47
|
+
/// <returns>Scoped message bus.</returns>
|
|
40
48
|
public IMessageBus Resolve()
|
|
41
49
|
{
|
|
42
50
|
return _resolver.Resolve<IMessageBus>();
|
|
@@ -16,6 +16,9 @@ namespace DxMessaging.Unity.Integrations.Zenject
|
|
|
16
16
|
InstallBindings();
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/// <summary>
|
|
20
|
+
/// Registers the DxMessaging builder within the Zenject container.
|
|
21
|
+
/// </summary>
|
|
19
22
|
public override void InstallBindings()
|
|
20
23
|
{
|
|
21
24
|
Container.Bind<IMessageRegistrationBuilder>().FromMethod(CreateBuilder).AsTransient();
|
|
@@ -40,12 +43,21 @@ namespace DxMessaging.Unity.Integrations.Zenject
|
|
|
40
43
|
private readonly DiContainer _container;
|
|
41
44
|
private readonly IMessageBus _cachedBus;
|
|
42
45
|
|
|
46
|
+
/// <summary>
|
|
47
|
+
/// Creates a provider that uses the container-supplied bus, falling back to resolving on demand.
|
|
48
|
+
/// </summary>
|
|
49
|
+
/// <param name="container">Zenject container used to resolve services.</param>
|
|
50
|
+
/// <param name="cachedBus">Cached bus instance to return if available.</param>
|
|
43
51
|
public ContainerMessageBusProvider(DiContainer container, IMessageBus cachedBus)
|
|
44
52
|
{
|
|
45
53
|
_container = container;
|
|
46
54
|
_cachedBus = cachedBus;
|
|
47
55
|
}
|
|
48
56
|
|
|
57
|
+
/// <summary>
|
|
58
|
+
/// Resolves the message bus for the current scope.
|
|
59
|
+
/// </summary>
|
|
60
|
+
/// <returns>Cached bus if provided; otherwise resolves from the container.</returns>
|
|
49
61
|
public IMessageBus Resolve()
|
|
50
62
|
{
|
|
51
63
|
return _cachedBus ?? _container.Resolve<IMessageBus>();
|