com.wallstop-studios.dxmessaging 3.0.1 → 3.2.0

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 (148) hide show
  1. package/CHANGELOG.md +497 -2
  2. package/Editor/Analyzers/BaseCallLogMessageParser.cs.meta +3 -3
  3. package/Editor/Analyzers/BaseCallReportAggregator.cs.meta +3 -3
  4. package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +69 -62
  5. package/Editor/Analyzers/DxMessagingConsoleHarvester.cs.meta +3 -3
  6. package/Editor/AssemblyInfo.cs.meta +9 -1
  7. package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs.meta +3 -3
  8. package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +24 -15
  9. package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs.meta +3 -3
  10. package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +9 -1
  11. package/Editor/DxMessagingEditorIdle.cs +62 -0
  12. package/{Runtime/Core/Internal/TypedDispatchLinkIndex.cs.meta → Editor/DxMessagingEditorIdle.cs.meta} +1 -1
  13. package/Editor/DxMessagingEditorInitializer.cs +112 -15
  14. package/Editor/DxMessagingEditorInitializer.cs.meta +9 -1
  15. package/Editor/DxMessagingEditorLog.cs +32 -0
  16. package/Editor/DxMessagingEditorLog.cs.meta +11 -0
  17. package/Editor/DxMessagingMenu.cs.meta +3 -3
  18. package/Editor/DxMessagingSceneBuildProcessor.cs.meta +3 -3
  19. package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +137 -15
  20. package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs.meta +3 -3
  21. package/Editor/Settings/DxMessagingSettings.cs +92 -31
  22. package/Editor/Settings/DxMessagingSettings.cs.meta +9 -1
  23. package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +9 -1
  24. package/Editor/SetupCscRsp.cs +539 -304
  25. package/Editor/SetupCscRsp.cs.meta +9 -1
  26. package/Editor/Testing/MessagingComponentEditorHarness.cs +1 -1
  27. package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +9 -1
  28. package/README.md +17 -18
  29. package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
  30. package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll.meta +3 -3
  31. package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll.meta +3 -3
  32. package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll.meta +3 -3
  33. package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +3 -3
  34. package/Runtime/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
  35. package/Runtime/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +46 -0
  36. package/Runtime/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  37. package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +2 -2
  38. package/Runtime/Analyzers.meta +8 -0
  39. package/Runtime/AssemblyInfo.cs.meta +9 -1
  40. package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +9 -1
  41. package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +9 -1
  42. package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs.meta +3 -3
  43. package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +2 -4
  44. package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +9 -1
  45. package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +9 -1
  46. package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +9 -1
  47. package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs +56 -0
  48. package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs.meta +11 -0
  49. package/Runtime/Core/DataStructure/CyclicBuffer.cs +44 -26
  50. package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +9 -1
  51. package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +9 -1
  52. package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +9 -1
  53. package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +9 -1
  54. package/Runtime/Core/DxMessagingStaticState.cs.meta +3 -3
  55. package/Runtime/Core/Extensions/EnumExtensions.cs +6 -5
  56. package/Runtime/Core/Extensions/EnumExtensions.cs.meta +9 -1
  57. package/Runtime/Core/Extensions/IListExtensions.cs.meta +9 -1
  58. package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +3 -3
  59. package/Runtime/Core/Extensions/MessageExtensions.cs +0 -60
  60. package/Runtime/Core/Extensions/MessageExtensions.cs.meta +3 -3
  61. package/Runtime/Core/Helper/MessageCache.cs.meta +9 -1
  62. package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +9 -1
  63. package/Runtime/Core/IMessage.cs.meta +3 -3
  64. package/Runtime/Core/InstanceId.cs +25 -1
  65. package/Runtime/Core/InstanceId.cs.meta +3 -3
  66. package/Runtime/Core/Internal/DxUnsafe.cs +60 -0
  67. package/Runtime/Core/Internal/DxUnsafe.cs.meta +11 -0
  68. package/Runtime/Core/Internal/FlatDispatch.cs +198 -0
  69. package/Runtime/Core/Internal/FlatDispatch.cs.meta +11 -0
  70. package/Runtime/Core/Internal/TypedSlots.cs +47 -21
  71. package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +3 -3
  72. package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +3 -3
  73. package/Runtime/Core/MessageBus/IMessageBus.cs +75 -40
  74. package/Runtime/Core/MessageBus/IMessageBus.cs.meta +3 -3
  75. package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +3 -3
  76. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +1 -0
  77. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +3 -3
  78. package/Runtime/Core/MessageBus/Internal/BusSlots.cs +7 -6
  79. package/Runtime/Core/MessageBus/MessageBus.cs +2864 -3413
  80. package/Runtime/Core/MessageBus/MessageBus.cs.meta +3 -3
  81. package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +3 -3
  82. package/Runtime/Core/MessageBus/MessageBusRegistration.cs +207 -0
  83. package/Runtime/Core/MessageBus/MessageBusRegistration.cs.meta +11 -0
  84. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +187 -14
  85. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +3 -3
  86. package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +3 -3
  87. package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +3 -3
  88. package/Runtime/Core/MessageHandler.cs +2206 -1510
  89. package/Runtime/Core/MessageHandler.cs.meta +3 -3
  90. package/Runtime/Core/MessageRegistrationHandle.cs.meta +3 -3
  91. package/Runtime/Core/MessageRegistrationToken.cs +1667 -812
  92. package/Runtime/Core/MessageRegistrationToken.cs.meta +3 -3
  93. package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +9 -1
  94. package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +3 -3
  95. package/Runtime/Core/Messages/ITargetedMessage.cs.meta +3 -3
  96. package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +3 -3
  97. package/Runtime/Core/Messages/ReflexiveMessage.cs.meta +9 -1
  98. package/Runtime/Core/Messages/SourcedStringMessage.cs.meta +3 -3
  99. package/Runtime/Core/Messages/StringMessage.cs.meta +9 -1
  100. package/Runtime/Core/MessagingDebug.cs.meta +3 -3
  101. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +3 -3
  102. package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +3 -3
  103. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +3 -3
  104. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +9 -1
  105. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +3 -3
  106. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +9 -1
  107. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +3 -3
  108. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +9 -1
  109. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +3 -3
  110. package/Runtime/Unity/MessageAwareComponent.cs +46 -1
  111. package/Runtime/Unity/MessageAwareComponent.cs.meta +3 -3
  112. package/Runtime/Unity/MessageBusProviderHandle.cs.meta +3 -3
  113. package/Runtime/Unity/MessagingComponent.cs +43 -10
  114. package/Runtime/Unity/MessagingComponent.cs.meta +3 -3
  115. package/Runtime/Unity/MessagingComponentInstaller.cs.meta +3 -3
  116. package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +3 -3
  117. package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
  118. package/Samples~/DI/README.md +7 -7
  119. package/Samples~/DI/Reflex/SampleInstaller.cs.meta +3 -3
  120. package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +3 -3
  121. package/Samples~/DI/Zenject/SampleInstaller.cs.meta +3 -3
  122. package/Samples~/Mini Combat/Boot.cs.meta +3 -3
  123. package/Samples~/Mini Combat/Enemy.cs.meta +3 -3
  124. package/Samples~/Mini Combat/Messages.cs.meta +3 -3
  125. package/Samples~/Mini Combat/Player.cs.meta +3 -3
  126. package/Samples~/Mini Combat/UIOverlay.cs.meta +3 -3
  127. package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs.meta +3 -3
  128. package/Samples~/UI Buttons + Inspector/Messages.cs.meta +3 -3
  129. package/Samples~/UI Buttons + Inspector/MessagingObserver.cs.meta +3 -3
  130. package/Samples~/UI Buttons + Inspector/UIButtonEmitter.cs.meta +3 -3
  131. package/SourceGenerators/Directory.Build.props +50 -3
  132. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +96 -63
  133. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs.meta +3 -3
  134. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +745 -87
  135. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +9 -1
  136. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +40 -46
  137. package/SourceGenerators/global.json +7 -0
  138. package/SourceGenerators/global.json.meta +7 -0
  139. package/package.json +30 -40
  140. package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
  141. package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +0 -33
  142. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  143. package/Runtime/Core/Internal/TypedDispatchLinkIndex.cs +0 -51
  144. /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  145. /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
  146. /package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll +0 -0
  147. /package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll +0 -0
  148. /package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 58b2b780f9844aeb8929eeca855ba3be
