com.wallstop-studios.dxmessaging 2.1.1 → 2.1.2

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 (125) hide show
  1. package/.github/workflows/dotnet-tests.yml +72 -0
  2. package/.lychee.toml +4 -2
  3. package/AGENTS.md +1 -0
  4. package/Docs/Comparisons.md +4 -4
  5. package/Docs/Install.md +2 -1
  6. package/Docs/Performance.md +13 -11
  7. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  8. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +13 -2
  9. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
  10. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +11 -0
  11. package/Editor/Analyzers/System.Collections.Immutable.dll +0 -0
  12. package/Editor/Analyzers/System.Collections.Immutable.dll.meta +11 -0
  13. package/Editor/Analyzers/System.Reflection.Metadata.dll +0 -0
  14. package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +13 -2
  15. package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
  16. package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +11 -0
  17. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  18. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +3 -2
  19. package/Editor/AssemblyInfo.cs +3 -0
  20. package/Editor/AssemblyInfo.cs.meta +3 -0
  21. package/Editor/CustomEditors/MessagingComponentEditor.cs +21 -0
  22. package/Editor/SetupCscRsp.cs +133 -53
  23. package/Editor/Testing/MessagingComponentEditorHarness.cs +218 -0
  24. package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +3 -0
  25. package/Editor/Testing.meta +3 -0
  26. package/README.md +9 -3
  27. package/Runtime/AssemblyInfo.cs +1 -0
  28. package/Runtime/Core/Diagnostics/MessageEmissionData.cs +26 -11
  29. package/Runtime/Core/Extensions/MessageBusExtensions.cs +2 -2
  30. package/Runtime/Core/Extensions/MessageExtensions.cs +2 -2
  31. package/Runtime/Core/InstanceId.cs +5 -3
  32. package/Runtime/Core/MessageBus/MessageBus.cs +4 -4
  33. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +2 -2
  34. package/Runtime/Core/MessageBus/MessagingRegistration.cs +3 -3
  35. package/Runtime/Core/MessageHandler.cs +34 -2
  36. package/Runtime/Core/MessageRegistrationToken.cs +2 -2
  37. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +2 -0
  38. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +2 -0
  39. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +2 -0
  40. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +2 -0
  41. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +2 -0
  42. package/Runtime/Unity/MessageAwareComponent.cs +2 -0
  43. package/Runtime/Unity/MessageBusProviderHandle.cs +4 -0
  44. package/Runtime/Unity/MessagingComponent.cs +16 -0
  45. package/Runtime/Unity/MessagingComponentInstaller.cs +2 -0
  46. package/Runtime/Unity/ScriptableMessageBusProvider.cs +2 -0
  47. package/SourceGenerators/Directory.Build.props +9 -0
  48. package/SourceGenerators/Directory.Build.props.meta +7 -0
  49. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +19 -24
  50. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +87 -27
  51. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +24 -4
  52. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DocsSnippetCompilationTests.cs +193 -0
  53. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DocsSnippetCompilationTests.cs.meta +11 -0
  54. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxAutoConstructorGeneratorDiagnosticsTests.cs +69 -0
  55. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxAutoConstructorGeneratorDiagnosticsTests.cs.meta +11 -0
  56. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxMessageIdGeneratorDiagnosticsTests.cs +66 -0
  57. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxMessageIdGeneratorDiagnosticsTests.cs.meta +11 -0
  58. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/GeneratorTestUtilities.cs +155 -0
  59. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/GeneratorTestUtilities.cs.meta +11 -0
  60. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj +20 -0
  61. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj.meta +7 -0
  62. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests.meta +8 -0
  63. package/Tests/Editor/MessagingComponentEditorHarnessTests.cs +243 -0
  64. package/Tests/Editor/MessagingComponentEditorHarnessTests.cs.meta +3 -0
  65. package/Tests/Editor/MessagingComponentSerializationTests.cs +129 -0
  66. package/Tests/Editor/MessagingComponentSerializationTests.cs.meta +3 -0
  67. package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef +19 -0
  68. package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef.meta +3 -0
  69. package/Tests/Editor.meta +3 -0
  70. package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +3 -0
  71. package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +3 -0
  72. package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +3 -0
  73. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +137 -0
  74. package/Tests/Runtime/Core/AlternateBusTests.cs +3 -0
  75. package/Tests/Runtime/Core/BroadcastTests.cs +3 -0
  76. package/Tests/Runtime/Core/CyclicBufferTests.cs +3 -0
  77. package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +5 -2
  78. package/Tests/Runtime/Core/DiagnosticsTests.cs +3 -0
  79. package/Tests/Runtime/Core/EdgeCaseTests.cs +3 -0
  80. package/Tests/Runtime/Core/EnablementTests.cs +3 -0
  81. package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +2 -2
  82. package/Tests/Runtime/Core/GenericMessageTests.cs +3 -0
  83. package/Tests/Runtime/Core/GlobalAcceptAllTests.cs +3 -0
  84. package/Tests/Runtime/Core/InterceptorCancellationTests.cs +3 -0
  85. package/Tests/Runtime/Core/LifecycleTests.cs +3 -0
  86. package/Tests/Runtime/Core/MessageEmissionDataTests.cs +70 -0
  87. package/Tests/Runtime/Core/MessageEmissionDataTests.cs.meta +11 -0
  88. package/Tests/Runtime/Core/MessagingComponentLifecycleTests.cs +3 -0
  89. package/Tests/Runtime/Core/MessagingTestBase.cs +3 -0
  90. package/Tests/Runtime/Core/MutationDedupeTests.cs +3 -0
  91. package/Tests/Runtime/Core/MutationDestructionTests.cs +3 -0
  92. package/Tests/Runtime/Core/MutationDuringEmissionTests.cs +3 -0
  93. package/Tests/Runtime/Core/MutationGlobalAddTests.cs +3 -0
  94. package/Tests/Runtime/Core/MutationInterceptorTests.cs +3 -0
  95. package/Tests/Runtime/Core/MutationPostProcessorAcrossHandlersTests.cs +3 -0
  96. package/Tests/Runtime/Core/MutationPostProcessorMoreTests.cs +3 -0
  97. package/Tests/Runtime/Core/MutationPriorityTests.cs +3 -0
  98. package/Tests/Runtime/Core/NominalTests.cs +3 -0
  99. package/Tests/Runtime/Core/OrderingTests.cs +3 -0
  100. package/Tests/Runtime/Core/OverDeregistrationTests.cs +3 -0
  101. package/Tests/Runtime/Core/PostProcessorTests.cs +3 -0
  102. package/Tests/Runtime/Core/ReflexiveErrorTests.cs +3 -0
  103. package/Tests/Runtime/Core/ReflexiveMessageWarningTests.cs +4 -1
  104. package/Tests/Runtime/Core/ReflexiveTests.cs +3 -0
  105. package/Tests/Runtime/Core/RegistrationTests.cs +3 -0
  106. package/Tests/Runtime/Core/StringShorthandTests.cs +3 -0
  107. package/Tests/Runtime/Core/TargetedTests.cs +3 -0
  108. package/Tests/Runtime/Core/TypedShorthandTests.cs +3 -0
  109. package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +3 -0
  110. package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +14 -78
  111. package/Tests/Runtime/Core/UntargetedTests.cs +3 -0
  112. package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +4 -1
  113. package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +3 -0
  114. package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +3 -0
  115. package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +3 -0
  116. package/Tests/Runtime/Scripts/Components/ManualListenerComponent.cs +3 -0
  117. package/Tests/Runtime/Scripts/Components/ReflexiveReceiverComponent.cs +3 -0
  118. package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +3 -0
  119. package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +3 -0
  120. package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +87 -3
  121. package/Tests/Runtime/Unity/MessagingComponentInstallerSceneTests.cs +109 -0
  122. package/Tests/Runtime/Unity/MessagingComponentInstallerSceneTests.cs.meta +11 -0
  123. package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +159 -17
  124. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +20 -7
  125. package/package.json +1 -1
