fix: 触发器响应优化 — pending trigger 在当前step结束后立即触发

修复网页触发器点击后无响应的问题。原因是 defer_triggers 模式下,
pending trigger 必须等待整个 sequence 播完才触发,当 step 有
random_loop_range [2,15] 时用户可能要等几分钟。
现在改为当前 step 循环结束后立即检查并执行 pending trigger。

同时添加 systemd service 脚本。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
showen
2026-03-13 13:08:10 +08:00
parent 29645d711d
commit d4f0eb7eca
2 changed files with 28 additions and 8 deletions

19
scripts/showen_v2.service Normal file
View File

@@ -0,0 +1,19 @@
[Unit]
Description=ShowenV2 — 数字生命窗口平台
After=network.target dbus.service
Wants=network.target
[Service]
Type=simple
User=showen
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/showen/.Xauthority
WorkingDirectory=/home/showen/Showen/ShowenV2
ExecStart=/home/showen/Showen/ShowenV2/target/release/showen_v2 --config /home/showen/Showen/ShowenV2/configs/dog_state_machine.json
Restart=on-failure
RestartSec=3
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=graphical.target

View File

@@ -50,6 +50,13 @@ impl StateMachine {
return Ok(false);
}
// 有待执行的触发器时,跳过 sequence 剩余 step立即切换状态
if self.pending_trigger_target.is_some() {
let target_state = self.pending_trigger_target.take().unwrap();
self.transition_to_state(&target_state)?;
return Ok(self.current_state != old_state);
}
let sequence_len = self
.current_state_config()
.ok_or_else(|| anyhow::anyhow!("当前状态不存在: {}", self.current_state))?
@@ -410,16 +417,10 @@ mod tests {
assert_eq!(machine.current_state, "idle");
assert_eq!(machine.current_loop_remaining, 1);
assert!(!machine
.on_video_completed()
.expect("should advance within same state"));
assert_eq!(machine.current_sequence_index, 1);
assert_eq!(machine.current_loop_remaining, 1);
assert_eq!(machine.current_video_id().as_deref(), Some("tail"));
// 当前 step 播完后,有 pending trigger 应立即跳转,跳过后续 step
assert!(machine
.on_video_completed()
.expect("pending trigger should fire at sequence end"));
.expect("pending trigger should fire after current step ends"));
assert_eq!(machine.current_state, "called");
assert_eq!(machine.current_video_id().as_deref(), Some("called"));
assert!(!machine.has_pending_trigger());