Record the leftover minimum and the images in the trees
Two rounds past the ninth sweep: `b295c8b` reads a share under a parent that divides nothing as a minimum, which is what Bryan said it means and what a span already did, sharing one comparison with it; `2dba90b` grows images in the generated trees, which is the only widget here whose hint is a length in pixels and so the only one that reaches the case. The dump baseline is 34,571 boxes now that the trees carry images, and a seed no longer names the tree it used to -- the log says what that costs and where those defects live instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
da6b003a1e
commit
6a92857079
2 files changed
+68
-21
No files matched your search
+17
-11
@@ -6,8 +6,8 @@ found is in `docs/LAYOUT_LOG.md`.
|
|||||||
|
|
||||||
## The Iris layout repair is submitted
|
## The Iris layout repair is submitted
|
||||||
|
|
||||||
**Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `c2b8bf8`,
|
**Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `2dba90b`,
|
||||||
and past the reviewed `cadfba0` it is eleven rounds, each described in
|
and past the reviewed `cadfba0` it is twelve rounds, each described in
|
||||||
`docs/LAYOUT_LOG.md`:
|
`docs/LAYOUT_LOG.md`:
|
||||||
|
|
||||||
- **The repair**, `add6774` and `84dad21` -- collapsed-share placement,
|
- **The repair**, `add6774` and `84dad21` -- collapsed-share placement,
|
||||||
@@ -50,6 +50,11 @@ and past the reviewed `cadfba0` it is eleven rounds, each described in
|
|||||||
call sites, the helper the eighth sweep shared being unable to see the
|
call sites, the helper the eighth sweep shared being unable to see the
|
||||||
defect it had just fixed, two bare arrays where the framework names the
|
defect it had just fixed, two bare arrays where the framework names the
|
||||||
pair, forty-five lines nothing references, and one word for two things.
|
pair, forty-five lines nothing references, and one word for two things.
|
||||||
|
- **A leftover as a minimum, and images in the trees**, `b295c8b` and
|
||||||
|
`2dba90b` -- a share under a parent that divides nothing losing the
|
||||||
|
overflow its pixels asked for, said as the place the parent gives and
|
||||||
|
sharing one comparison with the span; and `Image` grown in the generated
|
||||||
|
trees, which is the only widget here whose hint is a length in pixels.
|
||||||
|
|
||||||
The settled design of the vocabulary rounds is in `docs/LAYOUT.md` under
|
The settled design of the vocabulary rounds is in `docs/LAYOUT.md` under
|
||||||
"Three names, and the one argument that says them". Bryan settled the API
|
"Three names, and the one argument that says them". Bryan settled the API
|
||||||
@@ -106,9 +111,9 @@ the name it is reachable by.
|
|||||||
**Always**, because they cost nothing: format, workspace clippy under
|
**Always**, because they cost nothing: format, workspace clippy under
|
||||||
`-D warnings` with and without `layout-diagnostics`, the workspace tests, and
|
`-D warnings` with and without `layout-diagnostics`, the workspace tests, and
|
||||||
the **cold dump**. `layout_dump` over 400 depth-5 trees is **34,488** boxes
|
the **cold dump**. `layout_dump` over 400 depth-5 trees is **34,488** boxes
|
||||||
-- counted again on 2026-09-20, the fourth through eighth sweeps having all
|
-- **34,571 since `2dba90b` grew images in the trees**; counted again on
|
||||||
repeated 34,492, which is a `wc -l` of the whole run rather than of its box
|
2026-09-20, the fourth through eighth sweeps having all repeated 34,492, which
|
||||||
lines -- and it is the only thing that catches two same-typed values being
|
is a `wc -l` of the whole run rather than of its box lines -- and it is the only thing that catches two same-typed values being
|
||||||
swapped, which is the failure mode of a rename or a move. Count the lines
|
swapped, which is the failure mode of a rename or a move. Count the lines
|
||||||
that are a box (`grep -cE '^[0-9]+ [0-9]+ '`), not the output. The repair moved 650 of those
|
that are a box (`grep -cE '^[0-9]+ [0-9]+ '`), not the output. The repair moved 650 of those
|
||||||
boxes, all from the collapsed-share correction; every commit since has been
|
boxes, all from the collapsed-share correction; every commit since has been
|
||||||
@@ -178,11 +183,10 @@ glyphs do not follow a shortened entry.
|
|||||||
- A span can overflow itself without bound, so boxes of negative length reach
|
- A span can overflow itself without bound, so boxes of negative length reach
|
||||||
children and nothing states what a widget may assume about one.
|
children and nothing states what a widget may assume about one.
|
||||||
- A `leftover` under a parent that does not divide is a minimum size --
|
- A `leftover` under a parent that does not divide is a minimum size --
|
||||||
`max(box, px + rel*box)` (Bryan, 2026-09-20). A span does that; the
|
`max(box, px + rel*box)` (Bryan, 2026-09-20), which is a `SizeRule::Min` of
|
||||||
non-dividing path drops the overflow where the fixed part is longer than
|
`rel(1.0)` and shares `Painter::longer_than` with the span. Done in
|
||||||
the box. Measured in `docs/LAYOUT_LOG.md` under the ninth sweep, with the
|
`b295c8b` for a widget its parent asks; `root_layout` still reads the old
|
||||||
window contract a fix needs. Nothing here mixes the two, so nothing is
|
way, for which see `docs/LAYOUT_LOG.md`.
|
||||||
wrong on screen.
|
|
||||||
- `Fixed::div` by zero answers `MIN`/`MAX` while `ratio` answers `ZERO`; both
|
- `Fixed::div` by zero answers `MIN`/`MAX` while `ratio` answers `ZERO`; both
|
||||||
are caller bugs under `debug_assert`, but the fallbacks differ.
|
are caller bugs under `debug_assert`, but the fallbacks differ.
|
||||||
- `docs/LAYOUT.md` §4, §5 and the density section name `Painter::place`,
|
- `docs/LAYOUT.md` §4, §5 and the density section name `Painter::place`,
|
||||||
@@ -191,7 +195,9 @@ glyphs do not follow a shortened entry.
|
|||||||
`OnResize::Translate` or `OrthoSize`.
|
`OnResize::Translate` or `OrthoSize`.
|
||||||
- `LazySpan`, then `SizeRule::{Min, Max, Clamp}`. A cap may not contain
|
- `LazySpan`, then `SizeRule::{Min, Max, Clamp}`. A cap may not contain
|
||||||
`leftover`; whether `Max` narrows the child's drawing box is a product
|
`leftover`; whether `Max` narrows the child's drawing box is a product
|
||||||
decision.
|
decision. `Min` is `Painter::longer_than` again -- a `leftover` where
|
||||||
|
nothing divides it is already a `Min` of `rel(1.0)` -- so it belongs on
|
||||||
|
that path rather than beside it.
|
||||||
- `Scroll` taking a direction rather than one axis.
|
- `Scroll` taking a direction rather than one axis.
|
||||||
|
|
||||||
Other product work is in `docs/PLAN.md` and the focused documents it links.
|
Other product work is in `docs/PLAN.md` and the focused documents it links.
|
||||||
|
|||||||
+51
-10
@@ -6,6 +6,28 @@ nothing here is rediscovered. Each entry says who found it and when.
|
|||||||
it (settled design, the measurement method) belongs in `docs/LAYOUT.md`, and
|
it (settled design, the measurement method) belongs in `docs/LAYOUT.md`, and
|
||||||
the current plan is in `docs/HANDOFF.md`.
|
the current plan is in `docs/HANDOFF.md`.
|
||||||
|
|
||||||
|
## Images in the generated trees (2026-09-20)
|
||||||
|
|
||||||
|
`Image` is the only widget here whose size hint is a length in pixels, so it is
|
||||||
|
the only one that exercises a rule beside a hint -- which is what the two
|
||||||
|
findings above are about, and why neither was reachable from a generated tree.
|
||||||
|
Bryan asked for one in the trees, as a committed 64x64 checkerboard reusing one
|
||||||
|
texture handle. `2dba90b`: `Kind::Image` is a fifth leaf drawn one time in five,
|
||||||
|
stepping to a plain rect under the shrinker; the picture is
|
||||||
|
`src/assets/checkerboard.png`, purple and black in 8 px cells, included rather
|
||||||
|
than opened; and a `TextureHandle` is a counted reference, so the first image in
|
||||||
|
a tree uploads and the rest clone it. Measured: seed 1 at depth 4 grows 13
|
||||||
|
images and holds 1 texture, and `a_tree_of_images_uploads_one_texture` asserts
|
||||||
|
it.
|
||||||
|
|
||||||
|
The cost is that a seed no longer names the tree it used to, so the corpus in
|
||||||
|
`generated.rs` is a corpus and not a set of regression cases -- 20 and 86 no
|
||||||
|
longer grow the trees whose defects they caught. Both live on as shrunk fixtures
|
||||||
|
in `unsettled.rs`, which are trees rather than numbers, and both files now say
|
||||||
|
so. New dump baseline: **34,571** boxes over the 400 depth-5 trees. All three
|
||||||
|
scans pass over the new trees (400 at depth 5 in 62.79s, 1,000 at depth 6 in
|
||||||
|
160.20s, 2,000 at depth 4 in 299.58s).
|
||||||
|
|
||||||
## Ninth sweep: the widget vocabulary, and the eighth sweep's fix (2026-09-20)
|
## Ninth sweep: the widget vocabulary, and the eighth sweep's fix (2026-09-20)
|
||||||
|
|
||||||
Over the part no earlier round named -- `src/widget/trait_fns.rs` and
|
Over the part no earlier round named -- `src/widget/trait_fns.rs` and
|
||||||
@@ -65,16 +87,35 @@ learns the fixed part and falls back to the offer. The same length without the
|
|||||||
share does overflow (drawn -50..450, its alignment centring it), so what
|
share does overflow (drawn -50..450, its alignment centring it), so what
|
||||||
swallows it is the share and not the overflow.
|
swallows it is the share and not the overflow.
|
||||||
|
|
||||||
Fixing it means answering the longer of the offer and the fixed part, which is
|
**Fixed in `b295c8b`**, after Bryan asked for it if it was cheap and pointed out
|
||||||
not a `Len`: a maximum of two linear forms is not linear in the box, so it has
|
that the machinery is a minimum size of `rel(1.0)` and should share a path with
|
||||||
to be resolved where the box is known and the crossover pinned as a window
|
one. What made it cheap was saying it as the place the parent gives rather than
|
||||||
contract -- which is exactly what `Span` does with `has_room` and
|
as a declaration: where the fixed part is the longer, `widget_at` hands the
|
||||||
`painter.window_holds(axis, holds.through(room))`. In `widget_at` that range
|
child `fixed.as_desc().fills()`, which is what a declared length already comes
|
||||||
belongs to the parent, whose box decides it, so a parent of such a child would
|
to, and `active.placed` keeps it -- so nothing about `Declared`, `ActiveData` or
|
||||||
redraw across the crossover. **Not done: it is what a length means, and it is
|
the resize path had to change. A place that is already the child's placement is
|
||||||
Bryan's to say whether that cost is wanted.** Nothing in the repository mixes
|
skipped, because a parent that divides has given the share whatever it was owed;
|
||||||
`px` or `rel` with `leftover` outside the span's own test, so nothing is wrong
|
without that guard a span's slot was re-placed and its child moved from 0..500
|
||||||
on screen today.
|
to -50..450.
|
||||||
|
|
||||||
|
The comparison is one operation now, `Painter::longer_than`, and both callers
|
||||||
|
share it: the span's room for the shares it divides, and a share past the box it
|
||||||
|
was given. It narrows the widget's window range where the span replaced it,
|
||||||
|
since a comparison the framework makes on an arbitrary parent's behalf is one
|
||||||
|
more reason its drawing holds rather than the only one. `SizeRule::Min` of
|
||||||
|
`rel(1.0)` is the same operation and belongs on the same path when it lands.
|
||||||
|
|
||||||
|
Two things were tried and dropped. An escalation for a changed rule
|
||||||
|
(`shares_past_a_length`) turned out to buy nothing: the reported size is the
|
||||||
|
rule resolved, so a changed rule changes the answer and the parent refuses its
|
||||||
|
own drawing -- the tests pass without it. And `Holds::crossing`, a named
|
||||||
|
constructor for the range, had one caller and read better spelled there.
|
||||||
|
|
||||||
|
**The root still reads the old way.** `root_layout` asks
|
||||||
|
`Widgets::declared_lens` with no painter, so a mixed share on the root is the
|
||||||
|
window rather than the longer of the two. It would mean the comparison in a
|
||||||
|
second place, and the root's box is the window and is relaid out on every
|
||||||
|
resize; nothing here puts a share on a root.
|
||||||
|
|
||||||
**Marking a widget for redraw had no name.** Twenty-one sites under `tests/`
|
**Marking a widget for redraw had no name.** Twenty-one sites under `tests/`
|
||||||
said it as `widgets_mut().get_dyn_mut(id);` with the widget thrown away: five
|
said it as `widgets_mut().get_dyn_mut(id);` with the widget thrown away: five
|
||||||
|
|||||||
Reference in new issue
Block a user