@@ -0,0 +1,72 @@
1
+ name: dotnet-tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - main
8
+ - develop
9
+ pull_request:
10
+ branches:
11
+ - "*"
12
+
13
+ jobs:
14
+ test:
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Setup .NET
22
+ uses: actions/setup-dotnet@v3
23
+ with:
24
+ dotnet-version: "9.0.x"
25
+
26
+ - name: Install reportgenerator tool
27
+ run: |
28
+ dotnet tool install --global dotnet-reportgenerator-globaltool
29
+ echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
30
+
31
+ - name: Restore
32
+ run: dotnet restore SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj
33
+
34
+ - name: Run generator diagnostics tests
35
+ run: >
36
+ dotnet test SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj
37
+ --configuration Release
38
+ --collect:"XPlat Code Coverage"
39
+
40
+ - name: Generate coverage summary
41
+ run: |
42
+ mkdir -p artifacts/coverage
43
+ reportgenerator \
44
+ -reports:".artifacts/SourceGenerators.Tests/TestResults/**/coverage.cobertura.xml" \
45
+ -targetdir:"artifacts/coverage" \
46
+ -reporttypes:"TextSummary;HtmlSummary;Cobertura"
47
+ cat artifacts/coverage/Summary.txt
48
+
49
+ - name: Upload coverage report
50
+ uses: actions/upload-artifact@v4
51
+ with:
52
+ name: generator-coverage
53
+ path: artifacts/coverage
54
+
55
+ - name: Check for TODO/FIXME markers
56
+ shell: bash
57
+ run: |
58
+ set -uo pipefail
59
+ if rg --files-with-matches "(TODO|FIXME)" \
60
+ --hidden \
61
+ --no-ignore \
62
+ -g '!.git/**' \
63
+ -g '!.artifacts/**' \
64
+ -g '!node_modules/**' \
65
+ -g '!Tests/**/TestResults/**' \
66
+ -g '!PLAN.md' \
67
+ -g '!.vs/**'; then
68
+ echo "::error::Found TODO/FIXME markers in the repository. Please resolve or suppress them."
69
+ exit 1
70
+ else
71
+ echo "No TODO/FIXME markers detected."
72
+ fi
package/.lychee.toml CHANGED
@@ -17,10 +17,12 @@ accept = ["200..=299", 429]
17
17
  # Only check web links
