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.
Files changed (60) hide show
  1. package/.github/workflows/dotnet-tests.yml +1 -1
  2. package/AGENTS.md +12 -12
  3. package/Docs/Comparisons.md +5 -5
  4. package/Docs/InterceptorsAndOrdering.md +1 -1
  5. package/Docs/Performance.md +13 -13
  6. package/Docs/QuickReference.md +1 -1
  7. package/Docs/Reference.md +5 -5
  8. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  9. package/Editor/CustomEditors/MessagingComponentEditor.cs +3 -0
  10. package/Editor/DxMessagingEditorInitializer.cs +58 -1
  11. package/Editor/DxMessagingMenu.cs +38 -0
  12. package/Editor/DxMessagingMenu.cs.meta +11 -0
  13. package/Editor/DxMessagingSceneBuildProcessor.cs +81 -0
  14. package/Editor/DxMessagingSceneBuildProcessor.cs.meta +11 -0
  15. package/Editor/Settings/DxMessagingSettings.cs +37 -6
  16. package/Editor/Settings/DxMessagingSettingsProvider.cs +45 -7
  17. package/README.md +1 -1
  18. package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +52 -0
  19. package/Runtime/Core/DataStructure/CyclicBuffer.cs +16 -0
  20. package/Runtime/Core/Diagnostics/MessageEmissionData.cs +1 -1
  21. package/Runtime/Core/Diagnostics/MessageRegistrationType.cs +62 -0
  22. package/Runtime/Core/DxMessagingStaticState.cs +108 -0
  23. package/Runtime/Core/DxMessagingStaticState.cs.meta +11 -0
  24. package/Runtime/Core/Extensions/IListExtensions.cs +24 -0
  25. package/Runtime/Core/Extensions/MessageBusExtensions.cs +142 -0
  26. package/Runtime/Core/Helper/MessageCache.cs +16 -0
  27. package/Runtime/Core/Helper/MessageHelperIndexer.cs +77 -0
  28. package/Runtime/Core/InstanceId.cs +86 -0
  29. package/Runtime/Core/MessageBus/DiagnosticsTarget.cs +31 -0
  30. package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +11 -0
  31. package/Runtime/Core/MessageBus/IMessageBus.cs +44 -16
  32. package/Runtime/Core/MessageBus/MessageBus.cs +92 -21
  33. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +44 -0
  34. package/Runtime/Core/MessageBus/MessagingRegistration.cs +60 -2
  35. package/Runtime/Core/MessageBus/RegistrationLog.cs +10 -0
  36. package/Runtime/Core/MessageHandler.cs +107 -6
  37. package/Runtime/Core/MessageRegistrationHandle.cs +59 -0
  38. package/Runtime/Core/MessageRegistrationToken.cs +18 -2
  39. package/Runtime/Core/Messages/ReflexiveMessage.cs +38 -0
  40. package/Runtime/Core/MessagingDebug.cs +16 -1
  41. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +4 -0
  42. package/Runtime/Unity/DxMessagingRuntimeInitializer.cs +19 -0
  43. package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +11 -0
  44. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +4 -0
  45. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +17 -0
  46. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +8 -0
  47. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +12 -0
  48. package/Runtime/Unity/MessagingComponent.cs +93 -0
  49. package/Samples~/DI/README.md +13 -13
  50. package/Samples~/Mini Combat/README.md +15 -15
  51. package/Samples~/Mini Combat/Walkthrough.md +12 -12
  52. package/Samples~/UI Buttons + Inspector/README.md +4 -4
  53. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +4 -0
  54. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +4 -0
  55. package/Tests/Runtime/Core/DiagnosticsTests.cs +3 -3
  56. package/Tests/Runtime/Core/DxMessagingStaticStateTests.cs +69 -0
  57. package/Tests/Runtime/Core/DxMessagingStaticStateTests.cs.meta +11 -0
  58. package/package.json +1 -1
  59. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +0 -20
  60. 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 readonly MessageBus.MessageBus _defaultGlobalMessageBus = new();
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 original global <see cref="IMessageBus"/> instance created during static initialisation.
368
+ /// Gets the baseline global <see cref="IMessageBus"/> instance used when no custom bus is configured.
367
369
  /// </summary>
368
370
  /// <remarks>
369
- /// This reference never changes even when <see cref="SetGlobalMessageBus(IMessageBus)"/> is invoked.
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
- _globalMessageBus = _defaultGlobalMessageBus;
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 created during static initialisation and reused across resets to minimise allocations.
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
- _globalMessageBus = _defaultGlobalMessageBus;
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.GlobalDiagnosticsMode;
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
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 6e7f0de58bcf4f64813ef3650910c653
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -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>();