A quality sweep over the deferred request system, which no earlier round has reviewed. `Bound::outside` said which end a length fell outside and left the caller to look that end up through `Bound::at`, which `expect`s an end the value it is given does not promise: only the pairing of the two calls kept `at(Shorter)` off a bound with no floor. It already had the length in hand, so it returns that, and `Outside` and `at` go with the state that could panic. `measured_request` pinned the rel base for any bound at all, so a measured share under a cap in pixels was invalidated by a change to a base its answer cannot depend on. That question is `Bound::has_fraction` now, which is also the one `Placing::ask` and `SizeRule::has_fraction` were each writing out over a bare array. The rest is one name where there were several spellings: `Span::gaps`, `Padding::along`, `Plan::drop_bounds` behind one `IRIS_UNBOUNDED` in both rigs that had grown their own, and `Stack::size_request` resolving its sizing child the way its draw already does. `Span`'s placement loop asked three times whether the row was allocated, twice to decide one child's length; one match answers all three, so the allocated and plain rules are read side by side. The buffers `draw_at` now reuses for their capacity are empty only because every path to it drains them in `remove`; a `debug_assert` says so, since a drawing over primitives left in one would record them twice. Comments: `with_requests` named discovery as the hazard where it is a child drawn mid-row, `Painter::allocate` documented the window it holds for rather than what it does, `minimum_request` had none, and the note saying a span carries its children's weight whole -- which is still what the unallocated path does, and still the surprising part -- had been replaced by one about the other path.
48 lines
1.8 KiB
Rust
48 lines
1.8 KiB
Rust
//! Prints where a cold layout puts every widget of many grown trees, so two
|
|
//! commits can be compared on cold layout alone. The warm/cold oracle cannot
|
|
//! see a change that moves cold layout, since both of its sides move; this
|
|
//! can, by diffing its output across the change:
|
|
//!
|
|
//! IRIS_DUMP_SEEDS=400 IRIS_DUMP_DEPTH=5 cargo test --release \
|
|
//! --test layout_dump -- --ignored --nocapture > /tmp/before.txt
|
|
//!
|
|
//! then the same after, and `diff` the two. A line is one widget: the seed,
|
|
//! its index in creation order, and its box in window pixels, or `-` where
|
|
//! it is not drawn. `IRIS_UNBOUNDED=1` drops the trees' intrinsic bounds, as
|
|
//! in the diagnostics rig, which compares the two paths over the same shapes.
|
|
|
|
use iris::harness::Harness;
|
|
use iris::random::{Edits, build, plan};
|
|
|
|
fn env<T: std::str::FromStr>(name: &str, fallback: T) -> T {
|
|
std::env::var(name)
|
|
.ok()
|
|
.and_then(|value| value.parse().ok())
|
|
.unwrap_or(fallback)
|
|
}
|
|
|
|
#[test]
|
|
#[ignore = "a dump to diff across commits, not a check"]
|
|
fn every_cold_layout_is_printed() {
|
|
let seeds = env("IRIS_DUMP_SEEDS", 400_u64);
|
|
let depth = env("IRIS_DUMP_DEPTH", 5_usize);
|
|
let mut out = String::new();
|
|
for seed in 1..=seeds {
|
|
let mut harness = Harness::new((1920.0, 1200.0));
|
|
let mut plan = plan(seed, depth, &Edits::default());
|
|
if env("IRIS_UNBOUNDED", 0_u8) != 0 {
|
|
plan.drop_bounds();
|
|
}
|
|
let (root, tree) = build(&mut harness.rsc, &plan);
|
|
harness.state.root = Some(root);
|
|
harness.frame();
|
|
for (index, id) in tree.ids.iter().enumerate() {
|
|
match harness.region(id) {
|
|
Some(region) => out.push_str(&format!("{seed} {index} {region:?}\n")),
|
|
None => out.push_str(&format!("{seed} {index} -\n")),
|
|
}
|
|
}
|
|
}
|
|
print!("{out}");
|
|
}
|