18
18
  scheme = ["https", "http"]
19
19
 
20
- # Ignore common local/test URLs
20
+ # Ignore endpoints that block automated clients (local hosts, CF challenges)
21
21
  exclude = [
22
22
  "^https?://localhost",
23
23
  "^http://127\\.0\\.0\\.1",
24
24
  "^https?://0\\.0\\.0\\.0",
25
- "^file://"
25
+ "^file://",
26
+ # NPM package page serves a Cloudflare JS challenge to non-browser clients; registry endpoint remains covered.
27
+ "^https://www\\.npmjs\\.com/package/com\\.wallstop-studios\\.dxmessaging$"
26
28
  ]
package/AGENTS.md CHANGED
@@ -24,6 +24,7 @@
24
24
  - Do not use underscores in function names, especially test function names.
25
25
  - Do not use regions, anywhere, ever.
26
26
  - Avoid `var` wherever possible, use expressive types.
27
+ - Do not use nullable reference types.
27
28
 
28
29
  ## Testing Guidelines
29
30
 
@@ -34,10 +34,10 @@ These sections are auto-updated by the PlayMode comparison benchmarks in `Tests/
34
34
 
35
35
  | Message Tech | Operations / Second | Allocations? |
36
36
  | ---------------------------------- | ------------------- | ------------ |
37
- | DxMessaging (Untargeted) - No-Copy | 14,740,000 | No |
38
- | UniRx MessageBroker | 17,858,000 | No |
39
- | MessagePipe (Global) | 96,052,000 | No |
40
- | Zenject SignalBus | 2,632,000 | Yes |
37
+ | DxMessaging (Untargeted) - No-Copy | 14,734,000 | No |
38
+ | UniRx MessageBroker | 18,044,000 | No |
39
+ | MessagePipe (Global) | 97,774,000 | No |
40
+ | Zenject SignalBus | 2,600,000 | Yes |
41
41
 
42
42
  ### Comparisons (macOS)
43
43
 
package/Docs/Install.md CHANGED
@@ -9,7 +9,8 @@ This page helps you install DxMessaging into a Unity 2021.3+ project using the U
9
9
  - Unity Package Manager > Add package from git URL...
10
10
  - Paste:
11
11
 
12
- ```text
12
+ ```bash
13
+ # Unity UPM: Add package from git URL...
13
14
  https://github.com/wallstop/DxMessaging.git
14
15
  ```
