com.wallstop-studios.dxmessaging 2.1.0 → 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.
- package/.github/workflows/dotnet-tests.yml +72 -0
- package/.lychee.toml +4 -2
- package/AGENTS.md +1 -0
- package/Docs/Comparisons.md +4 -4
- package/Docs/EmitShorthands.md +2 -2
- package/Docs/Helpers.md +90 -75
- package/Docs/Install.md +2 -1
- package/Docs/Patterns.md +1 -1
- package/Docs/Performance.md +13 -11
- package/Docs/QuickStart.md +1 -2
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +13 -2
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +11 -0
- package/Editor/Analyzers/System.Collections.Immutable.dll +0 -0
- package/Editor/Analyzers/System.Collections.Immutable.dll.meta +11 -0
- package/Editor/Analyzers/System.Reflection.Metadata.dll +0 -0
- package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +13 -2
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +11 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +3 -2
- package/Editor/AssemblyInfo.cs +3 -0
- package/Editor/AssemblyInfo.cs.meta +3 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +21 -0
- package/Editor/SetupCscRsp.cs +133 -53
- package/Editor/Testing/MessagingComponentEditorHarness.cs +218 -0
- package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +3 -0
- package/Editor/Testing.meta +3 -0
- package/README.md +9 -3
- package/Runtime/AssemblyInfo.cs +1 -0
- package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs +1 -1
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs +26 -11
- package/Runtime/Core/Extensions/MessageBusExtensions.cs +2 -2
- package/Runtime/Core/Extensions/MessageExtensions.cs +2 -2
- package/Runtime/Core/InstanceId.cs +5 -3
- package/Runtime/Core/MessageBus/MessageBus.cs +4 -4
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +2 -2
- package/Runtime/Core/MessageBus/MessagingRegistration.cs +3 -3
- package/Runtime/Core/MessageHandler.cs +34 -2
- package/Runtime/Core/MessageRegistrationToken.cs +2 -2
- package/Runtime/Core/Messages/IBroadcastMessage.cs +1 -1
- package/Runtime/Core/Messages/ITargetedMessage.cs +1 -1
- package/Runtime/Core/Messages/IUntargetedMessage.cs +1 -1
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +2 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +2 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +2 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +2 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +2 -0
- package/Runtime/Unity/MessageAwareComponent.cs +2 -0
- package/Runtime/Unity/MessageBusProviderHandle.cs +4 -0
- package/Runtime/Unity/MessagingComponent.cs +27 -7
- package/Runtime/Unity/MessagingComponentInstaller.cs +2 -0
- package/Runtime/Unity/ScriptableMessageBusProvider.cs +2 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs +6 -6
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs +7 -9
- package/Samples~/DI/Zenject/SampleInstaller.cs +6 -8
- package/SourceGenerators/Directory.Build.props +9 -0
- package/{package-lock.json.meta → SourceGenerators/Directory.Build.props.meta} +2 -2
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +19 -24
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +87 -27
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +24 -4
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DocsSnippetCompilationTests.cs +193 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DocsSnippetCompilationTests.cs.meta +11 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxAutoConstructorGeneratorDiagnosticsTests.cs +69 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxAutoConstructorGeneratorDiagnosticsTests.cs.meta +11 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxMessageIdGeneratorDiagnosticsTests.cs +66 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/DxMessageIdGeneratorDiagnosticsTests.cs.meta +11 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/GeneratorTestUtilities.cs +155 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/GeneratorTestUtilities.cs.meta +11 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj +20 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests/WallstopStudios.DxMessaging.SourceGenerators.Tests.csproj.meta +7 -0
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.Tests.meta +8 -0
- package/Tests/Editor/MessagingComponentEditorHarnessTests.cs +243 -0
- package/Tests/Editor/MessagingComponentEditorHarnessTests.cs.meta +3 -0
- package/Tests/Editor/MessagingComponentSerializationTests.cs +129 -0
- package/Tests/Editor/MessagingComponentSerializationTests.cs.meta +3 -0
- package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef +19 -0
- package/Tests/Editor/WallstopStudios.DxMessaging.Tests.Editor.asmdef.meta +3 -0
- package/Tests/Editor.meta +3 -0
- package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +3 -0
- package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +3 -0
- package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +3 -0
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +137 -0
- package/Tests/Runtime/Core/AlternateBusTests.cs +3 -0
- package/Tests/Runtime/Core/BroadcastTests.cs +3 -0
- package/Tests/Runtime/Core/CyclicBufferTests.cs +3 -0
- package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +5 -2
- package/Tests/Runtime/Core/DiagnosticsTests.cs +3 -0
- package/Tests/Runtime/Core/EdgeCaseTests.cs +3 -0
- package/Tests/Runtime/Core/EnablementTests.cs +3 -0
- package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +2 -2
- package/Tests/Runtime/Core/GenericMessageTests.cs +3 -0
- package/Tests/Runtime/Core/GlobalAcceptAllTests.cs +3 -0
- package/Tests/Runtime/Core/InterceptorCancellationTests.cs +3 -0
- package/Tests/Runtime/Core/LifecycleTests.cs +3 -0
- package/Tests/Runtime/Core/MessageEmissionDataTests.cs +70 -0
- package/Tests/Runtime/Core/MessageEmissionDataTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessagingComponentLifecycleTests.cs +3 -0
- package/Tests/Runtime/Core/MessagingTestBase.cs +3 -0
- package/Tests/Runtime/Core/MutationDedupeTests.cs +3 -0
- package/Tests/Runtime/Core/MutationDestructionTests.cs +3 -0
- package/Tests/Runtime/Core/MutationDuringEmissionTests.cs +3 -0
- package/Tests/Runtime/Core/MutationGlobalAddTests.cs +3 -0
- package/Tests/Runtime/Core/MutationInterceptorTests.cs +3 -0
- package/Tests/Runtime/Core/MutationPostProcessorAcrossHandlersTests.cs +3 -0
- package/Tests/Runtime/Core/MutationPostProcessorMoreTests.cs +3 -0
- package/Tests/Runtime/Core/MutationPriorityTests.cs +3 -0
- package/Tests/Runtime/Core/NominalTests.cs +3 -0
- package/Tests/Runtime/Core/OrderingTests.cs +3 -0
- package/Tests/Runtime/Core/OverDeregistrationTests.cs +3 -0
- package/Tests/Runtime/Core/PostProcessorTests.cs +3 -0
- package/Tests/Runtime/Core/ReflexiveErrorTests.cs +3 -0
- package/Tests/Runtime/Core/ReflexiveMessageWarningTests.cs +4 -1
- package/Tests/Runtime/Core/ReflexiveTests.cs +3 -0
- package/Tests/Runtime/Core/RegistrationTests.cs +3 -0
- package/Tests/Runtime/Core/StringShorthandTests.cs +3 -0
- package/Tests/Runtime/Core/TargetedTests.cs +3 -0
- package/Tests/Runtime/Core/TypedShorthandTests.cs +3 -0
- package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +3 -0
- package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +14 -78
- package/Tests/Runtime/Core/UntargetedTests.cs +3 -0
- package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +4 -1
- package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +3 -0
- package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +3 -0
- package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +3 -0
- package/Tests/Runtime/Scripts/Components/ManualListenerComponent.cs +3 -0
- package/Tests/Runtime/Scripts/Components/ReflexiveReceiverComponent.cs +3 -0
- package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +3 -0
- package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +3 -0
- package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +87 -3
- package/Tests/Runtime/Unity/MessagingComponentInstallerSceneTests.cs +109 -0
- package/Tests/Runtime/Unity/MessagingComponentInstallerSceneTests.cs.meta +11 -0
- package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +159 -17
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj +20 -7
- package/package.json +1 -1
package/Editor/SetupCscRsp.cs
CHANGED
|
@@ -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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
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
|
-
|
|
82
|
-
|
|
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
|
-
|
|
103
|
+
bool needsCopy = FilesDiffer(sourceFile, outputAsset);
|
|
104
|
+
if (needsCopy)
|
|
102
105
|
{
|
|
103
|
-
File.Copy(
|
|
106
|
+
File.Copy(sourceFile, outputAsset, true);
|
|
104
107
|
AssetDatabase.ImportAsset(outputAsset);
|
|
105
|
-
found = true;
|
|
106
108
|
}
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
FileInfo destInfo = new(outputAsset);
|
|
127
|
+
bool importerDirty = false;
|
|
111
128
|
|
|
112
|
-
if (
|
|
129
|
+
if (importer.GetCompatibleWithAnyPlatform())
|
|
113
130
|
{
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
AssetDatabase.ImportAsset(outputAsset);
|
|
117
|
-
found = true;
|
|
131
|
+
importer.SetCompatibleWithAnyPlatform(false);
|
|
132
|
+
importerDirty = true;
|
|
118
133
|
}
|
|
119
|
-
|
|
134
|
+
|
|
135
|
+
if (importer.GetExcludeFromAnyPlatform("Editor"))
|
|
120
136
|
{
|
|
121
|
-
|
|
137
|
+
importer.SetExcludeFromAnyPlatform("Editor", false);
|
|
138
|
+
importerDirty = true;
|
|
122
139
|
}
|
|
123
|
-
}
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
141
|
+
if (!importer.GetExcludeFromAnyPlatform("Standalone"))
|
|
142
|
+
{
|
|
143
|
+
importer.SetExcludeFromAnyPlatform("Standalone", true);
|
|
144
|
+
importerDirty = true;
|
|
145
|
+
}
|
|
130
146
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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 (
|
|
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
|
-
|
|
204
|
+
bool modified = false;
|
|
205
|
+
foreach (string analyzerArgument in GetAnalyzerArguments())
|
|
172
206
|
{
|
|
173
|
-
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#if UNITY_EDITOR
|
|
2
|
+
namespace DxMessaging.Editor.Testing
|
|
3
|
+
{
|
|
4
|
+
using System;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Linq;
|
|
7
|
+
using Core;
|
|
8
|
+
using Core.Diagnostics;
|
|
9
|
+
using Core.MessageBus;
|
|
10
|
+
using Unity;
|
|
11
|
+
using UnityEngine;
|
|
12
|
+
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Captures inspector-oriented diagnostics for <see cref="MessagingComponent"/> instances without relying on GUI APIs.
|
|
15
|
+
/// Intended for automated editor tests that need to validate inspector state transitions.
|
|
16
|
+
/// </summary>
|
|
17
|
+
internal static class MessagingComponentEditorHarness
|
|
18
|
+
{
|
|
19
|
+
private static readonly MessageEmissionData[] EmptyEmissions =
|
|
20
|
+
Array.Empty<MessageEmissionData>();
|
|
21
|
+
|
|
22
|
+
internal static MessagingComponentInspectorState Capture(MessagingComponent component)
|
|
23
|
+
{
|
|
24
|
+
if (component == null)
|
|
25
|
+
{
|
|
26
|
+
throw new ArgumentNullException(nameof(component));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
bool globalDiagnosticsEnabled = false;
|
|
30
|
+
IReadOnlyList<MessageEmissionData> globalHistory = EmptyEmissions;
|
|
31
|
+
|
|
32
|
+
if (MessageHandler.MessageBus is MessageBus concreteBus)
|
|
33
|
+
{
|
|
34
|
+
globalDiagnosticsEnabled = concreteBus.DiagnosticsMode;
|
|
35
|
+
if (globalDiagnosticsEnabled && concreteBus._emissionBuffer.Count > 0)
|
|
36
|
+
{
|
|
37
|
+
globalHistory = concreteBus._emissionBuffer.ToArray();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
List<ListenerDiagnosticsView> listenerViews = component
|
|
42
|
+
._registeredListeners.OrderBy(pair => pair.Key.GetInstanceID())
|
|
43
|
+
.Select(pair => CreateListenerView(pair.Key, pair.Value))
|
|
44
|
+
.ToList();
|
|
45
|
+
|
|
46
|
+
ProviderDiagnosticsView providerDiagnostics = CreateProviderDiagnostics(component);
|
|
47
|
+
|
|
48
|
+
return new MessagingComponentInspectorState(
|
|
49
|
+
globalDiagnosticsEnabled,
|
|
50
|
+
globalHistory,
|
|
51
|
+
listenerViews,
|
|
52
|
+
providerDiagnostics
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private static ListenerDiagnosticsView CreateListenerView(
|
|
57
|
+
MonoBehaviour listener,
|
|
58
|
+
MessageRegistrationToken token
|
|
59
|
+
)
|
|
60
|
+
{
|
|
61
|
+
MessageRegistrationView[] registrations = token
|
|
62
|
+
._metadata.OrderBy(pair => pair.Key)
|
|
63
|
+
.Select(pair => new MessageRegistrationView(
|
|
64
|
+
pair.Key,
|
|
65
|
+
pair.Value,
|
|
66
|
+
token._callCounts.TryGetValue(pair.Key, out int callCount) ? callCount : 0
|
|
67
|
+
))
|
|
68
|
+
.ToArray();
|
|
69
|
+
|
|
70
|
+
IReadOnlyList<MessageEmissionData> emissionHistory =
|
|
71
|
+
token._emissionBuffer.Count > 0 ? token._emissionBuffer.ToArray() : EmptyEmissions;
|
|
72
|
+
|
|
73
|
+
return new ListenerDiagnosticsView(
|
|
74
|
+
listener,
|
|
75
|
+
token.DiagnosticMode,
|
|
76
|
+
token.Enabled,
|
|
77
|
+
registrations,
|
|
78
|
+
emissionHistory
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
internal static ProviderDiagnosticsView CreateProviderDiagnostics(
|
|
83
|
+
MessagingComponent component
|
|
84
|
+
)
|
|
85
|
+
{
|
|
86
|
+
bool autoConfigure = component.AutoConfigureSerializedProviderOnAwake;
|
|
87
|
+
bool hasSerializedProvider =
|
|
88
|
+
component.SerializedProviderAsset != null || component.HasSerializedProvider;
|
|
89
|
+
bool hasRuntimeProvider = component.HasRuntimeProvider;
|
|
90
|
+
bool hasMessageBusOverride = component.HasMessageBusOverride;
|
|
91
|
+
bool serializedProviderMissingWarning = autoConfigure && !hasSerializedProvider;
|
|
92
|
+
|
|
93
|
+
bool serializedProviderNullBusWarning = false;
|
|
94
|
+
if (hasSerializedProvider)
|
|
95
|
+
{
|
|
96
|
+
IMessageBus resolvedBus = component.SerializedProviderHandle.ResolveBus();
|
|
97
|
+
serializedProviderNullBusWarning = resolvedBus == null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return new ProviderDiagnosticsView(
|
|
101
|
+
autoConfigure,
|
|
102
|
+
hasSerializedProvider,
|
|
103
|
+
hasRuntimeProvider,
|
|
104
|
+
hasMessageBusOverride,
|
|
105
|
+
serializedProviderMissingWarning,
|
|
106
|
+
serializedProviderNullBusWarning
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
internal sealed class MessagingComponentInspectorState
|
|
112
|
+
{
|
|
113
|
+
internal MessagingComponentInspectorState(
|
|
114
|
+
bool globalDiagnosticsEnabled,
|
|
115
|
+
IReadOnlyList<MessageEmissionData> globalEmissionHistory,
|
|
116
|
+
IReadOnlyList<ListenerDiagnosticsView> listeners,
|
|
117
|
+
ProviderDiagnosticsView providerDiagnostics
|
|
118
|
+
)
|
|
119
|
+
{
|
|
120
|
+
GlobalDiagnosticsEnabled = globalDiagnosticsEnabled;
|
|
121
|
+
GlobalEmissionHistory =
|
|
122
|
+
globalEmissionHistory
|
|
123
|
+
?? throw new ArgumentNullException(nameof(globalEmissionHistory));
|
|
124
|
+
Listeners = listeners ?? throw new ArgumentNullException(nameof(listeners));
|
|
125
|
+
ProviderDiagnostics = providerDiagnostics;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
internal bool GlobalDiagnosticsEnabled { get; }
|
|
129
|
+
|
|
130
|
+
internal IReadOnlyList<MessageEmissionData> GlobalEmissionHistory { get; }
|
|
131
|
+
|
|
132
|
+
internal IReadOnlyList<ListenerDiagnosticsView> Listeners { get; }
|
|
133
|
+
|
|
134
|
+
internal ProviderDiagnosticsView ProviderDiagnostics { get; }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
internal sealed class ListenerDiagnosticsView
|
|
138
|
+
{
|
|
139
|
+
internal ListenerDiagnosticsView(
|
|
140
|
+
MonoBehaviour listener,
|
|
141
|
+
bool diagnosticsEnabled,
|
|
142
|
+
bool tokenEnabled,
|
|
143
|
+
IReadOnlyList<MessageRegistrationView> registrations,
|
|
144
|
+
IReadOnlyList<MessageEmissionData> emissionHistory
|
|
145
|
+
)
|
|
146
|
+
{
|
|
147
|
+
Listener = listener;
|
|
148
|
+
DiagnosticsEnabled = diagnosticsEnabled;
|
|
149
|
+
TokenEnabled = tokenEnabled;
|
|
150
|
+
Registrations = registrations ?? throw new ArgumentNullException(nameof(registrations));
|
|
151
|
+
EmissionHistory =
|
|
152
|
+
emissionHistory ?? throw new ArgumentNullException(nameof(emissionHistory));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
internal MonoBehaviour Listener { get; }
|
|
156
|
+
|
|
157
|
+
internal bool DiagnosticsEnabled { get; }
|
|
158
|
+
|
|
159
|
+
internal bool TokenEnabled { get; }
|
|
160
|
+
|
|
161
|
+
internal IReadOnlyList<MessageRegistrationView> Registrations { get; }
|
|
162
|
+
|
|
163
|
+
internal IReadOnlyList<MessageEmissionData> EmissionHistory { get; }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
internal readonly struct MessageRegistrationView
|
|
167
|
+
{
|
|
168
|
+
internal MessageRegistrationView(
|
|
169
|
+
MessageRegistrationHandle handle,
|
|
170
|
+
MessageRegistrationMetadata metadata,
|
|
171
|
+
int callCount
|
|
172
|
+
)
|
|
173
|
+
{
|
|
174
|
+
Handle = handle;
|
|
175
|
+
Metadata = metadata;
|
|
176
|
+
CallCount = callCount;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
internal MessageRegistrationHandle Handle { get; }
|
|
180
|
+
|
|
181
|
+
internal MessageRegistrationMetadata Metadata { get; }
|
|
182
|
+
|
|
183
|
+
internal int CallCount { get; }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
internal readonly struct ProviderDiagnosticsView
|
|
187
|
+
{
|
|
188
|
+
internal ProviderDiagnosticsView(
|
|
189
|
+
bool autoConfigureSerializedProviderOnAwake,
|
|
190
|
+
bool hasSerializedProvider,
|
|
191
|
+
bool hasRuntimeProvider,
|
|
192
|
+
bool hasMessageBusOverride,
|
|
193
|
+
bool serializedProviderMissingWarning,
|
|
194
|
+
bool serializedProviderNullBusWarning
|
|
195
|
+
)
|
|
196
|
+
{
|
|
197
|
+
AutoConfigureSerializedProviderOnAwake = autoConfigureSerializedProviderOnAwake;
|
|
198
|
+
HasSerializedProvider = hasSerializedProvider;
|
|
199
|
+
HasRuntimeProvider = hasRuntimeProvider;
|
|
200
|
+
HasMessageBusOverride = hasMessageBusOverride;
|
|
201
|
+
SerializedProviderMissingWarning = serializedProviderMissingWarning;
|
|
202
|
+
SerializedProviderNullBusWarning = serializedProviderNullBusWarning;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
internal bool AutoConfigureSerializedProviderOnAwake { get; }
|
|
206
|
+
|
|
207
|
+
internal bool HasSerializedProvider { get; }
|
|
208
|
+
|
|
209
|
+
internal bool HasRuntimeProvider { get; }
|
|
210
|
+
|
|
211
|
+
internal bool HasMessageBusOverride { get; }
|
|
212
|
+
|
|
213
|
+
internal bool SerializedProviderMissingWarning { get; }
|
|
214
|
+
|
|
215
|
+
internal bool SerializedProviderNullBusWarning { get; }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
#endif
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://unity.com/releases/editor)<br/>
|
|
4
4
|
[](LICENSE.md)<br/>
|
|
5
|
-
[](https://www.npmjs.com/package/com.wallstop-studios.dxmessaging)<br/>
|
|
6
6
|
[](Docs/Performance.md)<br/>
|
|
7
7
|
[](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-validity.yml)<br/>
|
|
8
8
|
[](https://github.com/wallstop/DxMessaging/actions/workflows/markdown-link-text-check.yml)
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
Think of it as **the event system Unity should have built-in** — one that actually scales.
|
|
13
13
|
|
|
14
|
+
Need install instructions for Git URLs, scoped registries, or tarballs? Jump to the [Install Guide](Docs/Install.md).
|
|
15
|
+
|
|
14
16
|
## Table of Contents
|
|
15
17
|
|
|
16
18
|
- [30-Second Elevator Pitch](#30-second-elevator-pitch)
|
|
@@ -62,12 +64,15 @@ Think of it as **the event system Unity should have built-in** — one that actu
|
|
|
62
64
|
|
|
63
65
|
### 1. Install
|
|
64
66
|
|
|
65
|
-
Via Unity Package Manager → Add package from git URL:
|
|
67
|
+
Via Unity Package Manager → Add package from git URL (see the [Install Guide](Docs/Install.md) for scoped registry, tarball, and offline options):
|
|
66
68
|
|
|
67
|
-
```
|
|
69
|
+
```bash
|
|
70
|
+
# Unity Package Manager > Add package from git URL...
|
|
68
71
|
https://github.com/wallstop/DxMessaging.git
|
|
69
72
|
```
|
|
70
73
|
|
|
74
|
+
Prefer OpenUPM, scoped registries, or local tarballs? The [Install Guide](Docs/Install.md) covers every path in detail.
|
|
75
|
+
|
|
71
76
|
### 2. Define Your First Message
|
|
72
77
|
|
|
73
78
|
```csharp
|
|
@@ -632,6 +637,7 @@ See [full comparison](Docs/Comparisons.md) for detailed analysis with code examp
|
|
|
632
637
|
|
|
633
638
|
### 📖 Reference
|
|
634
639
|
|
|
640
|
+
- [Install Guide](Docs/Install.md) — All install options (Git URL, scoped registry, tarball, manual copy)
|
|
635
641
|
- [Glossary](Docs/Glossary.md) — All terms explained in plain English
|
|
636
642
|
- [Quick Reference](Docs/QuickReference.md) — Cheat sheet
|
|
637
643
|
- [API Reference](Docs/Reference.md) — Complete API
|
package/Runtime/AssemblyInfo.cs
CHANGED
|
@@ -9,3 +9,4 @@ using System.Runtime.CompilerServices;
|
|
|
9
9
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Runtime.Reflex")]
|
|
10
10
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Runtime.VContainer")]
|
|
11
11
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Runtime.Zenject")]
|
|
12
|
+
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Editor")]
|
|
@@ -14,7 +14,7 @@ namespace DxMessaging.Core.Attributes
|
|
|
14
14
|
/// <code>
|
|
15
15
|
/// [DxMessaging.Core.Attributes.DxUntargetedMessage]
|
|
16
16
|
/// [DxMessaging.Core.Attributes.DxAutoConstructor]
|
|
17
|
-
/// public readonly struct VideoSettingsChanged
|
|
17
|
+
/// public readonly partial struct VideoSettingsChanged
|
|
18
18
|
/// {
|
|
19
19
|
/// public readonly int width;
|
|
20
20
|
/// public readonly int height;
|
|
@@ -13,7 +13,7 @@ namespace DxMessaging.Core.Attributes
|
|
|
13
13
|
/// <example>
|
|
14
14
|
/// <code>
|
|
15
15
|
/// [DxMessaging.Core.Attributes.DxBroadcastMessage]
|
|
16
|
-
/// public readonly struct TookDamage
|
|
16
|
+
/// public readonly partial struct TookDamage
|
|
17
17
|
/// {
|
|
18
18
|
/// public readonly int amount;
|
|
19
19
|
/// public TookDamage(int amount) { this.amount = amount; }
|
|
@@ -12,7 +12,7 @@ namespace DxMessaging.Core.Attributes
|
|
|
12
12
|
/// <example>
|
|
13
13
|
/// <code>
|
|
14
14
|
/// [DxAutoConstructor]
|
|
15
|
-
/// public readonly struct Example
|
|
15
|
+
/// public readonly partial struct Example
|
|
16
16
|
/// {
|
|
17
17
|
/// public readonly int required;
|
|
18
18
|
/// [DxOptionalParameter] public readonly int optional; // defaults to 0
|
|
@@ -14,7 +14,7 @@ namespace DxMessaging.Core.Attributes
|
|
|
14
14
|
/// <example>
|
|
15
15
|
/// <code>
|
|
16
16
|
/// [DxMessaging.Core.Attributes.DxTargetedMessage]
|
|
17
|
-
/// public readonly struct HealRequest
|
|
17
|
+
/// public readonly partial struct HealRequest
|
|
18
18
|
/// {
|
|
19
19
|
/// public readonly int amount;
|
|
20
20
|
/// public HealRequest(int amount) { this.amount = amount; }
|
|
@@ -14,7 +14,7 @@ namespace DxMessaging.Core.Attributes
|
|
|
14
14
|
/// <example>
|
|
15
15
|
/// <code>
|
|
16
16
|
/// [DxMessaging.Core.Attributes.DxUntargetedMessage]
|
|
17
|
-
/// public readonly struct WorldRegenerated
|
|
17
|
+
/// public readonly partial struct WorldRegenerated
|
|
18
18
|
/// {
|
|
19
19
|
/// public readonly int seed;
|
|
20
20
|
/// public WorldRegenerated(int seed) { this.seed = seed; }
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
namespace DxMessaging.Core.Diagnostics
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
|
-
|
|
4
|
+
using System.Linq;
|
|
5
|
+
#if UNITY_2021_3_OR_NEWER
|
|
5
6
|
using UnityEngine;
|
|
7
|
+
#else
|
|
8
|
+
using System.Diagnostics;
|
|
6
9
|
#endif
|
|
7
10
|
|
|
8
11
|
/// <summary>
|
|
@@ -45,7 +48,7 @@ namespace DxMessaging.Core.Diagnostics
|
|
|
45
48
|
private static string GetAccurateStackTrace()
|
|
46
49
|
{
|
|
47
50
|
string fullStackTrace;
|
|
48
|
-
#if
|
|
51
|
+
#if UNITY_2021_3_OR_NEWER
|
|
49
52
|
fullStackTrace = StackTraceUtility.ExtractStackTrace();
|
|
50
53
|
#else
|
|
51
54
|
fullStackTrace = new StackTrace(true).ToString();
|
|
@@ -57,18 +60,30 @@ namespace DxMessaging.Core.Diagnostics
|
|
|
57
60
|
|
|
58
61
|
string[] lines = fullStackTrace.Split(NewlineSeparators, StringSplitOptions.None);
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
string[] trimmedLines = lines
|
|
64
|
+
.Where(line => !string.IsNullOrWhiteSpace(line) && !IsInternalFrame(line))
|
|
65
|
+
.ToArray();
|
|
66
|
+
|
|
67
|
+
return trimmedLines.Length == 0
|
|
68
|
+
? string.Empty
|
|
69
|
+
: string.Join(JoinSeparator, trimmedLines);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private static bool IsInternalFrame(string line)
|
|
73
|
+
{
|
|
74
|
+
if (string.IsNullOrWhiteSpace(line))
|
|
65
75
|
{
|
|
66
|
-
|
|
76
|
+
return false;
|
|
67
77
|
}
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
if (!line.Contains("DxMessaging.", StringComparison.Ordinal))
|
|
80
|
+
{
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return line.Contains("DxMessaging.Core.", StringComparison.Ordinal)
|
|
85
|
+
|| line.Contains("DxMessaging.Unity.", StringComparison.Ordinal)
|
|
86
|
+
|| line.Contains("DxMessaging.Editor.", StringComparison.Ordinal);
|
|
72
87
|
}
|
|
73
88
|
}
|
|
74
89
|
}
|