3
- timeCreated: 1745161506
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: f9a83f6bf3c0487f9e5cff498dbb6932
3
- timeCreated: 1745161955
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: cf8206ca4c8449a8b8e112ad25554f1f
3
- timeCreated: 1745161457
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,7 +6,7 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
12
12
 
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,7 +6,7 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
12
12
 
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 978915f0cb9d43d99e46455ff38dc528
3
- timeCreated: 1761517485
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: c26d8cf1c99e45c0a847404d9a455ed1
3
- timeCreated: 1761517479
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: ec21f9c7970043fe88177114708ef79e
3
- timeCreated: 1761517466
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -19,6 +19,8 @@ namespace DxMessaging.Unity
19
19
  /// - <see cref="Awake"/> creates the token and calls <see cref="RegisterMessageHandlers"/>.
20
20
  /// - <see cref="OnEnable"/>/<see cref="OnDisable"/> enable/disable the token when
21
21
  /// <see cref="MessageRegistrationTiedToEnableStatus"/> is true.
22
+ /// - <see cref="OnEnable"/> can additionally re-create a released token when
23
+ /// <see cref="ReregisterOnEnableAfterRelease"/> is overridden to true.
22
24
  /// - <see cref="OnDestroy"/> disables the token and releases references.
23
25
  /// </remarks>