15
16
 
@@ -12,17 +12,19 @@ See also: `Docs/DesignAndArchitecture.md#performance-optimizations` for design d
12
12
 
13
13
  ## Windows
14
14
 
15
- | Message Tech | Operations / Second | Allocations? |
16
- | ---------------------------------- | ------------------- | ------------ |
17
- | Unity | 2,628,000 | Yes |
18
- | DxMessaging (GameObject) - Normal | 8,208,000 | No |
19
- | DxMessaging (Component) - Normal | 8,210,000 | No |
20
- | DxMessaging (GameObject) - No-Copy | 9,412,000 | No |
21
- | DxMessaging (Component) - No-Copy | 9,354,000 | No |
22
- | DxMessaging (Untargeted) - No-Copy | 14,812,000 | No |
23
- | Reflexive (One Argument) | 2,856,000 | No |
24
- | Reflexive (Two Arguments) | 2,372,000 | No |
25
- | Reflexive (Three Arguments) | 2,382,000 | No |
15
+ | Message Tech | Operations / Second | Allocations? |
16
+ | ------------------------------------------ | ------------------- | ------------ |
17
+ | Unity | 2,564,000 | Yes |
18
+ | DxMessaging (GameObject) - Normal | 8,476,000 | No |
19
+ | DxMessaging (Component) - Normal | 8,474,000 | No |
20
+ | DxMessaging (GameObject) - No-Copy | 9,418,000 | No |
21
+ | DxMessaging (Component) - No-Copy | 9,536,000 | No |
22
+ | DxMessaging (Untargeted) - No-Copy | 14,736,000 | No |
23
+ | DxMessaging (Untargeted) - Interceptors | 6,618,000 | No |
24
+ | DxMessaging (Untargeted) - Post-Processors | 5,244,000 | No |
25
+ | Reflexive (One Argument) | 2,828,000 | No |
26
+ | Reflexive (Two Arguments) | 2,360,000 | No |
27
+ | Reflexive (Three Arguments) | 2,358,000 | No |
26
28
 
27
29
  ## macOS
28
30
 
@@ -11,15 +11,26 @@ PluginImporter:
11
11
  isExplicitlyReferenced: 0
12
12
  validateReferences: 1
13
13
  platformData:
14
+ - first:
15
+ : Any
16
+ second:
17
+ enabled: 0
18
+ settings:
19
+ Exclude Editor: 0
20
+ Exclude Linux64: 1
21
+ Exclude OSXUniversal: 1
22
+ Exclude WebGL: 1
23
+ Exclude Win: 1
24
+ Exclude Win64: 1
14
25
  - first:
15
26
  Any:
16
27
  second:
17
- enabled: 1
28
+ enabled: 0
18
29
  settings: {}
19
30
  - first:
20
31
  Editor: Editor
21
32
  second:
22
- enabled: 0
33
+ enabled: 1
23
34
  settings:
24
35
  DefaultValueInitialized: true
25
36
  - first:
@@ -11,6 +11,17 @@ PluginImporter:
11
11
  isExplicitlyReferenced: 0
12
12
  validateReferences: 1
13
13
  platformData:
14
+ - first:
15
+ : Any
16
+ second:
17
+ enabled: 0
18
+ settings:
19
+ Exclude Editor: 0
20
+ Exclude Linux64: 1
21
+ Exclude OSXUniversal: 1
22
+ Exclude WebGL: 1
23
+ Exclude Win: 1
24
+ Exclude Win64: 1
14
25
  - first:
