com.wallstop-studios.dxmessaging 3.2.0 → 3.2.1

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 (61) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +8 -8
  3. package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +171 -13
  4. package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +391 -96
  5. package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs +279 -0
  6. package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs.meta +11 -0
  7. package/Editor/DxMessagingEditorPalette.cs +66 -0
  8. package/Editor/DxMessagingEditorPalette.cs.meta +11 -0
  9. package/Editor/DxMessagingEditorTheme.cs +200 -0
  10. package/Editor/DxMessagingEditorTheme.cs.meta +11 -0
  11. package/Editor/Icons/dxmessaging-icon-256.png +0 -0
  12. package/Editor/Icons/dxmessaging-icon-256.png.meta +156 -0
  13. package/Editor/Icons/dxmessaging-icon-32.png +0 -0
  14. package/Editor/Icons/dxmessaging-icon-32.png.meta +156 -0
  15. package/Editor/Icons/dxmessaging-icon-48.png +0 -0
  16. package/Editor/Icons/dxmessaging-icon-48.png.meta +156 -0
  17. package/Editor/Icons.meta +8 -0
  18. package/Editor/Settings/DxMessagingSettingsProvider.cs +368 -33
  19. package/Editor/Testing/MessagingComponentEditorHarness.cs +11 -4
  20. package/Editor/Theme/DxMessagingTheme.uss +255 -0
  21. package/Editor/Theme/DxMessagingTheme.uss.meta +11 -0
  22. package/Editor/Theme/DxTokens.uss +90 -0
  23. package/Editor/Theme/DxTokens.uss.meta +11 -0
  24. package/Editor/Theme.meta +8 -0
  25. package/Editor/Windows/DxMessagingFlowGraphWindow.cs +5513 -0
  26. package/Editor/Windows/DxMessagingFlowGraphWindow.cs.meta +11 -0
  27. package/Editor/Windows/DxMessagingMessageMonitorWindow.cs +2288 -0
  28. package/Editor/Windows/DxMessagingMessageMonitorWindow.cs.meta +11 -0
  29. package/Editor/Windows.meta +8 -0
  30. package/README.md +84 -35
  31. package/Runtime/AssemblyInfo.cs +1 -0
  32. package/Runtime/Core/Diagnostics/MessageEmissionData.cs +29 -1
  33. package/Runtime/Core/Extensions/MessageExtensions.cs +4 -5
  34. package/Runtime/Core/Helper/MessageCache.cs +56 -23
  35. package/Runtime/Core/Internal/FlatDispatch.cs +32 -0
  36. package/Runtime/Core/Internal/TypedSlots.cs +3 -7
  37. package/Runtime/Core/MessageBus/MessageBus.cs +577 -142
  38. package/Runtime/Core/MessageBus/RegistrationLog.cs +25 -12
  39. package/Runtime/Core/MessageHandler.cs +774 -786
  40. package/Runtime/Core/MessageRegistrationHandle.cs +19 -5
  41. package/Runtime/Core/MessageRegistrationToken.cs +1080 -520
  42. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs +173 -0
  43. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs.meta +11 -0
  44. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity +424 -0
  45. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity.meta +7 -0
  46. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs +185 -0
  47. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs.meta +11 -0
  48. package/Samples~/Diagnostics Tooling Exerciser/Messages.cs +46 -0
  49. package/Samples~/Diagnostics Tooling Exerciser/Messages.cs.meta +11 -0
  50. package/Samples~/Diagnostics Tooling Exerciser/README.md +53 -0
  51. package/Samples~/Diagnostics Tooling Exerciser/README.md.meta +7 -0
  52. package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef +13 -0
  53. package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef.meta +7 -0
  54. package/Samples~/Diagnostics Tooling Exerciser.meta +8 -0
  55. package/Samples~/Mini Combat/README.md +1 -1
  56. package/Samples~/Mini Combat/Walkthrough.md +3 -3
  57. package/docs/images/DxMessaging-banner.svg +79 -0
  58. package/docs/images/DxMessaging-banner.svg.meta +53 -0
  59. package/docs/images.meta +8 -0
  60. package/docs.meta +8 -0
  61. package/package.json +13 -4
package/CHANGELOG.md CHANGED
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.2.1]
11
+
12
+ ### Changed
13
+
14
+ - Removed the dead typed `MessageHandler.Handle*` callback methods and internalized the
15
+ three global callbacks still used by the message bus. These methods were nominally
16
+ public plumbing rather than supported registration APIs; bus dispatch and token
17
+ registration behavior are unchanged.
18
+ - Refreshed the README banner (`docs/images/DxMessaging-banner.svg`): added
19
+ vertical separation between the tagline and the badge row, replaced the badges
20
+ with **Simple**, **MIT**, and the synced version, and re-drew the right panel
21
+ as one bus spine dispatching three aligned, color-coded message dots along
22
+ routes to labeled **Untargeted**, **Targeted**, and **Broadcast** destinations.
23
+ - Simplified banner sync (`scripts/sync-banner-version.js`) to track only the
24
+ package version; the auto-derived test-count badge and its file-walking logic
25
+ were removed, along with the now-unneeded test-source triggers in the CI banner
26
+ gate and the pre-commit hook.
27
+
28
+ ### Added
29
+
30
+ - Added a **Diagnostics Tooling Exerciser** sample scene that deterministically
31
+ drives Message Monitor, Flow Graph, Inspector diagnostics, and Project
32
+ Settings with untargeted, targeted, broadcast, exact-source broadcast,
33
+ broadcast-without-source, and `RegisterGlobalAcceptAll` routes.
34
+ - Project Settings now exposes the **Ignored Base-Call Types** list under
35
+ Inspector Checks, so project-level base-call suppressions can be reviewed and
36
+ edited from the same settings page as the overlay toggles.
37
+ - Flow Graph now includes visible trace-id lanes and visible trace route-kind
38
+ lanes over visible trace paths, reporting path-membership breadth or
39
+ route-kind delivery breadth plus message, target, and context details without
40
+ changing export schema v5.
41
+ - Message Monitor now includes visible message-type and context lanes over the
42
+ current filter, reporting entry counts, distinct context/message breadth,
43
+ entry share, context lists, message lists, and row-level Filter shortcuts,
44
+ including exact quoted context shortcuts, without changing JSON export.
45
+ - Message Monitor filtering now supports typed `type:`, `message:`,
46
+ `context:`, and `stack:` facets over captured entry fields while preserving
47
+ existing plain text matching, supports quoted typed values with spaces, and
48
+ displays the active typed or plain filter with a Clear action.
49
+
10
50
  ## [3.2.0]
11
51
 
12
52
  ### Added
@@ -84,13 +84,13 @@ namespace DxMessaging.Editor.Analyzers
84
84
  /// </para>
85
85
  /// <para>
86
86
  /// The inspector overlay reads its snapshot from the unified per-FQN map populated here on
87
- /// every rescan. Use the menu <c>Tools > DxMessaging > Rescan Base-Call Warnings</c> for a
87
+ /// every rescan. Use the menu <c>Tools > Wallstop Studios > DxMessaging > Rescan Base-Call Warnings</c> for a
88
88
  /// manual force-rescan.
89
89
  /// </para>
90
90
  /// <para>
91
91
  /// <see cref="IsAvailable"/> stays <c>true</c> as long as the static constructor itself does
92
92
  /// not throw -- the IL scanner is always wired, so the overlay never falls back to its
93
- /// degraded "harvester unavailable" HelpBox in normal operation. <see cref="LogEntriesAvailable"/>
93
+ /// degraded "harvester unavailable" warning surface in normal operation. <see cref="LogEntriesAvailable"/>
94
94
  /// continues to report whether the legacy reflection layer is bindable, for diagnostics only.
95
95
  /// </para>
96
96
  /// </remarks>
@@ -187,7 +187,7 @@ namespace DxMessaging.Editor.Analyzers
187
187
  // or whether it was loaded eagerly from `Library/DxMessaging/baseCallReport.json` in the
188
188
  // static ctor and has not yet been overwritten. The inspector overlay reads this to
189
189
  // distinguish "fresh-this-session" warnings from cached-from-previous-session warnings;
190
- // when the cache is showing, we annotate the HelpBox with a small suffix so the user
190
+ // when the cache is showing, we annotate the warning surface so the user
191
191
  // understands the data may be stale until the first post-reload scan completes.
192
192
  //
193
193
  // Default `false`: the static ctor's `LoadFromDisk` runs first, so by the time anything
@@ -241,7 +241,7 @@ namespace DxMessaging.Editor.Analyzers
241
241
  /// constructor itself throws (a hard initialization failure). The LogEntries reflection
242
242
  /// layer is the optional source -- see <see cref="LogEntriesAvailable"/> for that flag.
243
243
  /// The inspector overlay reads this property to decide whether to render its degraded
244
- /// HelpBox, so the contract here is "should the overlay attempt to render at all".
244
+ /// warning surface, so the contract here is "should the overlay attempt to render at all".
245
245
  /// </remarks>
246
246
  public static bool IsAvailable { get; private set; } = true;
247
247
 
@@ -259,11 +259,11 @@ namespace DxMessaging.Editor.Analyzers
259
259
  /// loaded eagerly by the static constructor.
260
260
  /// </summary>
261
261
  /// <remarks>
262
- /// The inspector overlay reads this to annotate its HelpBox: when <c>false</c> AND a
263
- /// warning is being shown, the overlay appends a "(cached from previous session --
264
- /// refreshing...)" suffix so the user knows the data is from yesterday's scan and a fresh
262
+ /// The inspector overlay reads this to annotate its warning surface: when <c>false</c> AND a
263
+ /// warning is being shown, the overlay adds a "Report is cached from previous session;
264
+ /// refreshing..." note so the user knows the data is from yesterday's scan and a fresh
265
265
  /// one is in flight. The flag is set inside <see cref="RescanNow"/> and never reset, so
266
- /// the suffix disappears as soon as the first post-reload scan lands and stays gone for
266
+ /// the note disappears as soon as the first post-reload scan lands and stays gone for
267
267
  /// the rest of the session.
268
268
  /// </remarks>
269
269
  public static bool IsFreshThisSession => _isFreshThisSession;
@@ -1,14 +1,17 @@
1
1
  namespace DxMessaging.Editor.CustomEditors
2
2
  {
3
3
  #if UNITY_EDITOR
4
+ using System;
5
+ using DxMessaging.Editor.Analyzers;
4
6
  using DxMessaging.Unity;
5
7
  using UnityEditor;
8
+ using UnityEditor.UIElements;
9
+ using UnityEngine.UIElements;
6
10
 
7
11
  /// <summary>
8
- /// Primary CustomEditor for every <see cref="MessageAwareComponent"/> subclass. Renders the
9
- /// DxMessaging warning HelpBox above an inspector body that is byte-for-byte identical to
10
- /// Unity's default <c>GenericInspector</c> (achieved via
11
- /// <see cref="Editor.DrawDefaultInspector"/>).
12
+ /// Primary CustomEditor for every <see cref="MessageAwareComponent"/> subclass. Hosts the
13
+ /// DxMessaging warning above a default inspector body that keeps Unity's serialized field
14
+ /// surface intact.
12
15
  /// </summary>
13
16
  /// <remarks>
14
17
  /// We register as a non-fallback (primary) editor with
@@ -33,20 +36,20 @@ namespace DxMessaging.Editor.CustomEditors
33
36
  /// </list>
34
37
  ///
35
38
  /// <para>
36
- /// The current design is the simple one: be the primary editor, prepend the overlay's
37
- /// HelpBox via <see cref="MessageAwareComponentInspectorOverlay.RenderInsideOnInspectorGUI"/>,
38
- /// then call <see cref="Editor.DrawDefaultInspector"/>. The body therefore matches
39
- /// <c>GenericInspector</c> exactly: no missing Script row, no extra vertical gap. To avoid
40
- /// double-rendering when the header hook ALSO fires for our editor instance (Unity 2022+),
39
+ /// The current primary path is <see cref="CreateInspectorGUI"/>: it hosts the UI Toolkit
40
+ /// warning view, then fills Unity's default Inspector body through
41
+ /// <see cref="InspectorElement.FillDefaultInspector"/> so the disabled Script row and
42
+ /// serialized fields remain present. To avoid double-rendering when the header hook ALSO
43
+ /// fires for our editor instance (Unity 2022+),
41
44
  /// <see cref="MessageAwareComponentInspectorOverlay"/> unconditionally skips the header path
42
45
  /// for <see cref="MessageAwareComponentFallbackEditor"/> instances.
43
46
  /// </para>
44
47
  ///
45
48
  /// <para>
46
- /// We do NOT short-circuit <see cref="OnInspectorGUI"/> on event type. Unity invokes
47
- /// editors twice per frame (Layout + Repaint), and both passes MUST emit identical control
48
- /// counts, otherwise the inspector window's layout cache is corrupted and adjacent
49
- /// components fail to render. See
49
+ /// <see cref="OnInspectorGUI"/> remains as an IMGUI compatibility fallback. We do NOT
50
+ /// short-circuit it on event type. Unity invokes editors twice per frame (Layout + Repaint),
51
+ /// and both passes MUST emit identical control counts, otherwise the inspector window's layout
52
+ /// cache is corrupted and adjacent components fail to render. See
50
53
  /// <see cref="MessageAwareComponentInspectorOverlay.RenderInsideOnInspectorGUI"/> for the
51
54
  /// matching invariant on the overlay side.
52
55
  /// </para>
@@ -63,6 +66,23 @@ namespace DxMessaging.Editor.CustomEditors
63
66
  [CanEditMultipleObjects]
64
67
  public sealed class MessageAwareComponentFallbackEditor : Editor
65
68
  {
69
+ internal const string RootName = "dxmessaging-fallback-inspector";
70
+ internal const string RootClassName = "dxmessaging-fallback-inspector";
71
+ internal const string WarningHostName = "dxmessaging-fallback-inspector-warning-host";
72
+ internal const string WarningHostClassName = "dxmessaging-fallback-inspector-warning-host";
73
+ internal const string DefaultInspectorBodyName =
74
+ "dxmessaging-fallback-inspector-default-body";
75
+ internal const string DefaultInspectorBodyClassName =
76
+ "dxmessaging-fallback-inspector-default-body";
77
+
78
+ public override VisualElement CreateInspectorGUI()
79
+ {
80
+ return BuildInspectorGUI(
81
+ this,
82
+ () => MessageAwareComponentInspectorOverlay.ResolveInspectorState(target)
83
+ );
84
+ }
85
+
66
86
  public override void OnInspectorGUI()
67
87
  {
68
88
  // Render the overlay BEFORE the default body so the warning appears prominently at
@@ -76,6 +96,144 @@ namespace DxMessaging.Editor.CustomEditors
76
96
  // [SerializeField] fields.
77
97
  DrawDefaultInspector();
78
98
  }
99
+
100
+ internal static VisualElement BuildInspectorGUI(
101
+ Editor editor,
102
+ Func<MessageAwareComponentInspectorState> resolveState
103
+ )
104
+ {
105
+ if (editor == null)
106
+ {
107
+ throw new ArgumentNullException(nameof(editor));
108
+ }
109
+ if (resolveState == null)
110
+ {
111
+ throw new ArgumentNullException(nameof(resolveState));
112
+ }
113
+
114
+ VisualElement root = new() { name = RootName };
115
+ DxMessagingEditorTheme.Apply(root);
116
+ root.AddToClassList(RootClassName);
117
+
118
+ VisualElement warningHost = new() { name = WarningHostName };
119
+ warningHost.AddToClassList(WarningHostClassName);
120
+ root.Add(warningHost);
121
+
122
+ InspectorWarningBinding binding = new(warningHost, resolveState);
123
+ root.userData = binding;
124
+ binding.Refresh();
125
+
126
+ VisualElement defaultBody = new() { name = DefaultInspectorBodyName };
127
+ defaultBody.AddToClassList(DefaultInspectorBodyClassName);
128
+ InspectorElement.FillDefaultInspector(defaultBody, editor.serializedObject, editor);
129
+ root.Add(defaultBody);
130
+
131
+ root.RegisterCallback<AttachToPanelEvent>(_ => binding.Connect());
132
+ root.RegisterCallback<DetachFromPanelEvent>(_ => binding.Disconnect());
133
+
134
+ return root;
135
+ }
136
+
137
+ internal static void RefreshInspectorWarning(VisualElement root)
138
+ {
139
+ if (root == null)
140
+ {
141
+ throw new ArgumentNullException(nameof(root));
142
+ }
143
+ if (root.userData is not InspectorWarningBinding binding)
144
+ {
145
+ throw new InvalidOperationException(
146
+ "Fallback inspector root is missing its warning binding."
147
+ );
148
+ }
149
+
150
+ binding.Refresh();
151
+ }
152
+
153
+ private sealed class InspectorWarningBinding
154
+ {
155
+ private readonly VisualElement _warningHost;
156
+ private readonly Func<MessageAwareComponentInspectorState> _resolveState;
157
+ private bool _connected;
158
+ private bool _refreshRetryScheduled;
159
+
160
+ internal InspectorWarningBinding(
161
+ VisualElement warningHost,
162
+ Func<MessageAwareComponentInspectorState> resolveState
163
+ )
164
+ {
165
+ _warningHost = warningHost ?? throw new ArgumentNullException(nameof(warningHost));
166
+ _resolveState =
167
+ resolveState ?? throw new ArgumentNullException(nameof(resolveState));
168
+ }
169
+
170
+ internal void Connect()
171
+ {
172
+ if (_connected)
173
+ {
174
+ return;
175
+ }
176
+
177
+ DxMessagingConsoleHarvester.ReportUpdated += Refresh;
178
+ MessageAwareComponentInspectorOverlay.InspectorStateInvalidated += Refresh;
179
+ _connected = true;
180
+ Refresh();
181
+ }
182
+
183
+ internal void Disconnect()
184
+ {
185
+ if (!_connected)
186
+ {
187
+ return;
188
+ }
189
+
190
+ DxMessagingConsoleHarvester.ReportUpdated -= Refresh;
191
+ MessageAwareComponentInspectorOverlay.InspectorStateInvalidated -= Refresh;
192
+ _connected = false;
193
+ }
194
+
195
+ internal void Refresh()
196
+ {
197
+ MessageAwareComponentInspectorState state = _resolveState();
198
+ if (state.Kind == MessageAwareComponentInspectorStateKind.None)
199
+ {
200
+ if (
201
+ MessageAwareComponentInspectorOverlay.IsInspectorResolutionTransientlyBlocked()
202
+ )
203
+ {
204
+ ScheduleRefreshRetry();
205
+ return;
206
+ }
207
+
208
+ _warningHost.Clear();
209
+ _warningHost.style.display = DisplayStyle.None;
210
+ return;
211
+ }
212
+
213
+ _refreshRetryScheduled = false;
214
+ _warningHost.Clear();
215
+ _warningHost.style.display = DisplayStyle.Flex;
216
+ _warningHost.Add(MessageAwareComponentInspectorOverlay.CreateInspectorView(state));
217
+ }
218
+
219
+ private void ScheduleRefreshRetry()
220
+ {
221
+ if (_refreshRetryScheduled)
222
+ {
223
+ return;
224
+ }
225
+
226
+ _refreshRetryScheduled = true;
227
+ System.Action<System.Action> schedule =
228
+ MessageAwareComponentInspectorOverlay.TransientRefreshScheduler
229
+ ?? DxMessagingEditorIdle.ScheduleAssetDatabaseMutation;
230
+ schedule(() =>
231
+ {
232
+ _refreshRetryScheduled = false;
233
+ Refresh();
234
+ });
235
+ }
236
+ }
79
237
  }
80
238
  #endif
81
239
  }