Stop a scroll asking a question it has already answered
A seventh sweep, over the parts no earlier round named: the tree generator
and the scenario harness, `Fixed`, the headless rig, and once more over the
commit the sixth sweep left, which was itself unreviewed.
`Scroll`'s content box is `answer_px.max(container_len)`, so a scroll whose
content fits has nothing to scroll through and `update_amt` has already put
`amt` at zero. The test choosing between the viewport and a scrolled span
asked `amt != ZERO || content_len != container_len`, where the first
disjunct can never decide it -- the same defect `b7b8d09` removed from the
line above, one operand over. A `debug_assert` of the implication held
across the whole suite, including every scrolling test.
`Fixed::to_scale` and its private `shift_round` arrived on this branch with
no caller and never got one; the only thing that called either was the test
written for them.
`Len::align` wrote `Len` arithmetic out a component at a time, around an
`at.px` that is always zero, where `Len::scale` and the `Add`/`Sub` beside
it say the whole rule in two lines. `LayoutLen::without_leftover` took
`self` where the `apply_leftover` its own doc calls the opposite reading of
the same value takes `&self`.
`run-headless.sh --resize` changed the output's mode but not `out_w`/`out_h`,
which is the extent `replay-touch` scales a recording against -- so
`--resize` with `--replay` put every sample of the gesture somewhere else
and still finished like a run that worked. Both come from one function now.
The generator's plan/build split stranded a comment: "a row takes the height
it is given" describes the size rule `build` derives from `dir`, and it was
left above the `gap` draw, which is the one line it is not about and which
does consume randomness.
Format, clippy with and without layout-diagnostics, and the suite (131 + 19
+ 13 + 4) are clean. The cold dump over 400 depth-5 trees is byte-identical
to b7b8d09 across all 34,492 boxes, and all three seed scans pass: 400 at
depth 5 in 62.75s, 1,000 at depth 6 in 162.37s, 2,000 at depth 4 in 305.25s.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b7b8d09e40
commit
f8aa0c5cdf
6 files changed
+29
-48
No files matched your search
@@ -131,14 +131,6 @@ impl<const SHIFT: u32> Fixed<SHIFT> {
|
||||
self.0 as f32 / Self::one().0 as f32
|
||||
}
|
||||
|
||||
/// The same value on another grid, rounded where the new one is coarser.
|
||||
pub const fn to_scale<const TO: u32>(self) -> Fixed<TO> {
|
||||
Fixed(match TO >= SHIFT {
|
||||
true => self.0 << (TO - SHIFT),
|
||||
false => shift_round(self.0 as i64, SHIFT - TO) as i32,
|
||||
})
|
||||
}
|
||||
|
||||
pub const fn add(self, rhs: Self) -> Self {
|
||||
Self(self.0.wrapping_add(rhs.0))
|
||||
}
|
||||
@@ -246,16 +238,6 @@ impl<const SHIFT: u32> Fixed<SHIFT> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Back to a single step, rounding halves away from zero so that a value and
|
||||
/// its negation round to the same distance.
|
||||
const fn shift_round(v: i64, bits: u32) -> i64 {
|
||||
let half = (1i64 << bits) >> 1;
|
||||
match v < 0 {
|
||||
true => -((-v + half) >> bits),
|
||||
false => (v + half) >> bits,
|
||||
}
|
||||
}
|
||||
|
||||
const fn div_round(num: i64, den: i64) -> i64 {
|
||||
let (q, rem) = (num / den, num % den);
|
||||
match rem.unsigned_abs() * 2 >= den.unsigned_abs() {
|
||||
@@ -531,15 +513,6 @@ mod tests {
|
||||
assert_eq!(Px::from_f32(-1e12), Px::MIN);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_coarser_grid_rounds_and_a_finer_one_does_not() {
|
||||
// A third, which neither grid holds exactly.
|
||||
let third = Rel::ONE / Rel::from_int(3);
|
||||
assert_eq!(third.to_scale::<6>(), Fixed::<6>::from_raw(21));
|
||||
let coarse = Fixed::<6>::from_raw(21);
|
||||
assert_eq!(coarse.to_scale::<24>().to_scale::<6>(), coarse);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lerp_takes_the_fraction_as_the_receiver() {
|
||||
let (from, to) = (Px::from_int(10), Px::from_int(20));
|
||||
|
||||
@@ -151,13 +151,15 @@ impl Vec2 {
|
||||
}
|
||||
|
||||
impl Len {
|
||||
/// This length placed in the box it is measured in: the alignment names a
|
||||
/// point along that box, and the two ends are that point less the part of
|
||||
/// the length falling before it and plus the part falling after.
|
||||
pub const fn align(&self, align: AxisAlign) -> UiSpan {
|
||||
let rel = align.rel();
|
||||
let rest = Rel::ONE.sub(rel);
|
||||
let at = Len::from_parts(rel, Px::ZERO);
|
||||
UiSpan {
|
||||
start: Len::from_parts(at.rel.sub(self.rel.mul(rel)), at.px.sub(self.px.mul(rel))),
|
||||
end: Len::from_parts(at.rel.add(self.rel.mul(rest)), at.px.add(self.px.mul(rest))),
|
||||
start: at - self.scale(rel),
|
||||
end: at + self.scale(Rel::ONE.sub(rel)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ impl LayoutLen {
|
||||
/// anyone not dividing a box between siblings, where a share is a claim
|
||||
/// on someone else's room rather than a length of its own.
|
||||
/// [`Self::apply_leftover`] is the opposite reading of the same value.
|
||||
pub const fn without_leftover(self) -> Len {
|
||||
pub const fn without_leftover(&self) -> Len {
|
||||
Len::from_parts(self.rel, self.px)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user