fix: Interrupted PlayMode tests no longer leave domain reload disabled#1255
Conversation
Save the original Enter Play Mode settings in a delete-on-restore UserSettings marker before disabling domain reload. This keeps the v2 settings file untouched while preventing abandoned PlayMode test runs from leaving project settings dirty. Keep nested scopes active until the final scope exits and add focused EditMode coverage for recovery, cleanup, stale markers, and nested scopes.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a recovery utility that persists Enter Play Mode settings to a JSON marker and restores them on editor load or when the last DomainReloadDisableScope disposes. DomainReloadDisableScope is refactored to track active scopes statically (WeakReferences) so nested scopes cooperate. New tests cover disposal, nesting, abandoned-scope recovery, stale-marker consumption, and file cleanup. ChangesDomain Reload Scope Recovery System
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Packages/src/Editor/Core/CoreTools/Util/DomainReloadDisableScope.cs`:
- Around line 17-23: Call DomainReloadDisableScopeRecovery.RestoreIfPending()
before checking or incrementing _activeScopeCount so recovery runs even if a
previous scope left _activeScopeCount > 0; only call
DomainReloadDisableScopeRecovery.SaveCurrentSettings() when _activeScopeCount ==
0 (to preserve current settings for the first active scope), then increment
_activeScopeCount as before. Update the DomainReloadDisableScope constructor
(referencing _activeScopeCount,
DomainReloadDisableScopeRecovery.RestoreIfPending(), and
DomainReloadDisableScopeRecovery.SaveCurrentSettings()) to restore pending
recovery unconditionally and save settings only for the first-entered scope.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 05891f51-6772-4d6a-bf63-917377353884
⛔ Files ignored due to path filters (2)
Assets/Tests/Editor/DomainReloadDisableScopeTests.cs.metais excluded by none and included by nonePackages/src/Editor/Core/CoreTools/Util/DomainReloadDisableScopeRecovery.cs.metais excluded by none and included by none
📒 Files selected for processing (3)
Assets/Tests/Editor/DomainReloadDisableScopeTests.csPackages/src/Editor/Core/CoreTools/Util/DomainReloadDisableScope.csPackages/src/Editor/Core/CoreTools/Util/DomainReloadDisableScopeRecovery.cs
There was a problem hiding this comment.
2 issues found across 5 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Track live DomainReloadDisableScope instances with weak references so abandoned scopes can be pruned before the next run while preserving normal nested scopes. This lets pending recovery markers restore settings even when a previous same-session scope never disposed.
Summary
User Impact
Changes
UserSettings/uloop-domain-reload-recovery.jsonthrough a temporary sidecar file.Verification
node Packages/src/Cli~/dist/cli.bundle.cjs compile --force-recompile true --wait-for-domain-reload true --project-path <PROJECT_ROOT>-> ErrorCount 0, WarningCount 0node Packages/src/Cli~/dist/cli.bundle.cjs run-tests --test-mode EditMode --filter-type regex --filter-value io.github.hatayama.uLoopMCP.DomainReloadDisableScope --save-before-run false --project-path <PROJECT_ROOT>-> 5 passed~/.codex/skills/codex-review/scripts/codex-review --parallel-tests "node Packages/src/Cli~/dist/cli.bundle.cjs run-tests --test-mode EditMode --filter-type regex --filter-value io.github.hatayama.uLoopMCP.DomainReloadDisableScope --save-before-run false --project-path <PROJECT_ROOT>" main-> no accepted/actionable findingsFix: Interrupted PlayMode Tests No Longer Leave Domain Reload Disabled
Overview
This PR resolves an issue where interrupted PlayMode test runs could leave domain reload disabled in Unity. The fix introduces a static reference-counted scope model with persistent recovery state, allowing the editor to restore the user's original
Enter Play Modesettings even if aDomainReloadDisableScopeis abandoned or the editor is reloaded.Architecture
Key Components
classDiagram class DomainReloadDisableScope { -_activeScopeCount: static int -_disposed: bool +DomainReloadDisableScope() +Dispose() void +ResetActiveScopeCountForTests() internal static void } class DomainReloadDisableScopeRecovery { +SaveCurrentSettings() internal static void +RestoreIfPending() internal static void +ClearPendingRestoreForTests() internal static void +HasPendingRestoreForTests() internal static bool +ReadMarkerDataForTests() internal static DomainReloadDisableScopeRecoveryData -RestorePendingSettingsOnEditorLoad() private static void } class DomainReloadDisableScopeRecoveryData { +originalOptionsEnabled: bool +originalOptions: int } class DomainReloadDisableScopeRecoveryConstants { +DirectoryPath: const string +MarkerFileName: const string +TempFileName: const string +MarkerFilePath: readonly string +TempFilePath: readonly string } DomainReloadDisableScope --> DomainReloadDisableScopeRecovery DomainReloadDisableScopeRecovery --> DomainReloadDisableScopeRecoveryData DomainReloadDisableScopeRecovery --> DomainReloadDisableScopeRecoveryConstantsChanges Summary
1. DomainReloadDisableScope.cs (Refactored)
RestoreIfPending()andSaveCurrentSettings()before forcing disable-domain-reload EditorSettings.Dispose()is idempotent per instance (guarded by a_disposedflag), removes the instance from the static collection, and only when the last active scope is removed does it callRestoreIfPending().ResetActiveScopeCountForTests()internal helper to clear static tracking for tests.2. DomainReloadDisableScopeRecovery.cs (New)
[InitializeOnLoadMethod]to restore pending settings on editor load (skips Asset Import worker processes).EditorSettings.enterPlayModeOptionsEnabledandEditorSettings.enterPlayModeOptionstoUserSettings/uloop-domain-reload-recovery.jsonwith an atomic temp-file-then-rename strategy.HasPendingRestoreForTests(),ReadMarkerDataForTests(),ClearPendingRestoreForTests(), and test path properties for inspecting and cleaning marker/temp files.3. DomainReloadDisableScopeRecoveryData.cs (New)
4. DomainReloadDisableScopeRecoveryConstants.cs (New)
UserSettings/uloop-domain-reload-recovery.jsonand.tmpvariant.5. DomainReloadDisableScopeTests.cs (New Test Suite)
Comprehensive test coverage with lifecycle handling and recovery verification:
RestoreIfPending()restores original settings when a scope is abandoned and clears pending state.RestoreIfPending()removes both marker and temp files (no residual state).Recovery Flow
User Impact
EditorSettings.enterPlayModeOptionsset to disable domain reload, affecting subsequent runs.Verification