15
26
  Any:
16
27
  second:
@@ -11,6 +11,17 @@ PluginImporter:
11
11
  isExplicitlyReferenced: 0
12
12
  validateReferences: 1
13
13
  platformData:
14
+ - first:
15
+ : Any
16
+ second:
17
+ enabled: 0
18
+ settings:
19
+ Exclude Editor: 0
20
+ Exclude Linux64: 1
21
+ Exclude OSXUniversal: 1
22
+ Exclude WebGL: 1
23
+ Exclude Win: 1
24
+ Exclude Win64: 1
14
25
  - first:
15
26
  Any:
16
27
  second:
@@ -11,15 +11,26 @@ PluginImporter:
11
11
  isExplicitlyReferenced: 0
12
12
  validateReferences: 1
13
13
  platformData:
14
+ - first:
15
+ : Any
16
+ second:
17
+ enabled: 0
18
+ settings:
19
+ Exclude Editor: 0
20
+ Exclude Linux64: 1
21
+ Exclude OSXUniversal: 1
22
+ Exclude WebGL: 1
23
+ Exclude Win: 1
24
+ Exclude Win64: 1
14
25
  - first:
15
26
  Any:
16
27
  second:
17
- enabled: 1
28
+ enabled: 0
18
29
  settings: {}
19
30
  - first:
20
31
  Editor: Editor
21
32
  second:
22
- enabled: 0
33
+ enabled: 1
23
34
  settings:
24
35
  DefaultValueInitialized: true
25
36
  - first:
@@ -11,6 +11,17 @@ PluginImporter:
11
11
  isExplicitlyReferenced: 0
12
12
  validateReferences: 1
13
13
  platformData:
14
+ - first:
15
+ : Any
16
+ second:
17
+ enabled: 0
18
+ settings:
19
+ Exclude Editor: 0
20
+ Exclude Linux64: 1
21
+ Exclude OSXUniversal: 1
22
+ Exclude WebGL: 1
23
+ Exclude Win: 1
24
+ Exclude Win64: 1
14
25
  - first:
15
26
  Any:
16
27
  second:
@@ -18,9 +18,10 @@ PluginImporter:
18
18
  second:
19
19
  enabled: 0
20
20
  settings:
21
- Exclude Editor: 1
21
+ Exclude Editor: 0
22
22
  Exclude Linux64: 1
23
23
  Exclude OSXUniversal: 1
24
+ Exclude WebGL: 1
24
25
  Exclude Win: 1
25
26
  Exclude Win64: 1
26
27
  - first:
@@ -31,7 +32,7 @@ PluginImporter:
31
32
  - first:
32
33
  Editor: Editor
33
34
  second:
34
- enabled: 0
35
+ enabled: 1
35
36
  settings:
36
37
  CPU: AnyCPU
37
38
  DefaultValueInitialized: true
@@ -0,0 +1,3 @@
1
+ using System.Runtime.CompilerServices;
2
+
3
+ [assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Editor")]
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 55bb3ae7ef064633b5fe4b17ce29f8cc
3
+ timeCreated: 1761880591
@@ -7,6 +7,7 @@ namespace DxMessaging.Editor.CustomEditors
7
7
  using Core.Diagnostics;
8
8
  using Core.MessageBus;
9
9
  using Core.Messages;
10
+ using DxMessaging.Editor.Testing;
10
11
  using Unity;
11
12
  using UnityEditor;
12
13
  using UnityEngine;
@@ -66,6 +67,26 @@ namespace DxMessaging.Editor.CustomEditors
66
67
  return;
67
68
  }
68
69
 
70
+ MessagingComponentInspectorState inspectorState =
71
+ MessagingComponentEditorHarness.Capture(component);
72
+ ProviderDiagnosticsView providerDiagnostics = inspectorState.ProviderDiagnostics;
73
+
74
+ if (providerDiagnostics.SerializedProviderMissingWarning)
75
+ {
76
+ EditorGUILayout.HelpBox(
77
+ "Auto-configure serialized provider is enabled, but no provider asset is assigned.",
78
+ MessageType.Warning
79
+ );
80
+ }
81
+
82
+ if (providerDiagnostics.SerializedProviderNullBusWarning)
83
+ {
84
+ EditorGUILayout.HelpBox(
85
+ "The serialized provider resolved without returning a message bus. Verify the provider implementation.",
86
+ MessageType.Warning
87
+ );
88
+ }
89
+
69
90
  if (component._registeredListeners.Count == 0)
70
91
  {
71
92
  EditorGUILayout.LabelField("No listeners registered.");
@@ -6,6 +6,7 @@ namespace DxMessaging.Editor
6
6
  using System.Collections.Generic;
7
7
  using System.IO;
8
8
  using System.Linq;
9
+ using System.Security.Cryptography;
9
10
  using UnityEditor;
10
11
  using UnityEngine;
11
12
  using Object = UnityEngine.Object;
@@ -20,11 +21,11 @@ namespace DxMessaging.Editor
20
21
  )
21
22
  .Replace("\\", "/");
22
23
 
23
- private static readonly string AnalyzerPathRelative =
24
- "Packages/com.wallstop-studios.dxmessaging/Editor/Analyzers/";
25
-
26
- private static readonly string LibraryPathRelative =
27
- "Library/PackageCache/com.wallstop-studios.dxmessaging/Editor/Analyzers/";
24
+ private static readonly string[] AnalyzerDirectories =
25
+ {
26
+ "Packages/com.wallstop-studios.dxmessaging/Editor/Analyzers/",
27
+ "Library/PackageCache/com.wallstop-studios.dxmessaging/Editor/Analyzers/",
28
+ };
28
29
 
29
30
  private static readonly string SourceGeneratorDllName =
30
31
  "WallstopStudios.DxMessaging.SourceGenerators.dll";
@@ -34,13 +35,18 @@ namespace DxMessaging.Editor
34
35
  SourceGeneratorDllName,
35
36
  "Microsoft.CodeAnalysis.dll",
36
37
  "Microsoft.CodeAnalysis.CSharp.dll",
38
+ "System.Text.Encodings.Web.dll",
37
39
  "System.Reflection.Metadata.dll",
38
40
  "System.Runtime.CompilerServices.Unsafe.dll",
39
41
  "System.Collections.Immutable.dll",
42
+ "System.Memory.dll",
43
+ "System.Buffers.dll",
44
+ "System.Threading.Tasks.Extensions.dll",
45
+ "System.Numerics.Vectors.dll",
46
+ "System.Text.Encoding.CodePages.dll",
47
+ "Microsoft.Bcl.AsyncInterfaces.dll",
40
48
  };
41
49
 
42
- private static readonly string LibraryArgument = $"-a:\"{LibraryPathRelative}\"";
43
-
44
50
  private static readonly HashSet<string> DllNames = new(StringComparer.OrdinalIgnoreCase);
45
51
 
46
52
  static SetupCscRsp()
@@ -69,17 +75,14 @@ namespace DxMessaging.Editor
69
75
  }
70
76
  }
71
77
 
