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
+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
|
||||
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)
|
||||
|
||||
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
|
||||
swallows it is the share and not the overflow.
|
||||
|
||||
Fixing it means answering the longer of the offer and the fixed part, which is
|
||||
not a `Len`: a maximum of two linear forms is not linear in the box, so it has
|
||||
to be resolved where the box is known and the crossover pinned as a window
|
||||
contract -- which is exactly what `Span` does with `has_room` and
|
||||
`painter.window_holds(axis, holds.through(room))`. In `widget_at` that range
|
||||
belongs to the parent, whose box decides it, so a parent of such a child would
|
||||
redraw across the crossover. **Not done: it is what a length means, and it is
|
||||
Bryan's to say whether that cost is wanted.** Nothing in the repository mixes
|
||||
`px` or `rel` with `leftover` outside the span's own test, so nothing is wrong
|
||||
on screen today.
|
||||
**Fixed in `b295c8b`**, after Bryan asked for it if it was cheap and pointed out
|
||||
that the machinery is a minimum size of `rel(1.0)` and should share a path with
|
||||
one. What made it cheap was saying it as the place the parent gives rather than
|
||||
as a declaration: where the fixed part is the longer, `widget_at` hands the
|
||||
child `fixed.as_desc().fills()`, which is what a declared length already comes
|
||||
to, and `active.placed` keeps it -- so nothing about `Declared`, `ActiveData` or
|
||||
the resize path had to change. A place that is already the child's placement is
|
||||
skipped, because a parent that divides has given the share whatever it was owed;
|
||||
without that guard a span's slot was re-placed and its child moved from 0..500
|
||||
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/`
|
||||
said it as `widgets_mut().get_dyn_mut(id);` with the widget thrown away: five
|
||||
|
||||
Reference in new issue
Block a user