24
26
  /// <example>
@@ -61,6 +63,25 @@ namespace DxMessaging.Unity
61
63
  /// </summary>
62
64
  protected virtual bool MessageRegistrationTiedToEnableStatus => true;
63
65
 
66
+ /// <summary>
67
+ /// Controls whether enabling this component re-creates its registration token and replays
68
+ /// <see cref="RegisterMessageHandlers"/> after the token was released (for example via
69
+ /// <see cref="MessagingComponent.Release"/>).
70
+ /// </summary>
71
+ /// <remarks>
72
+ /// Default <c>false</c>: once released, the component stays unregistered across
73
+ /// enable/disable cycles until <see cref="MessagingComponent.Create"/> is invoked manually.
74
+ /// Override to return <c>true</c> to opt into automatic recovery on the next enable:
75
+ /// if no live token exists, a fresh one is created and <see cref="RegisterMessageHandlers"/>
76
+ /// replays exactly once; if a manual <see cref="MessagingComponent.Create"/> already minted
77
+ /// a fresh token since the release, that token is adopted as-is (the manual creator owns
78
+ /// staging, so nothing is replayed and nothing double-stages).
79
+ /// When <see cref="MessageRegistrationTiedToEnableStatus"/> is false, the recovery still
80
+ /// re-creates and stages but does NOT enable the new token; call
81
+ /// <see cref="MessageRegistrationToken.Enable"/> yourself, exactly as for the original token.
82
+ /// </remarks>
83
+ protected virtual bool ReregisterOnEnableAfterRelease => false;
84
+
64
85
  /// <summary>
65
86
  /// If true, registers demo handlers for <see cref="Core.Messages.StringMessage"/> and
66
87
  /// <see cref="Core.Messages.GlobalStringMessage"/>. Override and return <c>false</c> to disable.
@@ -138,9 +159,33 @@ namespace DxMessaging.Unity
138
159
 
139
160
  /// <summary>
140
161
  /// Enables the token if <see cref="MessageRegistrationTiedToEnableStatus"/> is true.
162
+ /// When <see cref="ReregisterOnEnableAfterRelease"/> is true and the token was released,
163
+ /// a fresh token is created and <see cref="RegisterMessageHandlers"/> replays first.
141
164
  /// </summary>
142
165
  protected virtual void OnEnable()