72
- string[] dllRelativeDirectories = { LibraryPathRelative, AnalyzerPathRelative };
73
-
74
- bool anyFound = false;
75
- foreach (
76
- string requiredDllName in RequiredDllNames.Where(dllName =>
77
- !DllNames.Contains(dllName)
78
- )
79
- )
78
+ foreach (string requiredDllName in RequiredDllNames)
80
79
  {
81
- bool found = false;
82
- foreach (string relativeDirectory in dllRelativeDirectories)
80
+ if (DllNames.Contains(requiredDllName))
81
+ {
82
+ continue;
83
+ }
84
+
85
+ foreach (string relativeDirectory in AnalyzerDirectories)
83
86
  {
84
87
  try
85
88
  {
@@ -92,52 +95,62 @@ namespace DxMessaging.Editor
92
95
  const string pluginsDirectory =
93
96
  "Assets/Plugins/Editor/WallstopStudios.DxMessaging/";
94
97
  string outputAsset = $"{pluginsDirectory}{requiredDllName}";
95
- string sourceAsset = $"{relativeDirectory}{requiredDllName}";
96
98
  if (!Directory.Exists(pluginsDirectory))
97
99
  {
98
100
  Directory.CreateDirectory(pluginsDirectory);
99
101
  AssetDatabase.Refresh();
100
102
  }
101
- if (!File.Exists(outputAsset))
103
+ bool needsCopy = FilesDiffer(sourceFile, outputAsset);
104
+ if (needsCopy)
102
105
  {
103
- File.Copy(sourceAsset, outputAsset);
106
+ File.Copy(sourceFile, outputAsset, true);
104
107
  AssetDatabase.ImportAsset(outputAsset);
105
- found = true;
106
108
  }
107
- else
109
+
110
+ if (requiredDllName == SourceGeneratorDllName)
111
+ {
112
+ Object loadedDll = AssetDatabase.LoadMainAssetAtPath(outputAsset);
113
+ if (loadedDll != null)
114
+ {
115
+ string[] existingLabels = AssetDatabase.GetLabels(loadedDll);
116
+ if (!existingLabels.Contains("RoslynAnalyzer"))
117
+ {
118
+ List<string> newLabels = existingLabels.ToList();
119
+ newLabels.Add("RoslynAnalyzer");
120
+ AssetDatabase.SetLabels(loadedDll, newLabels.ToArray());
121
+ }
122
+ }
123
+ }
124
+
125
+ if (AssetImporter.GetAtPath(outputAsset) is PluginImporter importer)
108
126
  {
109
- FileInfo sourceInfo = new(sourceAsset);
110
- FileInfo destInfo = new(outputAsset);
127
+ bool importerDirty = false;
111
128
 
112
- if (destInfo.LastWriteTime < sourceInfo.LastWriteTime)
129
+ if (importer.GetCompatibleWithAnyPlatform())
113
130
  {
114
- // Source file is newer, so copy the file (overwrite destination)
115
- File.Copy(sourceAsset, outputAsset, true);
116
- AssetDatabase.ImportAsset(outputAsset);
117
- found = true;
131
+ importer.SetCompatibleWithAnyPlatform(false);
132
+ importerDirty = true;
118
133
  }
119
- else
134
+
135
+ if (importer.GetExcludeFromAnyPlatform("Editor"))
120
136
  {
121
- continue;
137
+ importer.SetExcludeFromAnyPlatform("Editor", false);
138
+ importerDirty = true;
122
139
  }
123
- }
124
140
 
125
- if (requiredDllName == SourceGeneratorDllName)
126
- {
127
- Object loadedDll = AssetDatabase.LoadMainAssetAtPath(outputAsset);
128
- AssetDatabase.SetLabels(loadedDll, new[] { "RoslynAnalyzer" });
129
- }
141
+ if (!importer.GetExcludeFromAnyPlatform("Standalone"))
142
+ {
143
+ importer.SetExcludeFromAnyPlatform("Standalone", true);
144
+ importerDirty = true;
145
+ }
130
146
 
131
- PluginImporter importer =
132
- AssetImporter.GetAtPath(outputAsset) as PluginImporter;
133
- if (importer != null)
134
- {
135
- importer.SetCompatibleWithAnyPlatform(false);
136
- importer.SetExcludeFromAnyPlatform("Editor", false);
137
- importer.SetExcludeFromAnyPlatform("Standalone", false);
138
- importer.SaveAndReimport();
147
+ if (importerDirty || needsCopy)
148
+ {
149
+ importer.SaveAndReimport();
150
+ }
139
151
  }
140
152
 
153
+ DllNames.Add(requiredDllName);
141
154
  break;
142
155
  }
143
156
  catch (Exception e)
@@ -147,16 +160,36 @@ namespace DxMessaging.Editor
147
160
  );
148
161
  }
149
162
  }
150
-
151
- anyFound |= found;
152
163
  }
153
164
 
154
- if (anyFound)
165
+ if (DllNames.Count > 0)
155
166
  {
156
167
  AssetDatabase.Refresh();
157
168
  }
158
169
  }
159
170
 
171
+ private static bool FilesDiffer(string sourcePath, string destinationPath)
172
+ {
173
+ if (!File.Exists(destinationPath))
174
+ {
175
+ return true;
176
+ }
177
+
178
+ FileInfo sourceInfo = new(sourcePath);
179
+ FileInfo destinationInfo = new(destinationPath);
180
+ if (sourceInfo.Length != destinationInfo.Length)
181
+ {
182
+ return true;
183
+ }
184
+
185
+ using FileStream sourceStream = File.OpenRead(sourcePath);
186
+ using FileStream destinationStream = File.OpenRead(destinationPath);
187
+ using SHA256 sha256 = SHA256.Create();
188
+ byte[] sourceHash = sha256.ComputeHash(sourceStream);
189
+ byte[] destinationHash = sha256.ComputeHash(destinationStream);
190
+ return !sourceHash.AsSpan().SequenceEqual(destinationHash);
191
+ }
192
+
160
193
  private static void EnsureCscRsp()
161
194
  {
162
195
  try
@@ -168,20 +201,67 @@ namespace DxMessaging.Editor
168
201
  }
169
202
 
170
203
  string rspContent = File.ReadAllText(RspFilePath);
171
- if (rspContent.Contains(LibraryArgument, StringComparison.OrdinalIgnoreCase))
204
+ bool modified = false;
205
+ foreach (string analyzerArgument in GetAnalyzerArguments())
172
206
  {
173
- return;
207
+ if (rspContent.Contains(analyzerArgument, StringComparison.OrdinalIgnoreCase))
208
+ {
209
+ continue;
210
+ }
211
+
212
+ File.AppendAllText(RspFilePath, analyzerArgument + Environment.NewLine);
213
+ modified = true;
174
214
  }
175
215
 
176
- File.AppendAllText(RspFilePath, $"{LibraryArgument}{Environment.NewLine}");
177
- AssetDatabase.ImportAsset("csc.rsp");
178
- Debug.Log("Updated csc.rsp.");
216
+ if (modified)
217
+ {
218
+ AssetDatabase.ImportAsset("csc.rsp");
219
+ Debug.Log("Updated csc.rsp.");
220
+ }
179
221
  }
180
222
  catch (IOException ex)
181
223
  {
182
224
  Debug.LogError($"Failed to modify csc.rsp: {ex}");
183
225
  }
184
226
  }
227
+
228
+ private static IEnumerable<string> GetAnalyzerArguments()
229
+ {
230
+ HashSet<string> yielded = new(StringComparer.OrdinalIgnoreCase);
231
+ string projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
232
+
233
+ foreach (string directory in AnalyzerDirectories)
234
+ {
235
+ foreach (string dllName in RequiredDllNames)
236
+ {
237
+ string absoluteDirectory = Path.IsPathRooted(directory)
238
+ ? directory
239
+ : Path.GetFullPath(Path.Combine(projectRoot, directory));
240
+
241
+ string absoluteAnalyzerPath = Path.Combine(absoluteDirectory, dllName);
242
+ if (!File.Exists(absoluteAnalyzerPath))
243
+ {
244
+ continue;
245
+ }
246
+
247
+ string projectRelativePath = FileUtil.GetProjectRelativePath(
248
+ absoluteAnalyzerPath
249
+ );
250
+ if (string.IsNullOrEmpty(projectRelativePath))
251
+ {
252
+ continue;
253
+ }
254
+
255
+ string normalizedRelativePath = projectRelativePath.Replace("\\", "/");
256
+ if (!yielded.Add(normalizedRelativePath))
257
+ {
258
+ continue;
259
+ }
260
+
261
+ yield return $"-a:\"{normalizedRelativePath}\"";
262
+ }
263
+ }
264
+ }
185
265
  }
186
266
  }
187
267
  #endif