Let OnResize answer for the window too, and delete the second rule
A resize had its own mechanism: `reads_output` recorded that a widget had looked at the output, `update` scanned every active widget for one whose `output_px` had moved, marked it and its whole reader chain, and `resize_marks` kept those marks from counting as content dirtiness -- while `on_resize` answered the same question for every other box. Two answers to "does this drawing survive its box changing length", and the one that applied to the window ignored what the widget had declared. With the output held as the root of the chain there is one question. A resize offers the root widget its box again, `try_reuse` answers per axis from `on_resize`, and `redraws_under` prices the subtree. Gone with it: `reads_output`, `resized`, `resize_marks`, the scan, the eager reader marking, and the shallowest-first branch in `redraw_updates`, which only existed because resize marking worked differently -- the settle loop now has one order. Two things this needed. An unslotted widget may be reused when only its parent's box changed length: it has nothing of its own to write, and what it drew is a fraction of that box, so the slot above it already carries the change. And `root_readers` holds the widgets whose size came from the output rather than their own box -- `MaxSize` -- since no box of theirs need have changed; they are marked per axis, from a set kept as they draw rather than by scanning. `a_resize_does_not_redraw_what_the_shader_can_move` now says `Scale`, which is what it was always describing, and `a_resize_redraws_what_does _not_scale` is its other half. `ReadsWidth` declares `Scale` across the axis it does not read, so per-axis precision comes from the widget rather than from which output axis it happened to touch. Resize phase, seed 1 depth 8: 6.45M instructions per frame to 5.84M. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9f4311774b
commit
ef815dadfd
4 files changed
+105
-81
No files matched your search
+28
-2
@@ -191,6 +191,8 @@ impl Widget for ReadsOutput {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the output across one axis only, and says so: its drawing follows
|
||||
/// a taller box on its own, so only a wider one is worth a draw.
|
||||
struct ReadsWidth {
|
||||
draws: Rc<Cell<usize>>,
|
||||
}
|
||||
@@ -200,12 +202,19 @@ impl Widget for ReadsWidth {
|
||||
self.draws.set(self.draws.get() + 1);
|
||||
Size::px((painter.output_len(Axis::X) / 4.0, 20.0).into())
|
||||
}
|
||||
|
||||
fn on_resize(&self, axis: Axis) -> OnResize {
|
||||
match axis {
|
||||
Axis::X => OnResize::Redraw,
|
||||
Axis::Y => OnResize::Scale,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_resize_does_not_redraw_what_the_shader_can_move() {
|
||||
let mut h = Harness::new((400, 200));
|
||||
let (leaf, draws) = counted(&mut h, Size::REST, OnResize::Redraw);
|
||||
let (leaf, draws) = counted(&mut h, Size::REST, OnResize::Scale);
|
||||
h.set_root(leaf);
|
||||
let settled = draws.get();
|
||||
|
||||
@@ -216,11 +225,28 @@ fn a_resize_does_not_redraw_what_the_shader_can_move() {
|
||||
assert_eq!(
|
||||
draws.get(),
|
||||
settled,
|
||||
"its box is the same fraction of a different output"
|
||||
"a scaling drawing follows its box, and the output is one"
|
||||
);
|
||||
assert_corners!(h, leaf, (0, 0), (800, 100));
|
||||
}
|
||||
|
||||
/// The output is the root of the box chain, so a resize is a box that changed
|
||||
/// length and `OnResize` answers for it -- there is not a second rule for the
|
||||
/// window. A drawing that does not scale is redrawn whichever box moved.
|
||||
#[test]
|
||||
fn a_resize_redraws_what_does_not_scale() {
|
||||
let mut h = Harness::new((400, 200));
|
||||
let (leaf, draws) = counted(&mut h, Size::REST, OnResize::Redraw);
|
||||
h.set_root(leaf);
|
||||
let settled = draws.get();
|
||||
|
||||
h.resize((800, 100));
|
||||
h.frame();
|
||||
|
||||
assert_eq!(draws.get(), settled + 1, "its box is a different length");
|
||||
assert_corners!(h, leaf, (0, 0), (800, 100));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_resize_redraws_what_read_the_output() {
|
||||
let mut h = Harness::new((400, 200));
|
||||
|
||||
Reference in new issue
Block a user