143
166
  {
167
+ if (
168
+ ReregisterOnEnableAfterRelease
169
+ && _messageRegistrationToken != null
170
+ && _messagingComponent != null
171
+ )
172
+ {
173
+ if (_messagingComponent.TryGetToken(this, out MessageRegistrationToken liveToken))
174
+ {
175
+ // A manual MessagingComponent.Create(this) between the release and
176
+ // this enable minted a fresh token the field does not know about;
177
+ // adopt it so Token/Enable() operate on the live registration. The
178
+ // manual creator owns staging in that case, so RegisterMessageHandlers
179
+ // is NOT replayed here (no double-staging).
180
+ _messageRegistrationToken = liveToken;
181
+ }
182
+ else
183
+ {
184
+ _messageRegistrationToken = _messagingComponent.Create(this);
185
+ RegisterMessageHandlers();
186
+ }
187
+ }
188
+
144
189
  if (MessageRegistrationTiedToEnableStatus)
145
190
  {
146
191
  _messageRegistrationToken?.Enable();
@@ -159,7 +204,7 @@ namespace DxMessaging.Unity
159
204
  Debug.LogError(
160
205
  $"[DxMessaging] {GetType().Name} appears to be missing a base.Awake() call; "
161
206
  + "no registration token exists, so this component will not receive messages. "
162
- + "See https://github.com/wallstop/DxMessaging/blob/master/docs/reference/analyzers.md#dxmsg006-missing-base-call",
207
+ + "See https://github.com/Ambiguous-Interactive/DxMessaging/blob/master/docs/reference/analyzers.md#dxmsg006-missing-base-call",
163
208
  this
164
209
  );
165
210
  }
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,7 +6,7 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
12
12
 
@@ -185,8 +185,9 @@ namespace DxMessaging.Unity
185
185
  /// </summary>
186
186
  /// <param name="listener">Listener whose token should be released.</param>
187
187
  /// <remarks>
188
- /// Invokes <see cref="MessageRegistrationToken.Disable"/> and removes the listener from the internal cache.
189
- /// Safe to call multiple times.
188
+ /// Invokes <see cref="MessageRegistrationToken.Dispose"/> and removes the listener from the internal cache after
189
+ /// disposal succeeds. If token disposal throws, the listener remains cached so release can be retried. Safe to call
190
+ /// multiple times after a successful release.
190
191
  /// </remarks>
191
192
  public bool Release(MonoBehaviour listener)
192
193
  {
@@ -195,9 +196,10 @@ namespace DxMessaging.Unity
195
196
  return false;
196
197
  }
197
198
 
198
- if (_registeredListeners.Remove(listener, out MessageRegistrationToken token))
199
+ if (_registeredListeners.TryGetValue(listener, out MessageRegistrationToken token))
199
200
  {
200
- token?.Disable();
201
+ token?.Dispose();
202
+ _ = _registeredListeners.Remove(listener);
201
203
  return true;
202
204
  }
203
205
 
@@ -225,34 +227,65 @@ namespace DxMessaging.Unity
225
227
  /// <summary>
226
228
  /// Activates the underlying handler when this component becomes enabled.
227
229
  /// </summary>
230
+ /// <remarks>
231
+ /// When <see cref="emitMessagesWhenDisabled"/> is true, the Unity enable/disable
232
+ /// lifecycle leaves the handler untouched in BOTH directions, so an explicit
233
+ /// <see cref="ToggleMessageHandler"/> decision survives enable/disable cycles.
234
+ /// </remarks>
228
235
  public void OnEnable()
229
236
  {
230
- ToggleMessageHandler(true);
237
+ if (!emitMessagesWhenDisabled)
238
+ {
239
+ ToggleMessageHandler(true);
240
+ }
231
241
  }
232
242
 
233
243
  /// <summary>
234
244
  /// Deactivates the underlying handler when this component becomes disabled.
235
245
  /// </summary>
246
+ /// <remarks>
247
+ /// When <see cref="emitMessagesWhenDisabled"/> is true, disabling leaves the handler
248
+ /// active so the GameObject keeps emitting (and listeners whose tokens are not tied to
249
+ /// the Unity lifecycle keep receiving).
250
+ /// </remarks>
236
251
  public void OnDisable()
237
252
  {
238
- ToggleMessageHandler(false);
253
+ if (!emitMessagesWhenDisabled)
254
+ {
255
+ ToggleMessageHandler(false);
256
+ }
239
257
  }
240
258
 
241
259
  /// <summary>
242
260
  /// Explicitly toggle the underlying handler's active state.
243
261
  /// </summary>
244
262
  /// <param name="newActive">Desired active state.</param>
263
+ /// <remarks>
264
+ /// Explicit calls always win: unlike the Unity lifecycle, this method is never gated by
265
+ /// <see cref="emitMessagesWhenDisabled"/>.
266
+ /// </remarks>
245
267
  public void ToggleMessageHandler(bool newActive)
246
268
  {
247
- if (!newActive && emitMessagesWhenDisabled)
269
+ if (_messageHandler != null && _messageHandler.active != newActive)
248
270
  {
249
- return;
271
+ _messageHandler.active = newActive;
250
272
  }
273
+ }
251
274
 
252
- if (_messageHandler != null && _messageHandler.active != newActive)
275
+ /// <summary>
276
+ /// Fetches the live (created and not released) registration token for
277
+ /// <paramref name="listener"/> without the double-create warning
278
+ /// <see cref="Create(MonoBehaviour)"/> logs.
279
+ /// </summary>
280
+ internal bool TryGetToken(MonoBehaviour listener, out MessageRegistrationToken token)
281
+ {
282
+ if (listener == null)
253
283
  {
254
- _messageHandler.active = newActive;
284
+ token = null;
285
+ return false;
255
286
  }
287
+
288
+ return _registeredListeners.TryGetValue(listener, out token);
256
289
  }
257
290
 
258
291
  /// <summary>
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,7 +6,7 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
12
12
 
@@ -6,7 +6,7 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
12
12
 
@@ -6,7 +6,7 @@
6
6
  "excludePlatforms": [],
7
7
  "allowUnsafeCode": true,
8
8
  "overrideReferences": false,
9
- "precompiledReferences": ["System.Runtime.CompilerServices.Unsafe.dll"],
9
+ "precompiledReferences": [],
10
10
  "autoReferenced": true,
11
11
  "defineConstraints": [],
12
12
  "versionDefines": [],
@@ -31,15 +31,15 @@ Each sample shows:
31
31
  1. **Place the prefab**
32
32
  Drag `Prefabs/MessagingInstallerSample.prefab` into your test scene. The root object carries `MessagingComponentInstaller` with its provider handle already pointing at the global provider ScriptableObject.
33
33
 
34
- 1. **Hook up the container**
35
- - **Zenject**:
36
- - Add `DxMessagingRegistrationInstaller` (from [Runtime/Unity/Integrations](../../Runtime/Unity/Integrations/)) to your ProjectContext or scene installer list.
34
+ 1. **Hook up the container**
35
+ - **Zenject**:
36
+ - Add `DxMessagingRegistrationInstaller` (from [Runtime/Unity/Integrations](../../Runtime/Unity/Integrations/)) to your ProjectContext or scene installer list.
37
37
  - Drop [SampleInstaller.cs](./Zenject/SampleInstaller.cs) into your project and register it alongside other installers. When the scene runs, the installer resolves `IMessageRegistrationBuilder`, stages a `PlayerSpawned` listener, and activates via the Zenject lifecycle.
38
- - **VContainer**:
39
- - Define `VCONTAINER_PRESENT` and reference the optional extension under [VContainerRegistrationExtensions.cs](../../Runtime/Unity/Integrations/VContainerRegistrationExtensions.cs).
38
+ - **VContainer**:
39
+ - Define `VCONTAINER_PRESENT` and reference the optional extension under [VContainerRegistrationExtensions.cs](../../Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs).
40
40
  - Add [SampleLifetimeScope.cs](./VContainer/SampleLifetimeScope.cs) to the scene (or derive from it); the sample scope registers the builder and an entry point that emits/consumes `ScoreUpdated` messages each tick.
41
- - **Reflex**:
42
- - Enable `REFLEX_PRESENT` and install `DxMessagingRegistrationInstaller` into your container bootstrap.
41
+ - **Reflex**:
42
+ - Enable `REFLEX_PRESENT` and install `DxMessagingRegistrationInstaller` into your container bootstrap.
43
43
  - Include [SampleInstaller.cs](./Reflex/SampleInstaller.cs) in your installer chain. The sample service resolves `IMessageRegistrationBuilder`, subscribes to `PlayerAlert`, and can emit alerts via `EmitAlertFor`.
44
44
 
45
45
  1. **Emit a message**
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -6,6 +6,6 @@ MonoImporter:
6
6
  defaultReferences: []
7
7
  executionOrder: 0
8
8
  icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant:
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: