fix(app-iced): 删掉空操作串行门 + 钉住档位贯穿产品启动路径 + 退场起点接当前进度
复审 r2 的三条: 1) 删掉 motion::serialize() 那把串行门:PUMP/LAST_FRAME 都是 thread_local,libtest 每用例 一线程 ⇒ 它改变不了任何结果(ULL_MOTION=off 下握门照样红)。留一个不起作用的同步原语 比没有更坏。subscription.rs 与 motion_sync.rs 的 idle_app 恢复原签名。 2) 真实根因是「喂给 configure 的值」:idle_app 先钉 STANDARD,随后 on_boot → configure_motion(app/update.rs:276)→ boot_env::motion_scale(..) 再定一次档,把钉住覆盖掉。 改成 BYPASS_PROBE(bool) → FORCED_SCALE(Cell<Option<MotionScale>>):configure 里钉住优先, 于是三条定档路径(configure_for_test / on_boot / boot_env 的 env·后端 tier)都穿不过去。 两条用例钉住它(纯合成 + 真 Message::Boot),删掉「钉住优先」两处都红。 3) P2-2:Modal::Closing 记住起手进度 from,progress = from*(1-eased) —— 进场途中被关掉时 从当前进度接着缩,不再先跳到 1.0(反向硬跳)。新用例 closing_during_the_entrance_does_not_jump_to_fully_open,把 from 改回 1.0 即红。
This commit is contained in:
1 parent
c21c6df51b
commit
787cb16189
4 files changed
+122
-44
No files matched your search
@@ -246,3 +246,70 @@ fn configure_goes_through_the_real_os_probe() {
|
||||
);
|
||||
reset();
|
||||
}
|
||||
|
||||
/// **进场途中被关掉**:进度必须从**当前值**接着缩,不许先跳到 1.0 再退(复审 r2 的 P2-2)。
|
||||
///
|
||||
/// 抓得住:把 `begin_modal_close` 的起点改回恒 `1.0`(旧实现)⇒ 下面那条
|
||||
/// `(关掉后首帧)<=(关掉前一帧)` 立刻红——那就是"反向硬跳"。
|
||||
/// 抓不住:那一帧在真实屏幕上有多刺眼(D30 的观感,不是断言)。
|
||||
#[test]
|
||||
fn closing_during_the_entrance_does_not_jump_to_fully_open() {
|
||||
let mut pump = standard();
|
||||
assert!(pump.observe_modal(true), "起跑进场");
|
||||
for _ in 0..3 {
|
||||
pump.advance(FRAME_MS); // 走到进场的 1/4 左右
|
||||
}
|
||||
let before = pump.modal_frame().progress;
|
||||
assert!(
|
||||
before > 0.0 && before < 1.0,
|
||||
"前提:进场走到半路,实测 {before}"
|
||||
);
|
||||
|
||||
assert!(!pump.begin_modal_close(), "有动效 ⇒ 起跑退场");
|
||||
let first = pump.modal_frame().progress;
|
||||
assert!(
|
||||
first <= before + 1.0e-6,
|
||||
"关掉后的首帧进度不许**变大**({before} → {first} 就是反向硬跳)"
|
||||
);
|
||||
assert!(
|
||||
(first - before).abs() < 0.05,
|
||||
"起点必须接在当前进度上({before} → {first})"
|
||||
);
|
||||
|
||||
// 之后单调缩到 0,且必须真的走完(交回一次「已关」)
|
||||
let mut previous = first;
|
||||
while pump.is_animating() {
|
||||
pump.advance(FRAME_MS);
|
||||
let now = pump.modal_frame().progress;
|
||||
assert!(
|
||||
now <= previous + 1.0e-6,
|
||||
"退场必须单调缩小:{previous} → {now}"
|
||||
);
|
||||
previous = now;
|
||||
}
|
||||
assert_eq!(pump.modal_frame(), ModalFrame::HIDDEN);
|
||||
assert!(pump.take_modal_closed());
|
||||
}
|
||||
|
||||
/// **钉住的档压过任何来源的取值**(复审 r2 的根因机制)。
|
||||
///
|
||||
/// `App::on_boot` 会再调一次 `configure`(`app/update.rs:276`),值来自
|
||||
/// `boot_env::motion_scale(...)`(本机默认 HALF、`ULL_MOTION=off` 时 NONE)。本用例把那次调用
|
||||
/// 的**取值**直接喂进来:钉住 STANDARD 之后,`configure(HALF)` / `configure(NONE)` 都改不动它。
|
||||
///
|
||||
/// 抓得住:删掉 `configure` 里「`FORCED_SCALE` 优先」那一段 ⇒ 两行断言全红(= r2 之前的真红)。
|
||||
/// 抓不住:`boot_env` 自己那张分支表(env / 后端 tier 的取值规则,不在本 mission 的 scope)。
|
||||
#[test]
|
||||
fn a_pinned_scale_survives_every_later_configure() {
|
||||
reset();
|
||||
configure_for_test(MotionScale::STANDARD, None);
|
||||
configure(MotionScale::HALF, None); // = 本机 ICED_BACKEND 未设时 boot_env 的默认档
|
||||
assert_eq!(scale(), MotionScale::STANDARD);
|
||||
configure(MotionScale::NONE, None); // = ULL_MOTION=off 时 boot_env 的取值
|
||||
assert_eq!(
|
||||
scale(),
|
||||
MotionScale::STANDARD,
|
||||
"钉住的档必须压过 on_boot 的取值"
|
||||
);
|
||||
reset();
|
||||
}
|
||||
Reference in new issue
Block a user