Skip to content

fix: 区分用户停止与自然结束 (fixes #1358, #1790)#2223

Open
antecanis8 wants to merge 3 commits into
OneDragon-Anything:mainfrom
antecanis8:codex/manual-stop
Open

fix: 区分用户停止与自然结束 (fixes #1358, #1790)#2223
antecanis8 wants to merge 3 commits into
OneDragon-Anything:mainfrom
antecanis8:codex/manual-stop

Conversation

@antecanis8
Copy link
Copy Markdown
Contributor

@antecanis8 antecanis8 commented May 4, 2026

This pull request adds support for configuring "after completion" actions (such as closing the game or shutting down) in the one-dragon run interface, and ensures these actions are only executed when the application ends naturally (not when stopped by the user). It introduces logic to track whether the last stop was user-initiated, updates the UI and configuration accordingly, and adds comprehensive tests for these behaviors.

After Completion Actions & User Stop Tracking:

  • Added new "after completion" configuration options ("None", "Close Game", "Shut Down") to the UI and translation files (en.po, zh.po) and documented the intended behavior in the architecture docs. [1] [2] [3]
  • Introduced logic (should_execute_after_done) and state tracking in ApplicationRunContext to distinguish between user-initiated stops and natural application completion, ensuring "after completion" actions only run on natural completion. [1] [2] [3] [4] [5] [6] [7]
  • Updated all stop-running call sites (UI button, keyboard shortcut) to correctly mark user-initiated stops. [1] [2]

Testing:

  • Added a new test suite to verify correct tracking of stop sources and correct execution/skipping of after-done actions.

Miscellaneous Improvements:

  • Refactored string formatting for instance naming and deletion for clarity and consistency. [1] [2]
  • Minor code cleanup in run_application (removed unused variable).

Summary by CodeRabbit

发布说明

  • 新功能

    • 新增运行后动作配置,支持关闭游戏、关机等操作,并区分用户主动停止和自然完成的行为
    • 补充英文和中文UI标签翻译
  • 文档

    • 更新应用运行架构文档
  • 测试

    • 添加运行停止行为测试覆盖

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

本PR为OneDragon运行框架添加了用户主动停止与自然完成的区分机制。通过在ApplicationRunContext中追踪停止源,并在UI停止按钮和键盘快捷键处标记为用户主动停止,从而在结束后动作(关闭游戏、关机)执行前进行条件判断,确保此类动作仅在应用自然完成时触发。

Changes

用户停止追踪与结束后动作控制流

层级 / 文件 摘要
配置与判定逻辑
src/one_dragon/base/config/one_dragon_config.py
新增should_execute_after_done(after_done, is_last_stop_by_user)方法,当停止由用户主动触发时返回False,否则仅允许CLOSE_GAMESHUTDOWN动作执行;另更新实例索引格式从%02d到f-string。
核心状态追踪
src/one_dragon/base/operation/application/application_run_context.py
新增内部标志_last_stop_by_user和公开属性is_last_stop_by_userstop_running()方法扩展by_user参数(默认False);start_running()重置该标志。
用户交互标记
src/one_dragon/base/operation/one_dragon_context.py
src/one_dragon_qt/view/app_run_interface.py
快捷键停止与UI停止按钮均调用stop_running(by_user=True),显式标记为用户主动停止。
结束后动作执行控制
src/one_dragon_qt/view/one_dragon/one_dragon_run_interface.py
导入should_execute_after_done,在on_context_state_changed中通过条件判断决定是否执行关闭游戏或关机动作。
本地化与文档
assets/text/ui/en.po
assets/text/ui/zh.po
docs/develop/one_dragon/one_dragon_architecture.md
新增八项UI标签的英文及中文翻译条目;文档补充ApplicationRunContext的停止源追踪职责和"结束后动作"配置说明。
测试覆盖
tests/one_dragon/base/operation/application/application_run_context/test_stop_running.py
新增TestStopRunning测试类,通过FakeController验证用户停止标志设置、清除以及should_execute_after_done()在不同停止源下的行为。

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as App UI
    participant RunCtx as ApplicationRunContext
    participant Config as one_dragon_config
    participant OneDragon as OneDragonRunInterface
    
    User->>UI: Click Stop Button / Press Hotkey
    UI->>RunCtx: stop_running(by_user=True)
    RunCtx->>RunCtx: _last_stop_by_user = True
    
    rect rgba(200, 150, 100, 0.5)
    Note over RunCtx,OneDragon: Natural App Completion
    RunCtx->>RunCtx: _last_stop_by_user = False (reset on start)
    RunCtx->>OneDragon: context_state_changed(stopped)
    OneDragon->>Config: should_execute_after_done(after_done, is_last_stop_by_user=False)
    Config-->>OneDragon: True (if CLOSE_GAME or SHUTDOWN)
    OneDragon->>OneDragon: Execute close/shutdown action
    end
    
    rect rgba(100, 150, 200, 0.5)
    Note over RunCtx,OneDragon: User-Initiated Stop
    RunCtx->>OneDragon: context_state_changed(stopped)
    OneDragon->>Config: should_execute_after_done(after_done, is_last_stop_by_user=True)
    Config-->>OneDragon: False (skip close/shutdown)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

  • fix(framework): 修复后台驻留线程 #2053:均修改ApplicationRunContext中的运行上下文逻辑,本PR关注用户停止追踪与结束后动作控制,该PR关注应用关闭后清理工作——代码级别相关联。

Suggested reviewers

  • Usagi-wusaqi

Poem

🐰 用户按停留痕迹,
应用自终各有异,
关机游戏分时机,
条件判断护周期,
停止信号记真意。

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确反映了本次变更的主要目的:区分用户停止与自然结束,这是整个PR的核心改动,涵盖了状态跟踪、条件执行和相关UI调用的更新。
Docstring Coverage ✅ Passed Docstring coverage is 81.82% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms


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.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/one_dragon/base/operation/application/application_run_context/test_stop_running.py (1)

72-93: ⚡ Quick win

建议补一条 AfterDoneOpEnum.NONE 的断言覆盖。

当前参数化已覆盖“应执行”的两种动作;再补 NONE 可以更稳地防止误回归。

可选补丁
@@
     `@pytest.mark.parametrize`(
         "after_done",
         [
+            AfterDoneOpEnum.NONE.value.value,
             AfterDoneOpEnum.CLOSE_GAME.value.value,
             AfterDoneOpEnum.SHUTDOWN.value.value,
         ],
     )
     def test_after_done_action_skips_user_stop(self, after_done: str) -> None:
@@
     `@pytest.mark.parametrize`(
         "after_done",
         [
+            AfterDoneOpEnum.NONE.value.value,
             AfterDoneOpEnum.CLOSE_GAME.value.value,
             AfterDoneOpEnum.SHUTDOWN.value.value,
         ],
     )
     def test_after_done_action_runs_after_natural_stop(self, after_done: str) -> None:
         """测试自然结束时会执行结束后动作。"""
-        assert should_execute_after_done(after_done, is_last_stop_by_user=False)
+        expected = after_done != AfterDoneOpEnum.NONE.value.value
+        assert should_execute_after_done(after_done, is_last_stop_by_user=False) is expected
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tests/one_dragon/base/operation/application/application_run_context/test_stop_running.py`
around lines 72 - 93, Add a dedicated test to cover AfterDoneOpEnum.NONE: create
a new test (e.g., test_after_done_none_never_runs) that calls
should_execute_after_done(AfterDoneOpEnum.NONE.value.value,
is_last_stop_by_user=True) and
should_execute_after_done(AfterDoneOpEnum.NONE.value.value,
is_last_stop_by_user=False) and asserts both return False; reference
AfterDoneOpEnum and should_execute_after_done so the NONE case is explicitly
covered and prevents regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@tests/one_dragon/base/operation/application/application_run_context/test_stop_running.py`:
- Around line 72-93: Add a dedicated test to cover AfterDoneOpEnum.NONE: create
a new test (e.g., test_after_done_none_never_runs) that calls
should_execute_after_done(AfterDoneOpEnum.NONE.value.value,
is_last_stop_by_user=True) and
should_execute_after_done(AfterDoneOpEnum.NONE.value.value,
is_last_stop_by_user=False) and asserts both return False; reference
AfterDoneOpEnum and should_execute_after_done so the NONE case is explicitly
covered and prevents regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d20014a1-cbb9-493c-87da-55957e076642

📥 Commits

Reviewing files that changed from the base of the PR and between cd5b4b9 and 4923bbf.

📒 Files selected for processing (11)
  • assets/text/output/en/LC_MESSAGES/ui.mo
  • assets/text/output/zh/LC_MESSAGES/ui.mo
  • assets/text/ui/en.po
  • assets/text/ui/zh.po
  • docs/develop/one_dragon/one_dragon_architecture.md
  • src/one_dragon/base/config/one_dragon_config.py
  • src/one_dragon/base/operation/application/application_run_context.py
  • src/one_dragon/base/operation/one_dragon_context.py
  • src/one_dragon_qt/view/app_run_interface.py
  • src/one_dragon_qt/view/one_dragon/one_dragon_run_interface.py
  • tests/one_dragon/base/operation/application/application_run_context/test_stop_running.py

Copy link
Copy Markdown
Contributor

@Usagi-wusaqi Usagi-wusaqi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

至少 功能测试 没问题
image
image

@JoshCai233
Copy link
Copy Markdown
Contributor

至少 功能测试 没问题 image image

+1

SHUTDOWN = ConfigItem('关机')


def should_execute_after_done(after_done: str, is_last_stop_by_user: bool) -> bool:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个函数封装一层感觉收益不大

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants