com.wallstop-studios.dxmessaging 3.0.1 → 3.1.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 (81) hide show
  1. package/CHANGELOG.md +211 -2
  2. package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +69 -62
  3. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
  4. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +3 -3
  5. package/Editor/Analyzers/System.Collections.Immutable.dll.meta +3 -3
  6. package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +3 -3
  7. package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +3 -3
  8. package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
  9. package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +15 -2
  10. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  11. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +2 -2
  12. package/Editor/AssemblyInfo.cs.meta +9 -1
  13. package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +24 -15
  14. package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +9 -1
  15. package/Editor/DxMessagingEditorIdle.cs +62 -0
  16. package/{Runtime/Core/Internal/TypedDispatchLinkIndex.cs.meta → Editor/DxMessagingEditorIdle.cs.meta} +1 -1
  17. package/Editor/DxMessagingEditorInitializer.cs +112 -15
  18. package/Editor/DxMessagingEditorInitializer.cs.meta +9 -1
  19. package/Editor/DxMessagingEditorLog.cs +32 -0
  20. package/Editor/DxMessagingEditorLog.cs.meta +11 -0
  21. package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +135 -12
  22. package/Editor/Settings/DxMessagingSettings.cs +92 -31
  23. package/Editor/Settings/DxMessagingSettings.cs.meta +9 -1
  24. package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +9 -1
  25. package/Editor/SetupCscRsp.cs +339 -173
  26. package/Editor/SetupCscRsp.cs.meta +9 -1
  27. package/Editor/Testing/MessagingComponentEditorHarness.cs +1 -1
  28. package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +9 -1
  29. package/README.md +17 -18
  30. package/Runtime/AssemblyInfo.cs.meta +9 -1
  31. package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +9 -1
  32. package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +9 -1
  33. package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +2 -4
  34. package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +9 -1
  35. package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +9 -1
  36. package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +9 -1
  37. package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs +56 -0
  38. package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs.meta +11 -0
  39. package/Runtime/Core/DataStructure/CyclicBuffer.cs +44 -26
  40. package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +9 -1
  41. package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +9 -1
  42. package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +9 -1
  43. package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +9 -1
  44. package/Runtime/Core/Extensions/EnumExtensions.cs +6 -5
  45. package/Runtime/Core/Extensions/EnumExtensions.cs.meta +9 -1
  46. package/Runtime/Core/Extensions/IListExtensions.cs.meta +9 -1
  47. package/Runtime/Core/Extensions/MessageExtensions.cs +0 -60
  48. package/Runtime/Core/Helper/MessageCache.cs.meta +9 -1
  49. package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +9 -1
  50. package/Runtime/Core/InstanceId.cs +25 -1
  51. package/Runtime/Core/Internal/DxUnsafe.cs +60 -0
  52. package/Runtime/Core/Internal/DxUnsafe.cs.meta +11 -0
  53. package/Runtime/Core/Internal/FlatDispatch.cs +198 -0
  54. package/Runtime/Core/Internal/FlatDispatch.cs.meta +11 -0
  55. package/Runtime/Core/Internal/TypedSlots.cs +5 -21
  56. package/Runtime/Core/MessageBus/IMessageBus.cs +12 -12
  57. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +1 -0
  58. package/Runtime/Core/MessageBus/Internal/BusSlots.cs +7 -6
  59. package/Runtime/Core/MessageBus/MessageBus.cs +2313 -2936
  60. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +187 -14
  61. package/Runtime/Core/MessageHandler.cs +1023 -1143
  62. package/Runtime/Core/MessageRegistrationToken.cs +425 -47
  63. package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +9 -1
  64. package/Runtime/Core/Messages/ReflexiveMessage.cs.meta +9 -1
  65. package/Runtime/Core/Messages/StringMessage.cs.meta +9 -1
  66. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +9 -1
  67. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +9 -1
  68. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +9 -1
  69. package/Runtime/Unity/MessageAwareComponent.cs +46 -1
  70. package/Runtime/Unity/MessagingComponent.cs +43 -10
  71. package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
  72. package/Samples~/DI/README.md +7 -7
  73. package/SourceGenerators/Directory.Build.props +50 -3
  74. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +96 -63
  75. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +745 -87
  76. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +9 -1
  77. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +39 -46
  78. package/SourceGenerators/global.json +7 -0
  79. package/SourceGenerators/global.json.meta +7 -0
  80. package/package.json +27 -40
  81. package/Runtime/Core/Internal/TypedDispatchLinkIndex.cs +0 -51
