`.width()` built a `SetSize` whose whole job was to answer `size_hint`, so every declared length cost a widget, an `ActiveData` and a link of chain to say one number. It is now a `SizeRule` per axis on `WidgetData`, beside `region_node`, resolved by `Painter` where the widget is drawn. `SetSize` and `MaxSize` are gone; `MaxSize` had no caller but its own builders. That settles which of two answers is the size. A rule wins on the axis it names and the `Size` returned by `draw` answers the rest, applied once in `draw_inner` rather than by each widget that could carry one -- so the widget under a rule never learns of it. `Painter::size_hint` reads the rule first for the same reason: a rule that beats what a widget would draw has to beat what it says about itself. `declared_lens` still falls back to a non-leftover `size_hint`, which is how an image or a gap gets its own pixel size rather than the whole offer. That is the offer's business rather than a declaration's, and it falls away when a widget occupies its reported size inside the box it was offered. `known` and `declared` are separate because a share is a length to whoever divides one and not to whoever composes a box: `.width(leftover(3))` is known without drawing but cannot narrow anything. Checked: fmt, clippy, 85 tests, and 100 generated seeds agreeing warm against cold in 67.6 s. `minimal`, `text` and `view` render byte-identical at 1920x1200; `tabs` differs only in the widget count it prints about itself, which is two wrapper types smaller.
42 lines
1.3 KiB
Rust
42 lines
1.3 KiB
Rust
//! What remapping a subtree costs per frame, as a load for a counter rather
|
|
//! than a check. A span of 200 fixed-height rows, five primitives each, with
|
|
//! the row above them changing height every frame, so every row below is
|
|
//! offered a box the same shape somewhere else.
|
|
//!
|
|
//! cargo test --release --test replace_cost -- --ignored
|
|
//! perf stat -e instructions:u target/release/.../replace_cost-* --ignored
|
|
//!
|
|
//! Wall time is the wrong number here; see `draw_cost.rs`.
|
|
|
|
use iris::harness::Harness;
|
|
use iris::prelude::*;
|
|
|
|
const ROWS: usize = 200;
|
|
const FRAMES: usize = 200;
|
|
|
|
#[test]
|
|
#[ignore = "measurement, not a check"]
|
|
fn remapping_rows_every_frame() {
|
|
let mut h = Harness::new((1920, 1200));
|
|
let first = rect(Color::RED).height(40).add(&mut h.rsc);
|
|
let mut span = Span::empty(Dir::DOWN);
|
|
span.push(first.add_strong(&mut h.rsc));
|
|
for i in 0..ROWS {
|
|
let row = (
|
|
rect(Color::BLUE.darker(i as f32 / (ROWS * 2) as f32)),
|
|
rect(Color::GREEN).pad(2),
|
|
wtext("row").size(16).pad(2),
|
|
)
|
|
.span(Dir::RIGHT)
|
|
.pad(4)
|
|
.height(40)
|
|
.add(&mut h.rsc);
|
|
span.push(row.add_strong(&mut h.rsc));
|
|
}
|
|
h.set_root(span);
|
|
for i in 0..FRAMES {
|
|
h.set_len(first, Axis::Y, 40.0 + (i % 2) as f32);
|
|
h.frame();
|
|
}
|
|
}
|