fix(app-iced): 动效全局态按「测试隔离」修 —— 串行门 + 探针旁路(复审 P2-5 返工)
tip 8b6f090 上 7 条用例在 -j 2 下红,根因两层: 1) P2-5 引入的 configure_for_test 只挡调用点,而 App::update(Boot) 会走**产品** configure 再按真探针定档 —— 本机(RDP 会话)SPI_GETCLIENTAREAANIMATION 报「动画关」⇒ 档位被压成 NONE ⇒ 位移恒 0 ⇒ 门槛 B/C 的守卫全红(日志里 [motion] scale=0.00 就是它)。 2) 动效全局态(档位 + 进程级时间轴)在并行用例间共享,谁先写谁赢。 修法(判据一条没动): - components :: motion :: serialize():**跨模块共用的唯一一把**串行门,subscription.rs 与 update/motion_sync.rs 的用例都取它(idle_app 把 guard 一起返回,活到用例结束)。 - configure_for_test 置 thread-local BYPASS_PROBE,configure 读它 ⇒ 产品启动路径也不会再按 探针改档;reset() 清旁路,供「故意走真探针」那条用例使用。 - NONE 仍要求严格 0、STANDARD 仍要求 12~20 帧与端点归位。
This commit is contained in:
1 parent
1edf645c2f
commit
c21c6df51b
3 files changed
+55
-29
No files matched your search
@@ -84,13 +84,22 @@ thread_local! {
|
||||
/// 上次收到帧的时刻(`advance` 用它把「帧到达」换算成流逝毫秒)。
|
||||
#[allow(clippy::missing_const_for_thread_local)]
|
||||
static LAST_FRAME: Cell<Option<Instant>> = const { Cell::new(None) };
|
||||
/// **测试专用**:置真后 [`configure`] 不再读系统偏好(见 [`configure_for_test`])。
|
||||
#[allow(clippy::missing_const_for_thread_local)]
|
||||
static BYPASS_PROBE: Cell<bool> = const { Cell::new(false) };
|
||||
}
|
||||
|
||||
/// 定档:`on_boot` 调一次(截图档给 `NONE`,CPU 档给 `HALF`,见 `app/update/boot_env.rs`)。
|
||||
///
|
||||
/// **系统「减少动效」在这里合成**(见模块文档的表):`Reduced` ⇒ `NONE`;`Unknown` ⇒ 不动。
|
||||
pub fn configure(scale: MotionScale, pin: Option<f64>) {
|
||||
let scale = effective_scale(scale, ReduceMotion::probe(), pin.is_some());
|
||||
// 用例走 `configure_for_test` 置位旁路:**产品启动路径**(`on_boot` → 这里)也会重新定档,
|
||||
// 只挡调用点是不够的。
|
||||
let scale = if BYPASS_PROBE.with(Cell::get) {
|
||||
scale
|
||||
} else {
|
||||
effective_scale(scale, ReduceMotion::probe(), pin.is_some())
|
||||
};
|
||||
PUMP.with(|pump| pump.borrow_mut().configure(scale, pin));
|
||||
}
|
||||
|
||||
@@ -102,7 +111,8 @@ pub fn configure(scale: MotionScale, pin: Option<f64>) {
|
||||
/// 这条判据悄悄删掉。
|
||||
#[cfg(test)]
|
||||
pub fn configure_for_test(scale: MotionScale, pin: Option<f64>) {
|
||||
PUMP.with(|pump| pump.borrow_mut().configure(scale, pin));
|
||||
BYPASS_PROBE.with(|flag| flag.set(true));
|
||||
configure(scale, pin);
|
||||
}
|
||||
|
||||
/// 档位与系统偏好的**合成本身**(纯函数,可断言)。
|
||||
@@ -121,6 +131,18 @@ pub fn scale() -> MotionScale {
|
||||
PUMP.with(|pump| pump.borrow().scale())
|
||||
}
|
||||
|
||||
/// **测试专用**:动效全局态的串行门(复审 P2-5 的第二半)。
|
||||
///
|
||||
/// `Pump` 与「旁路探针」都是 thread-local,正常并行用例本就互不干扰;但用例会读**产品启动路径**
|
||||
/// 写下的档位,而 libtest 允许 `--test-threads=1`(届时所有用例同线程)。凡是会改写动效全局态的
|
||||
/// 用例都先取这把锁,把时序固定下来——**跨模块共用的只有这一把**(`subscription.rs` 与
|
||||
/// `motion_sync.rs` 都从这里取)。
|
||||
#[cfg(test)]
|
||||
pub fn serialize() -> std::sync::MutexGuard<'static, ()> {
|
||||
static GATE: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||
GATE.lock().unwrap_or_else(|poisoned| poisoned.into_inner())
|
||||
}
|
||||
|
||||
/// 已推进的帧数。
|
||||
pub fn samples() -> u64 {
|
||||
PUMP.with(|pump| pump.borrow().samples())
|
||||
@@ -236,6 +258,8 @@ pub fn shifted<'a, M: 'a>(
|
||||
pub fn reset() {
|
||||
PUMP.with(|pump| *pump.borrow_mut() = pump::Pump::new());
|
||||
LAST_FRAME.with(|last| last.set(None));
|
||||
// 旁路也要清:「故意走真探针」的那条用例靠 `reset()` 回到未旁路状态。
|
||||
BYPASS_PROBE.with(|flag| flag.set(false));
|
||||
}
|
||||
|
||||
/// 测试专用:按给定毫秒推进(`advance` 读真实时钟,单元测试不能等它)。
|
||||
|
||||
Reference in new issue
Block a user