package/README.md CHANGED
@@ -5,18 +5,17 @@
5
5
  </p>
6
6
 
7
7
  <p align="center">
8
- <a href="https://wallstop.github.io/DxMessaging/">
8
+ <a href="https://ambiguous-interactive.github.io/DxMessaging/">
9
9
  <img src="https://img.shields.io/badge/Full_Documentation-Visit_the_Docs_Site-2ea44f?style=for-the-badge" alt="Full Documentation" />
10
10
  </a>
11
11
  </p>
12
12
 
13
- [![Unity](https://img.shields.io/badge/Unity-2021.3+-black.svg)](https://unity.com/releases/editor)<br/>
13
+ [![Unity](https://img.shields.io/badge/Unity-2021.3+-black.svg)](https://unity.com/releases/editor/archive)<br/>
14
14
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)<br/>
15
15
  [![openupm](https://img.shields.io/npm/v/com.wallstop-studios.dxmessaging?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.wallstop-studios.dxmessaging/)<br/>
16
16
  [![Version](https://img.shields.io/npm/v/com.wallstop-studios.dxmessaging.svg)](https://www.npmjs.com/package/com.wallstop-studios.dxmessaging)<br/>
17
- [![Performance: OS-Specific Benchmarks](https://img.shields.io/badge/Performance-OS--specific-blueviolet.svg)](docs/architecture/performance.md)<br/>
18
- [![Markdown Link Validity](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-validity.yml/badge.svg)](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-validity.yml)<br/>
19
- [![Markdown Link Text Check](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-text-check.yml/badge.svg)](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-text-check.yml)
17
+ [![Performance: Standalone (IL2CPP)](<https://img.shields.io/badge/Performance-Standalone%20(IL2CPP)-blueviolet.svg>)](docs/architecture/performance.md)<br/>
18
+ [![Markdown Link Validity](https://github.com/Ambiguous-Interactive/DxMessaging/actions/workflows/markdown-link-validity.yml/badge.svg)](https://github.com/Ambiguous-Interactive/DxMessaging/actions/workflows/markdown-link-validity.yml)
20
19
 
21
20
  > **🤖 AI Assistance Disclosure:**
22
21
  >
@@ -90,7 +89,7 @@ You have data. You need to pass it around. That's the problem. DxMessaging provi
90
89
 
91
90
  ### The Three Message Types: Real-World Analogies
92
91
 
93
- > 💡 _Diagrams below require Mermaid support. If they don't render, try viewing this file directly on [GitHub](https://github.com/wallstop/DxMessaging)._
92
+ > 💡 _Diagrams below require Mermaid support. If they don't render, try viewing this file directly on [GitHub](https://github.com/Ambiguous-Interactive/DxMessaging)._
94
93
 
95
94
  Each message type maps to a real-world communication pattern:
96
95
 
@@ -192,7 +191,7 @@ openupm add com.wallstop-studios.dxmessaging
192
191
 
193
192
  ```bash
194
193
  # Unity Package Manager > Add package from git URL...
195
- https://github.com/wallstop/DxMessaging.git
194
+ https://github.com/Ambiguous-Interactive/DxMessaging.git
196
195
  ```
197
196
 
198
197
  See the [Install Guide](docs/getting-started/install.md) for all options including NPM scoped registries and local tarballs.
@@ -340,7 +339,7 @@ flowchart TD
340
339
 
341
340
  **Rule of thumb:** If decoupling, lifecycle leaks, or handler-ordering bugs match what you're hitting today, DxMessaging fits. If none of those describe your project, start with the [Visual Guide](docs/getting-started/visual-guide.md) or stick with simpler patterns.
342
341
 
343
- Looking for hard numbers? See OS-specific [Performance Benchmarks](docs/architecture/performance.md).
342
+ Looking for hard numbers? See the Standalone IL2CPP dispatch and library-comparison [Performance Benchmarks](docs/architecture/performance.md).
344
343
 
345
344
  ## Why DxMessaging
346
345
 
@@ -672,8 +671,8 @@ public void TestAchievementSystem() {
672
671
 
673
672
  ## Documentation
674
673
 
675
- - **[Documentation Site](https://wallstop.github.io/DxMessaging/)** - Full searchable documentation
676
- - **[Wiki](https://github.com/wallstop/DxMessaging/wiki)** - Quick reference wiki
674
+ - **[Documentation Site](https://ambiguous-interactive.github.io/DxMessaging/)** - Full searchable documentation
675
+ - **[Wiki](https://github.com/Ambiguous-Interactive/DxMessaging/wiki)** - Quick reference wiki
677
676
  - **[Changelog](CHANGELOG.md)** - Version history
678
677
 
679
678
  ### Learn
@@ -738,7 +737,7 @@ See the [DI Compatible section](#dependency-injection-di-compatible) above for a
738
737
  | ------------------- | --------------------------------- | -------------------------------- | --------------- | -------------- |
739
738
  | **DxMessaging** | Unity pub/sub with lifecycle mgmt | Inspector debugging + control | Built for Unity | Moderate |
740
739
  | **UniRx** | Complex event stream transforms | Reactive operators (LINQ) | Built for Unity | Easy |
741
- | **MessagePipe** | High-performance DI messaging | Highest throughput (97M ops/sec) | Built for Unity | Steep |
740
+ | **MessagePipe** | High-performance DI messaging | Highest throughput (74M ops/sec) | Built for Unity | Steep |
742
741
  | **Zenject Signals** | DI-integrated messaging | Zenject ecosystem | Built for Unity | Easy |
743
742
  | **C# Events** | Simple, local communication | Minimal overhead | Native C# | Steepest |
744
743
 
@@ -832,7 +831,7 @@ public class AchievementTracker : MessageAwareComponent {
832
831
 
833
832
  See [Design & Architecture](docs/architecture/design-and-architecture.md#performance-optimizations) for details.
834
833
 
835
- For OS-specific benchmark tables generated by PlayMode tests, see [Performance Benchmarks](docs/architecture/performance.md).
834
+ For live, CI-generated Standalone IL2CPP dispatch tables and a cross-library comparison matrix, see [Performance Benchmarks](docs/architecture/performance.md). Those numbers are auto-generated on every push with the .NET Standard 2.1 profile and a Release build; the comparison table below is a static summary, not the live data.
836
835
 
837
836
  ## Comparison Table
838
837
 
@@ -851,7 +850,7 @@ For OS-specific benchmark tables generated by PlayMode tests, see [Performance B
851
850
  | **Interceptors** | Pipeline | No | Filters | No |
852
851
  | **Post-Processing** | Dedicated | No | Filters | No |
853
852
  | **Stream Operators** | No | Extensive | No | With UniRx |
854
- | **Performance** | Good (10-17M) | Good (18M) | High (97M) | Moderate (2.5M) |
853
+ | **Performance** | Good (27M) | Moderate (4M) | High (74M) | Moderate (2M) |
855
854
  | **Dependencies** | None | UniTask | None | Zenject |
856
855
 
857
856
  ### Comparison with Traditional Approaches
@@ -896,10 +895,10 @@ Created and maintained by [wallstop studios](https://wallstopstudios.com)
896
895
 
897
896
  ## Links
898
897
 
899
- - [Package on GitHub](https://github.com/wallstop/DxMessaging)
900
- - [Report Issues](https://github.com/wallstop/DxMessaging/issues)
901
- - [Documentation Site](https://wallstop.github.io/DxMessaging/)
902
- - [Wiki](https://github.com/wallstop/DxMessaging/wiki)
898
+ - [Package on GitHub](https://github.com/Ambiguous-Interactive/DxMessaging)
899
+ - [Report Issues](https://github.com/Ambiguous-Interactive/DxMessaging/issues)
900
+ - [Documentation Site](https://ambiguous-interactive.github.io/DxMessaging/)
901
+ - [Wiki](https://github.com/Ambiguous-Interactive/DxMessaging/wiki)
903
902
 
904
903
  ## AI Agent Integration
905
904
 
@@ -909,7 +908,7 @@ DxMessaging publishes machine-readable context for AI agents through [llms.txt](
909
908
 
910
909
  - **[llms.txt](llms.txt)** -- Complete project overview, API reference, and context in a single file
911
910
  - **[Repository Guidelines](.llm/context.md)** -- Coding standards and development workflows
912
- - **[AI Agent Skills](.llm/skills/)** -- 140+ specialized skill documents covering documentation, testing, GitHub Actions, and more
911
+ - **[AI Agent Skills](.llm/skills/)** -- 155+ specialized skill documents covering documentation, testing, GitHub Actions, and more
913
912
 
914
913
  The `llms.txt` file is automatically updated via CI/CD to stay current with project changes. It includes:
915
914
 
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 83aab80bf265483fb08c5f884e4b24fc
3
- timeCreated: 1759525804
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: bef6adb9baf545129cb9a841b13da451
3
- timeCreated: 1749776355
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 73fd653a34be4f36b5773dce342ae9fa
3
- timeCreated: 1730779174
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -8,6 +8,8 @@ namespace DxMessaging.Core.Attributes
8
8
  /// <remarks>
9
9
  /// The source generator will emit a constructor parameter with a default value for fields annotated
10
10
  /// with this attribute. This is helpful for messages with sensible defaults.
11
+ /// Overloads accepting explicit default values require compile-time constants and are validated by
12
+ /// the source generator against the field type.
11
13
  /// </remarks>
12
14
  /// <example>
13
15
  /// <code>
@@ -27,10 +29,6 @@ namespace DxMessaging.Core.Attributes
27
29
  /// </summary>
28
30
  public DxOptionalParameterAttribute() { }
29
31
 
30
- /// <summary>
31
- /// Optional default value overloads. Values must be compile-time constants and
32
- /// will be validated by the source generator against the field type.
33
- /// </summary>
34
32
  /// <summary>
35
33
  /// Initializes the attribute with the specified default boolean value.
36
34
  /// </summary>
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 87d96cdf2fc74f40ba77ae0d157be964
3
- timeCreated: 1749850608
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: ab2509dd51f5467d95b4fca1cb794b29
3
- timeCreated: 1730779159
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 418b461df3764ef6896dc86524a00132
3
- timeCreated: 1730779131
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,56 @@
1
+ // Vendored copy of Unity's Il2CppSetOption attribute. The IL2CPP code
2
+ // generator (il2cpp.exe) matches this attribute by its FULL NAME
3
+ // (Unity.IL2CPP.CompilerServices.Il2CppSetOptionAttribute), not by assembly,
4
+ // so an internal per-assembly copy is the sanctioned way for a package to opt
5
+ // hot methods out of generated null/bounds checks (the same pattern UniTask
6
+ // and other performance-focused packages use). The shape below mirrors the
7
+ // attribute source Unity publishes in the IL2CPP documentation; do not add
8
+ // members or change the namespace. Under Mono (editor, Mono players) the
9
+ // attribute is inert.
10
+ namespace Unity.IL2CPP.CompilerServices
11
+ {
12
+ using System;
13
+
14
+ /// <summary>
15
+ /// Runtime checks that il2cpp.exe can omit for an annotated scope.
16
+ /// </summary>
17
+ internal enum Option
18
+ {
19
+ /// <summary>Implicit null checks before member access.</summary>
20
+ NullChecks = 1,
21
+
22
+ /// <summary>Array bounds checks on element access.</summary>
23
+ ArrayBoundsChecks = 2,
24
+
25
+ /// <summary>Integer divide-by-zero checks.</summary>
26
+ DivideByZeroChecks = 3,
27
+ }
28
+
29
+ /// <summary>
30
+ /// Instructs the IL2CPP code generator to enable or disable a runtime
31
+ /// check for the annotated type, method, or property.
32
+ /// </summary>
33
+ /// <remarks>
34
+ /// Only apply with <c>false</c> to code whose safety invariants are
35
+ /// guaranteed by construction and covered by tests: with checks disabled,
36
+ /// a violated invariant is memory corruption instead of a managed
37
+ /// exception.
38
+ /// </remarks>
39
+ [AttributeUsage(
40
+ AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property,
41
+ Inherited = false,
42
+ AllowMultiple = true
43
+ )]
44
+ internal sealed class Il2CppSetOptionAttribute : Attribute
45
+ {
46
+ public Option Option { get; private set; }
47
+
48
+ public object Value { get; private set; }
49
+
50
+ public Il2CppSetOptionAttribute(Option option, object value)
51
+ {
52
+ Option = option;
53
+ Value = value;
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 45b1a17f8c10b654c9ba5cd3e70e5f9e
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -77,6 +77,8 @@ namespace DxMessaging.Core.DataStructure
77
77
  private readonly List<T> _cache;
78
78
  private int _position;
79
79
 
80
+ internal int ScratchCacheCount => _cache.Count;
81
+
80
82
  /// <summary>
81
83
  /// Accesses the element at the specified chronological index (0 = oldest).
82
84
  /// </summary>
@@ -180,30 +182,37 @@ namespace DxMessaging.Core.DataStructure
180
182
  comparer ??= EqualityComparer<T>.Default;
181
183
 
182
184
  _cache.Clear();
183
- for (int i = 0; i < Count; ++i)
185
+ try
184
186
  {
185
- _cache.Add(_buffer[AdjustedIndexFor(i)]);
186
- }
187
+ for (int i = 0; i < Count; ++i)
188
+ {
189
+ _cache.Add(_buffer[AdjustedIndexFor(i)]);
190
+ }
187
191
 
188
- // Find and remove the element
189
- bool removed = false;
190
- for (int i = 0; i < _cache.Count; ++i)
191
- {
192
- if (comparer.Equals(_cache[i], element))
192
+ // Find and remove the element
193
+ bool removed = false;
194
+ for (int i = 0; i < _cache.Count; ++i)
193
195
  {
194
- _cache.RemoveAt(i);
195
- removed = true;
196
- break;
196
+ if (comparer.Equals(_cache[i], element))
197
+ {
198
+ _cache.RemoveAt(i);
199
+ removed = true;
200
+ break;
201
+ }
197
202
  }
198
- }
199
203
 
200
- if (!removed)
204
+ if (!removed)
205
+ {
206
+ return false;
207
+ }
208
+
209
+ RebuildFromCache();
210
+ return true;
211
+ }
212
+ finally
201
213
  {
202
- return false;
214
+ _cache.Clear();
203
215
  }
204
-
205
- RebuildFromCache();
206
- return true;
207
216
  }
208
217
 
209
218
  /// <summary>
@@ -219,19 +228,26 @@ namespace DxMessaging.Core.DataStructure
219
228
  }
220
229
 
221
230
  _cache.Clear();
222
- for (int i = 0; i < Count; ++i)
231
+ try
223
232
  {
224
- _cache.Add(_buffer[AdjustedIndexFor(i)]);
225
- }
233
+ for (int i = 0; i < Count; ++i)
234
+ {
235
+ _cache.Add(_buffer[AdjustedIndexFor(i)]);
236
+ }
237
+
238
+ int removedCount = _cache.RemoveAll(predicate);
239
+ if (removedCount == 0)
240
+ {
241
+ return 0;
242
+ }
226
243
 
227
- int removedCount = _cache.RemoveAll(predicate);
228
- if (removedCount == 0)
244
+ RebuildFromCache();
245
+ return removedCount;
246
+ }
247
+ finally
229
248
  {
230
- return 0;
249
+ _cache.Clear();
231
250
  }
232
-
233
- RebuildFromCache();
234
- return removedCount;
235
251
  }
236
252
 
237
253
  private void RebuildFromCache()
@@ -240,6 +256,7 @@ namespace DxMessaging.Core.DataStructure
240
256
  _buffer.AddRange(_cache);
241
257
  Count = _cache.Count;
242
258
  _position = Count < Capacity ? Count : 0;
259
+ _cache.Clear();
243
260
  }
244
261
 
245
262
  /// <summary>
@@ -250,6 +267,7 @@ namespace DxMessaging.Core.DataStructure
250
267
  Count = 0;
251
268
  _position = 0;
252
269
  _buffer.Clear();
270
+ _cache.Clear();
253
271
  }
254
272
 
255
273
  /// <summary>
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 7d8dbf8640e24846bf35fb18a1b7c504
3
- timeCreated: 1749671893
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 8eafaabae0f549ec82f67ea18be788e1
3
- timeCreated: 1749672335
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 01598791b01241caabfecea4c1f5880d
3
- timeCreated: 1749672447
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 7d393cfbb3c8429d83af17a737fdaf0e
3
- timeCreated: 1749672471
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -2,6 +2,7 @@ namespace DxMessaging.Core.Extensions
2
2
  {
3
3
  using System;
4
4
  using System.Runtime.CompilerServices;
5
+ using DxMessaging.Core.Internal;
5
6
 
6
7
  internal static class EnumExtensions
7
8
  {
@@ -26,12 +27,12 @@ namespace DxMessaging.Core.Extensions
26
27
  {
27
28
  try
28
29
  {
29
- return Unsafe.SizeOf<T>() switch
30
+ return DxUnsafe.SizeOf<T>() switch
30
31
  {
31
- 1 => Unsafe.As<T, byte>(ref value),
32
- 2 => Unsafe.As<T, ushort>(ref value),
33
- 4 => Unsafe.As<T, uint>(ref value),
34
- 8 => Unsafe.As<T, ulong>(ref value),
32
+ 1 => DxUnsafe.As<T, byte>(ref value),
33
+ 2 => DxUnsafe.As<T, ushort>(ref value),
34
+ 4 => DxUnsafe.As<T, uint>(ref value),
35
+ 8 => DxUnsafe.As<T, ulong>(ref value),
35
36
  _ => null,
36
37
  };
37
38
  }
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: f01ee914d7634a69a85f86bb02f2f07e
3
- timeCreated: 1745162639
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: f6956caef19744a0b0d96215d4e5154a
3
- timeCreated: 1749671953
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -79,12 +79,6 @@ namespace DxMessaging.Core.Extensions
79
79
  {
80
80
  InstanceId targetId = target;
81
81
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
82
- if (typeof(TMessage) == typeof(ITargetedMessage))
83
- {
84
- resolvedBus.UntypedTargetedBroadcast(targetId, message);
85
- return;
86
- }
87
-
88
82
  resolvedBus.TargetedBroadcast(ref targetId, ref message);
89
83
  }
90
84
 
@@ -129,12 +123,6 @@ namespace DxMessaging.Core.Extensions
129
123
  {
130
124
  InstanceId targetId = target;
131
125
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
132
- if (typeof(TMessage) == typeof(ITargetedMessage))
133
- {
134
- resolvedBus.UntypedTargetedBroadcast(targetId, message);
135
- return;
136
- }
137
-
138
126
  resolvedBus.TargetedBroadcast(ref targetId, ref message);
139
127
  }
140
128
  #endif
@@ -178,12 +166,6 @@ namespace DxMessaging.Core.Extensions
178
166
  where TMessage : struct, ITargetedMessage
179
167
  {
180
168
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
181
- if (typeof(TMessage) == typeof(ITargetedMessage))
182
- {
183
- resolvedBus.UntypedTargetedBroadcast(target, message);
184
- return;
185
- }
186
-
187
169
  resolvedBus.TargetedBroadcast(ref target, ref message);
188
170
  }
189
171
 
@@ -259,12 +241,6 @@ namespace DxMessaging.Core.Extensions
259
241
  where TMessage : struct, IUntargetedMessage
260
242
  {
261
243
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
262
- if (typeof(TMessage) == typeof(IUntargetedMessage))
263
- {
264
- resolvedBus.UntypedUntargetedBroadcast(message);
265
- return;
266
- }
267
-
268
244
  resolvedBus.UntargetedBroadcast(ref message);
269
245
  }
270
246
 
@@ -296,12 +272,6 @@ namespace DxMessaging.Core.Extensions
296
272
  where TMessage : struct, IUntargetedMessage
297
273
  {
298
274
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
299
- if (typeof(TMessage) == typeof(IUntargetedMessage))
300
- {
301
- resolvedBus.UntypedUntargetedBroadcast(message);
302
- return;
303
- }
304
-
305
275
  resolvedBus.UntargetedBroadcast(ref message);
306
276
  }
307
277
 
@@ -341,12 +311,6 @@ namespace DxMessaging.Core.Extensions
341
311
  where TMessage : struct, ITargetedMessage
342
312
  {
343
313
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
344
- if (typeof(TMessage) == typeof(ITargetedMessage))
345
- {
346
- resolvedBus.UntypedTargetedBroadcast(target, message);
347
- return;
348
- }
349
-
350
314
  resolvedBus.TargetedBroadcast(ref target, ref message);
351
315
  }
352
316
 
@@ -386,12 +350,6 @@ namespace DxMessaging.Core.Extensions
386
350
  where TMessage : struct, IBroadcastMessage
387
351
  {
388
352
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
389
- if (typeof(TMessage) == typeof(ITargetedMessage))
390
- {
391
- resolvedBus.UntypedSourcedBroadcast(source, message);
392
- return;
393
- }
394
-
395
353
  resolvedBus.SourcedBroadcast(ref source, ref message);
396
354
  }
397
355
 
@@ -437,12 +395,6 @@ namespace DxMessaging.Core.Extensions
437
395
  {
438
396
  InstanceId sourceId = source;
439
397
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
440
- if (typeof(TMessage) == typeof(IBroadcastMessage))
441
- {
442
- resolvedBus.UntypedSourcedBroadcast(sourceId, message);
443
- return;
444
- }
445
-
446
398
  resolvedBus.SourcedBroadcast(ref sourceId, ref message);
447
399
  }
448
400
 
@@ -487,12 +439,6 @@ namespace DxMessaging.Core.Extensions
487
439
  {
488
440
  InstanceId sourceId = source;
489
441
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
490
- if (typeof(TMessage) == typeof(IBroadcastMessage))
491
- {
492
- resolvedBus.UntypedSourcedBroadcast(sourceId, message);
493
- return;
494
- }
495
-
496
442
  resolvedBus.SourcedBroadcast(ref sourceId, ref message);
497
443
  }
498
444
  #endif
@@ -536,12 +482,6 @@ namespace DxMessaging.Core.Extensions
536
482
  where TMessage : struct, IBroadcastMessage
537
483
  {
538
484
  IMessageBus resolvedBus = ResolveMessageBus(messageBus, messageBusProvider);
539
- if (typeof(TMessage) == typeof(IBroadcastMessage))
540
- {
541
- resolvedBus.UntypedSourcedBroadcast(source, message);
542
- return;
543
- }
544
-
545
485
  resolvedBus.SourcedBroadcast(ref source, ref message);
546
486
  }
547
487
 
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 23cb3bf7f25d479c862736482ee96fa7
3
- timeCreated: 1745102344
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,3 +1,11 @@
1
1
  fileFormatVersion: 2
2
2
  guid: 612c352c3d984a3486ac4b19bb69fa37
3
- timeCreated: 1745101032
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: