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.
- package/CHANGELOG.md +211 -2
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +69 -62
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +3 -3
- package/Editor/Analyzers/System.Collections.Immutable.dll.meta +3 -3
- package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +3 -3
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +3 -3
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +15 -2
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +2 -2
- package/Editor/AssemblyInfo.cs.meta +9 -1
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +24 -15
- package/Editor/CustomEditors/MessagingComponentEditor.cs.meta +9 -1
- package/Editor/DxMessagingEditorIdle.cs +62 -0
- package/{Runtime/Core/Internal/TypedDispatchLinkIndex.cs.meta → Editor/DxMessagingEditorIdle.cs.meta} +1 -1
- package/Editor/DxMessagingEditorInitializer.cs +112 -15
- package/Editor/DxMessagingEditorInitializer.cs.meta +9 -1
- package/Editor/DxMessagingEditorLog.cs +32 -0
- package/Editor/DxMessagingEditorLog.cs.meta +11 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +135 -12
- package/Editor/Settings/DxMessagingSettings.cs +92 -31
- package/Editor/Settings/DxMessagingSettings.cs.meta +9 -1
- package/Editor/Settings/DxMessagingSettingsProvider.cs.meta +9 -1
- package/Editor/SetupCscRsp.cs +339 -173
- package/Editor/SetupCscRsp.cs.meta +9 -1
- package/Editor/Testing/MessagingComponentEditorHarness.cs +1 -1
- package/Editor/Testing/MessagingComponentEditorHarness.cs.meta +9 -1
- package/README.md +17 -18
- package/Runtime/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxAutoConstructorAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +2 -4
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +9 -1
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs +56 -0
- package/Runtime/Core/Attributes/Il2CppSetOptionAttribute.cs.meta +11 -0
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +44 -26
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageRegistrationData.cs.meta +9 -1
- package/Runtime/Core/Diagnostics/MessageRegistrationType.cs.meta +9 -1
- package/Runtime/Core/Extensions/EnumExtensions.cs +6 -5
- package/Runtime/Core/Extensions/EnumExtensions.cs.meta +9 -1
- package/Runtime/Core/Extensions/IListExtensions.cs.meta +9 -1
- package/Runtime/Core/Extensions/MessageExtensions.cs +0 -60
- package/Runtime/Core/Helper/MessageCache.cs.meta +9 -1
- package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +9 -1
- package/Runtime/Core/InstanceId.cs +25 -1
- package/Runtime/Core/Internal/DxUnsafe.cs +60 -0
- package/Runtime/Core/Internal/DxUnsafe.cs.meta +11 -0
- package/Runtime/Core/Internal/FlatDispatch.cs +198 -0
- package/Runtime/Core/Internal/FlatDispatch.cs.meta +11 -0
- package/Runtime/Core/Internal/TypedSlots.cs +5 -21
- package/Runtime/Core/MessageBus/IMessageBus.cs +12 -12
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +1 -0
- package/Runtime/Core/MessageBus/Internal/BusSlots.cs +7 -6
- package/Runtime/Core/MessageBus/MessageBus.cs +2313 -2936
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +187 -14
- package/Runtime/Core/MessageHandler.cs +1023 -1143
- package/Runtime/Core/MessageRegistrationToken.cs +425 -47
- package/Runtime/Core/Messages/GlobalStringMessage.cs.meta +9 -1
- package/Runtime/Core/Messages/ReflexiveMessage.cs.meta +9 -1
- package/Runtime/Core/Messages/StringMessage.cs.meta +9 -1
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +9 -1
- package/Runtime/Unity/MessageAwareComponent.cs +46 -1
- package/Runtime/Unity/MessagingComponent.cs +43 -10
- package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
- package/Samples~/DI/README.md +7 -7
- package/SourceGenerators/Directory.Build.props +50 -3
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs +96 -63
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +745 -87
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +9 -1
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +39 -46
- package/SourceGenerators/global.json +7 -0
- package/SourceGenerators/global.json.meta +7 -0
- package/package.json +27 -40
- package/Runtime/Core/Internal/TypedDispatchLinkIndex.cs +0 -51
|
@@ -31,6 +31,39 @@ namespace DxMessaging.Editor.Settings
|
|
|
31
31
|
private const string FormatComment =
|
|
32
32
|
"# One fully-qualified type name per line. Lines starting with # are comments.";
|
|
33
33
|
|
|
34
|
+
/// <summary>
|
|
35
|
+
/// Test seam controlling WHEN deferred regeneration runs. Production schedules the work on
|
|
36
|
+
/// the next editor tick via <see cref="EditorApplication.delayCall"/>; tests substitute a
|
|
37
|
+
/// capturing scheduler so they can assert no synchronous AssetDatabase import happens and
|
|
38
|
+
/// then drive the deferred work deterministically without touching the filesystem.
|
|
39
|
+
/// </summary>
|
|
40
|
+
internal static Action<Action> DeferralScheduler { get; set; } =
|
|
41
|
+
work => EditorApplication.delayCall += () => work();
|
|
42
|
+
|
|
43
|
+
/// <summary>
|
|
44
|
+
/// Test seam for Unity editor state. Production uses Unity's update/compile flags; tests
|
|
45
|
+
/// substitute a deterministic busy/idle predicate to prove deferred work requeues.
|
|
46
|
+
/// </summary>
|
|
47
|
+
internal static Func<bool> CanMutateAssetDatabase { get; set; } =
|
|
48
|
+
DxMessaging.Editor.DxMessagingEditorIdle.CanMutateAssetDatabase;
|
|
49
|
+
|
|
50
|
+
/// <summary>
|
|
51
|
+
/// Test seam controlling WHAT regeneration does. Production performs the real
|
|
52
|
+
/// write + <see cref="AssetDatabase.ImportAsset"/> via <see cref="RegenerateSidecarCore"/>;
|
|
53
|
+
/// tests substitute a recorder so they can observe whether the apply happens synchronously
|
|
54
|
+
/// or only after the deferred tick, without writing the on-disk sidecar.
|
|
55
|
+
/// </summary>
|
|
56
|
+
internal static Action<DxMessagingSettings> SidecarApplier { get; set; } =
|
|
57
|
+
RegenerateSidecarCore;
|
|
58
|
+
|
|
59
|
+
/// <summary>
|
|
60
|
+
/// Test seam for the follow-up <c>csc.rsp</c> sync. Production schedules the
|
|
61
|
+
/// <c>-additionalfile</c> normalization after sidecar regeneration, which covers deferred
|
|
62
|
+
/// <c>OnValidate</c> writes that finish after <see cref="SetupCscRsp"/>'s startup pass.
|
|
63
|
+
/// </summary>
|
|
64
|
+
internal static Action CscRspAdditionalFileSyncScheduler { get; set; } =
|
|
65
|
+
ScheduleDefaultCscRspAdditionalFileSync;
|
|
66
|
+
|
|
34
67
|
/// <summary>
|
|
35
68
|
/// Regenerates the sidecar text file from the supplied settings asset. Writes only when
|
|
36
69
|
/// the on-disk content differs from what would be written, matching the
|
|
@@ -39,11 +72,15 @@ namespace DxMessaging.Editor.Settings
|
|
|
39
72
|
/// </summary>
|
|
40
73
|
/// <param name="settings">The settings asset. May be <c>null</c> -- no-op in that case.</param>
|
|
41
74
|
/// <remarks>
|
|
42
|
-
///
|
|
43
|
-
///
|
|
44
|
-
///
|
|
45
|
-
///
|
|
46
|
-
///
|
|
75
|
+
/// This is the entry point for explicit, user-driven edits (the "Ignore this type" button,
|
|
76
|
+
/// settings asset Inspector edits) and for EditMode tests: when Unity is idle the regen runs
|
|
77
|
+
/// synchronously for immediate feedback, and when Unity is mid-compile or mid-asset-import
|
|
78
|
+
/// it falls back to <see cref="RegenerateSidecarDeferred"/>. It MUST NOT be called from a
|
|
79
|
+
/// deserialization callback such as <c>ScriptableObject.OnValidate</c> -- those callbacks
|
|
80
|
+
/// can fire during the domain-load asset-import-worker window where
|
|
81
|
+
/// <see cref="EditorApplication.isUpdating"/> and <see cref="EditorApplication.isCompiling"/>
|
|
82
|
+
/// are both <c>false</c>, so this method would import synchronously and crash the editor
|
|
83
|
+
/// (issue #210). Use <see cref="RegenerateSidecarDeferred"/> from those callbacks instead.
|
|
47
84
|
/// </remarks>
|
|
48
85
|
public static void RegenerateSidecar(DxMessagingSettings settings)
|
|
49
86
|
{
|
|
@@ -52,13 +89,97 @@ namespace DxMessaging.Editor.Settings
|
|
|
52
89
|
return;
|
|
53
90
|
}
|
|
54
91
|
|
|
55
|
-
if (
|
|
92
|
+
if (!CanCurrentlyMutateAssetDatabase())
|
|
56
93
|
{
|
|
57
|
-
|
|
94
|
+
RegenerateSidecarDeferred(settings);
|
|
58
95
|
return;
|
|
59
96
|
}
|
|
60
97
|
|
|
61
|
-
|
|
98
|
+
ApplySidecarAndScheduleCscRspSync(settings);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/// <summary>
|
|
102
|
+
/// Schedules sidecar regeneration for the next editor tick, NEVER writing or importing
|
|
103
|
+
/// synchronously. This is the only safe entry point from
|
|
104
|
+
/// <see cref="ScriptableObject.OnValidate"/> and other asset-deserialization callbacks.
|
|
105
|
+
/// </summary>
|
|
106
|
+
/// <param name="settings">The settings asset. May be <c>null</c> -- no-op in that case.</param>
|
|
107
|
+
/// <remarks>
|
|
108
|
+
/// A synchronous <see cref="AssetDatabase.ImportAsset"/> issued from within asset
|
|
109
|
+
/// deserialization re-enters the asset importer and hard-crashes the native editor
|
|
110
|
+
/// (<c>GuidReservations::Reserve</c> abort, issue #210, observed on Unity 6000.4+). The
|
|
111
|
+
/// dangerous window includes the domain-load asset-import worker, during which
|
|
112
|
+
/// <see cref="EditorApplication.isUpdating"/> and <see cref="EditorApplication.isCompiling"/>
|
|
113
|
+
/// are both <c>false</c> -- so the flag-based guard in <see cref="RegenerateSidecar"/> is
|
|
114
|
+
/// not sufficient on its own and this method defers unconditionally. The captured
|
|
115
|
+
/// <paramref name="settings"/> reference is safe to hold: <see cref="EditorApplication.delayCall"/>
|
|
116
|
+
/// is cleared on domain reload, so the callback never outlives its domain, and the
|
|
117
|
+
/// lifetime-aware null check covers the asset being destroyed (deleted) within the domain.
|
|
118
|
+
/// Scheduling here cannot throw, and the deferred regeneration self-guards via
|
|
119
|
+
/// <see cref="RegenerateSidecarCore"/>'s internal try/catch, so callers such as
|
|
120
|
+
/// <c>OnValidate</c> need no surrounding exception guard.
|
|
121
|
+
/// </remarks>
|
|
122
|
+
internal static void RegenerateSidecarDeferred(DxMessagingSettings settings)
|
|
123
|
+
{
|
|
124
|
+
if (settings == null)
|
|
125
|
+
{
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
DxMessaging.Editor.DxMessagingEditorIdle.ScheduleAssetDatabaseMutation(
|
|
130
|
+
() =>
|
|
131
|
+
{
|
|
132
|
+
if (settings == null)
|
|
133
|
+
{
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
ApplySidecarAndScheduleCscRspSync(settings);
|
|
137
|
+
},
|
|
138
|
+
DeferralScheduler,
|
|
139
|
+
CanCurrentlyMutateAssetDatabase
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private static bool CanCurrentlyMutateAssetDatabase()
|
|
144
|
+
{
|
|
145
|
+
Func<bool> canMutateAssetDatabase =
|
|
146
|
+
CanMutateAssetDatabase
|
|
147
|
+
?? DxMessaging.Editor.DxMessagingEditorIdle.CanMutateAssetDatabase;
|
|
148
|
+
return canMutateAssetDatabase();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private static void ApplySidecarAndScheduleCscRspSync(DxMessagingSettings settings)
|
|
152
|
+
{
|
|
153
|
+
try
|
|
154
|
+
{
|
|
155
|
+
SidecarApplier(settings);
|
|
156
|
+
}
|
|
157
|
+
finally
|
|
158
|
+
{
|
|
159
|
+
ScheduleCscRspAdditionalFileSync();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private static void ScheduleCscRspAdditionalFileSync()
|
|
164
|
+
{
|
|
165
|
+
try
|
|
166
|
+
{
|
|
167
|
+
Action scheduler =
|
|
168
|
+
CscRspAdditionalFileSyncScheduler ?? ScheduleDefaultCscRspAdditionalFileSync;
|
|
169
|
+
scheduler();
|
|
170
|
+
}
|
|
171
|
+
catch (Exception ex)
|
|
172
|
+
{
|
|
173
|
+
DxMessaging.Editor.DxMessagingEditorLog.LogWarning(
|
|
174
|
+
"Failed to schedule csc.rsp base-call ignore additionalfile sync.",
|
|
175
|
+
ex
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private static void ScheduleDefaultCscRspAdditionalFileSync()
|
|
181
|
+
{
|
|
182
|
+
DxMessaging.Editor.SetupCscRsp.ScheduleAdditionalFileForIgnoreListSync();
|
|
62
183
|
}
|
|
63
184
|
|
|
64
185
|
private static void RegenerateSidecarCore(DxMessagingSettings settings)
|
|
@@ -88,8 +209,9 @@ namespace DxMessaging.Editor.Settings
|
|
|
88
209
|
}
|
|
89
210
|
catch (Exception ex)
|
|
90
211
|
{
|
|
91
|
-
|
|
92
|
-
$"
|
|
212
|
+
DxMessaging.Editor.DxMessagingEditorLog.LogWarning(
|
|
213
|
+
$"Failed to write base-call ignore sidecar at '{SidecarAssetPath}'.",
|
|
214
|
+
ex
|
|
93
215
|
);
|
|
94
216
|
}
|
|
95
217
|
}
|
|
@@ -126,8 +248,9 @@ namespace DxMessaging.Editor.Settings
|
|
|
126
248
|
}
|
|
127
249
|
catch (Exception ex)
|
|
128
250
|
{
|
|
129
|
-
|
|
130
|
-
$"
|
|
251
|
+
DxMessaging.Editor.DxMessagingEditorLog.LogWarning(
|
|
252
|
+
$"Failed to read base-call ignore sidecar at '{SidecarAssetPath}'.",
|
|
253
|
+
ex
|
|
131
254
|
);
|
|
132
255
|
return Array.Empty<string>();
|
|
133
256
|
}
|
|
@@ -25,7 +25,7 @@ namespace DxMessaging.Editor.Settings
|
|
|
25
25
|
[SerializeField]
|
|
26
26
|
[HideInInspector]
|
|
27
27
|
[FormerlySerializedAs("_enableDiagnosticsInEditor")]
|
|
28
|
-
|
|
28
|
+
internal bool _legacyEnableDiagnosticsInEditor;
|
|
29
29
|
|
|
30
30
|
[SerializeField]
|
|
31
31
|
internal int _messageBufferSize = IMessageBus.DefaultMessageBufferSize;
|
|
@@ -47,8 +47,12 @@ namespace DxMessaging.Editor.Settings
|
|
|
47
47
|
/// </summary>
|
|
48
48
|
public DiagnosticsTarget DiagnosticsTargets
|
|
49
49
|
{
|
|
50
|
-
get =>
|
|
51
|
-
set
|
|
50
|
+
get => EffectiveDiagnosticsTargets;
|
|
51
|
+
set
|
|
52
|
+
{
|
|
53
|
+
_diagnosticsTargets = value;
|
|
54
|
+
_legacyEnableDiagnosticsInEditor = false;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/// <summary>
|
|
@@ -128,8 +132,8 @@ namespace DxMessaging.Editor.Settings
|
|
|
128
132
|
/// </para>
|
|
129
133
|
/// <para>
|
|
130
134
|
/// Toggling this property is observable via a deferred
|
|
131
|
-
/// <see cref="DxMessaging.Editor.Analyzers.DxMessagingConsoleHarvester.
|
|
132
|
-
/// inspector overlay refreshes without waiting for the next compile.
|
|
135
|
+
/// <see cref="DxMessaging.Editor.Analyzers.DxMessagingConsoleHarvester.ScheduleRescanWhenIdle"/>
|
|
136
|
+
/// so the inspector overlay refreshes without waiting for the next compile.
|
|
133
137
|
/// </para>
|
|
134
138
|
/// </remarks>
|
|
135
139
|
public bool UseConsoleBridge
|
|
@@ -143,24 +147,51 @@ namespace DxMessaging.Editor.Settings
|
|
|
143
147
|
}
|
|
144
148
|
_useConsoleBridge = value;
|
|
145
149
|
EditorUtility.SetDirty(this);
|
|
146
|
-
|
|
147
|
-
.Editor
|
|
148
|
-
.Analyzers
|
|
149
|
-
.DxMessagingConsoleHarvester
|
|
150
|
-
.RescanNow;
|
|
150
|
+
DxMessaging.Editor.Analyzers.DxMessagingConsoleHarvester.ScheduleRescanWhenIdle();
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
/// <summary>
|
|
155
|
-
/// Fully-qualified type names excluded from the base-call check. Editable
|
|
156
|
-
/// or via the Inspector overlay's "Ignore this type" button.
|
|
155
|
+
/// Fully-qualified type names excluded from the base-call check. Editable on the settings
|
|
156
|
+
/// asset Inspector or via the Inspector overlay's "Ignore this type" button.
|
|
157
157
|
/// </summary>
|
|
158
158
|
public IReadOnlyList<string> BaseCallIgnoredTypes => _baseCallIgnoredTypes;
|
|
159
159
|
|
|
160
160
|
/// <summary>
|
|
161
|
-
///
|
|
161
|
+
/// Diagnostics target value after applying legacy serialized fields in memory. This does
|
|
162
|
+
/// not mark the settings asset dirty or persist the migration.
|
|
162
163
|
/// </summary>
|
|
163
|
-
internal
|
|
164
|
+
internal DiagnosticsTarget EffectiveDiagnosticsTargets
|
|
165
|
+
{
|
|
166
|
+
get
|
|
167
|
+
{
|
|
168
|
+
if (
|
|
169
|
+
_diagnosticsTargets == DiagnosticsTarget.Off
|
|
170
|
+
&& _legacyEnableDiagnosticsInEditor
|
|
171
|
+
)
|
|
172
|
+
{
|
|
173
|
+
return DiagnosticsTarget.Editor;
|
|
174
|
+
}
|
|
175
|
+
return _diagnosticsTargets;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/// <summary>
|
|
180
|
+
/// Loads the settings asset without creating, saving, or migrating it. Returns
|
|
181
|
+
/// <c>null</c> when no asset exists.
|
|
182
|
+
/// </summary>
|
|
183
|
+
/// <remarks>
|
|
184
|
+
/// Unlike <see cref="GetOrCreateSettings"/>, this performs NO <c>AssetDatabase</c> mutation
|
|
185
|
+
/// (<c>CreateAsset</c>/<c>SaveAssets</c>/durable legacy migration), so it is safe to call
|
|
186
|
+
/// during the domain-load asset-import window -- e.g. from an <c>[InitializeOnLoad]</c>
|
|
187
|
+
/// static constructor -- where a synchronous mutation re-enters the importer and crashes
|
|
188
|
+
/// the native editor (issue #210). Legacy serialized fields are still reflected through
|
|
189
|
+
/// effective property getters so passive callers see the intended value while the durable
|
|
190
|
+
/// migration waits for a safe editor-idle tick. Callers that need the asset
|
|
191
|
+
/// created/migrated must schedule <see cref="GetOrCreateSettings"/> off that window (e.g.
|
|
192
|
+
/// via <see cref="DxMessaging.Editor.DxMessagingEditorIdle.ScheduleAssetDatabaseMutation"/>).
|
|
193
|
+
/// </remarks>
|
|
194
|
+
internal static DxMessagingSettings LoadSettingsPassive()
|
|
164
195
|
{
|
|
165
196
|
DxMessagingSettings settings = AssetDatabase.LoadAssetAtPath<DxMessagingSettings>(
|
|
166
197
|
SettingsPath
|
|
@@ -175,6 +206,21 @@ namespace DxMessaging.Editor.Settings
|
|
|
175
206
|
.FirstOrDefault(asset => asset != null);
|
|
176
207
|
}
|
|
177
208
|
|
|
209
|
+
return settings;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/// <summary>
|
|
213
|
+
/// Loads the settings asset if present, otherwise creates it with sensible defaults.
|
|
214
|
+
/// </summary>
|
|
215
|
+
/// <remarks>
|
|
216
|
+
/// Performs <c>AssetDatabase</c> mutations (create on first run, legacy-field migration), so
|
|
217
|
+
/// it MUST NOT be called synchronously during the domain-load asset-import window (issue
|
|
218
|
+
/// #210). Use <see cref="LoadSettingsPassive"/> for mutation-free reads in that context.
|
|
219
|
+
/// </remarks>
|
|
220
|
+
internal static DxMessagingSettings GetOrCreateSettings()
|
|
221
|
+
{
|
|
222
|
+
DxMessagingSettings settings = LoadSettingsPassive();
|
|
223
|
+
|
|
178
224
|
if (settings == null)
|
|
179
225
|
{
|
|
180
226
|
settings = CreateInstance<DxMessagingSettings>();
|
|
@@ -191,13 +237,8 @@ namespace DxMessaging.Editor.Settings
|
|
|
191
237
|
AssetDatabase.SaveAssets();
|
|
192
238
|
}
|
|
193
239
|
|
|
194
|
-
if (
|
|
195
|
-
settings._diagnosticsTargets == DiagnosticsTarget.Off
|
|
196
|
-
&& settings._legacyEnableDiagnosticsInEditor
|
|
197
|
-
)
|
|
240
|
+
if (settings.ApplyLegacyDiagnosticsMigration())
|
|
198
241
|
{
|
|
199
|
-
settings._diagnosticsTargets = DiagnosticsTarget.Editor;
|
|
200
|
-
settings._legacyEnableDiagnosticsInEditor = false;
|
|
201
242
|
EditorUtility.SetDirty(settings);
|
|
202
243
|
AssetDatabase.SaveAssets();
|
|
203
244
|
}
|
|
@@ -205,6 +246,21 @@ namespace DxMessaging.Editor.Settings
|
|
|
205
246
|
return settings;
|
|
206
247
|
}
|
|
207
248
|
|
|
249
|
+
internal bool ApplyLegacyDiagnosticsMigration()
|
|
250
|
+
{
|
|
251
|
+
if (!_legacyEnableDiagnosticsInEditor)
|
|
252
|
+
{
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (_diagnosticsTargets == DiagnosticsTarget.Off)
|
|
257
|
+
{
|
|
258
|
+
_diagnosticsTargets = DiagnosticsTarget.Editor;
|
|
259
|
+
}
|
|
260
|
+
_legacyEnableDiagnosticsInEditor = false;
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
|
|
208
264
|
/// <summary>
|
|
209
265
|
/// Returns a serialized wrapper for use in SettingsProvider inspectors.
|
|
210
266
|
/// </summary>
|
|
@@ -216,10 +272,7 @@ namespace DxMessaging.Editor.Settings
|
|
|
216
272
|
private void OnEnable()
|
|
217
273
|
{
|
|
218
274
|
// Defensive: the field can be null if the asset was saved before this field existed.
|
|
219
|
-
|
|
220
|
-
{
|
|
221
|
-
_baseCallIgnoredTypes = new List<string>();
|
|
222
|
-
}
|
|
275
|
+
EnsureIgnoreListInitialized();
|
|
223
276
|
// Intentionally NOT regenerating the sidecar here. OnEnable fires on every domain reload
|
|
224
277
|
// and play-mode entry; the sidecar on disk is already consistent with what we'd write
|
|
225
278
|
// (RegenerateSidecar is idempotent, but ImportAsset still produces churn). Regen runs
|
|
@@ -227,12 +280,22 @@ namespace DxMessaging.Editor.Settings
|
|
|
227
280
|
}
|
|
228
281
|
|
|
229
282
|
private void OnValidate()
|
|
283
|
+
{
|
|
284
|
+
EnsureIgnoreListInitialized();
|
|
285
|
+
// Issue #210: OnValidate fires during asset deserialization, including the domain-load
|
|
286
|
+
// asset-import-worker window where EditorApplication.isUpdating/isCompiling are both
|
|
287
|
+
// false. Writing + importing the sidecar synchronously there re-enters the asset
|
|
288
|
+
// importer and hard-crashes the native editor (GuidReservations::Reserve abort on Unity
|
|
289
|
+
// 6000.4+). Always defer to the next editor tick; never import synchronously from here.
|
|
290
|
+
DxMessagingBaseCallIgnoreSync.RegenerateSidecarDeferred(this);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private void EnsureIgnoreListInitialized()
|
|
230
294
|
{
|
|
231
295
|
if (_baseCallIgnoredTypes == null)
|
|
232
296
|
{
|
|
233
297
|
_baseCallIgnoredTypes = new List<string>();
|
|
234
298
|
}
|
|
235
|
-
TryRegenerateSidecar();
|
|
236
299
|
}
|
|
237
300
|
|
|
238
301
|
/// <summary>
|
|
@@ -245,10 +308,7 @@ namespace DxMessaging.Editor.Settings
|
|
|
245
308
|
{
|
|
246
309
|
return;
|
|
247
310
|
}
|
|
248
|
-
|
|
249
|
-
{
|
|
250
|
-
_baseCallIgnoredTypes = new List<string>();
|
|
251
|
-
}
|
|
311
|
+
EnsureIgnoreListInitialized();
|
|
252
312
|
if (
|
|
253
313
|
_baseCallIgnoredTypes.Any(entry =>
|
|
254
314
|
string.Equals(entry, fullyQualifiedTypeName, System.StringComparison.Ordinal)
|
|
@@ -296,8 +356,9 @@ namespace DxMessaging.Editor.Settings
|
|
|
296
356
|
}
|
|
297
357
|
catch (System.Exception ex)
|
|
298
358
|
{
|
|
299
|
-
|
|
300
|
-
|
|
359
|
+
DxMessaging.Editor.DxMessagingEditorLog.LogWarning(
|
|
360
|
+
"Failed to regenerate base-call ignore sidecar.",
|
|
361
|
+
ex
|
|
301
362
|
);
|
|
302
363
|
}
|
|
303
364
|
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
fileFormatVersion: 2
|
|
2
2
|
guid: 477d53eef70c4496b945199c62169dfb
|
|
3
|
-
|
|
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: e4353b92a69a4703abc268fb885a1224
|
|
3
|
-
|
|
3
|
+
MonoImporter:
|
|
4
|
+
externalObjects: {}
|
|
5
|
+
serializedVersion: 2
|
|
6
|
+
defaultReferences: []
|
|
7
|
+
executionOrder: 0
|
|
8
|
+
icon: {instanceID: 0}
|
|
9
|
+
userData:
|
|
10
|
+
assetBundleName:
|
|
11
|
+
assetBundleVariant:
|