Repository navigation
Let a node read another node's geometry and a text's measurements #328
Description
Part of #326. Batch 2 — depends on #327.
Nothing in a scenario can refer to anything else in it. Eight lines joining a logo to badges orbiting around it were abandoned during the rebuild, because a line's endpoint cannot follow a node whose position is animated. A ? detaching from the end of a typed sentence was abandoned for the same reason: there is no way to ask where that sentence ends.
Glyph positions are already computed at paint time in engine/renderer/text.rs (str_to_glyphs_vec, get_widths, then a positions vector). They are simply never exposed. This workstream is mostly exposure, not new geometry.
Owned files
crates/rustmotion-core/src/engine/deps.rs(new — the dependency graph)crates/rustmotion-core/src/engine/layout_pass.rs,paint_pass.rscrates/rustmotion-core/src/engine/renderer/text.rs(retain and expose the glyph run)crates/rustmotion-components/src/intrinsic.rs
Do NOT write: crates/rustmotion-core/src/expr/** (#327 owns the evaluator; add reference resolution as a resolver it calls).
Deliverables
-
A node takes an optional
id, unique within its scene. An expression then reads@id.prop. -
Four families of readable property.
Family Properties Resolved Geometry x y width height cx cy right bottomafter layout_passAnimated transform tx ty scale rotation opacityper frame Text measurement textWidth capHeight ascender baselineafter layout_passGlyphs glyph(n).x,glyph(n).cx,glyphCountafter layout_passThe animated-transform family is the one that carries the architectural cost, and it is the one the eight lines need.
-
A dependency graph built once at load and topologically sorted. Static references resolve in a pass after
layout_pass. Animated references resolve per frame, in topological order rather than tree order. Getting this wrong yields values one frame stale, which is invisible until someone pauses, so the ordering needs a test that would catch exactly that. -
Errors — a cycle is reported at load with the full chain, named and located. A reference crossing a scene boundary is
reference_cross_sceneand is rejected, since scenes are independent render units. -
The detaching glyph needs no glyph slicing. The author writes the sentence without its last character and places a separate node at
"x": "= @q.right"with its own animation.glyph(n)remains for per-letter work thechar_*presets do not cover.
Acceptance
- A
linewhosex2is"= @chip3.cx + @chip3.tx"tracks an orbiting badge across every frame, with no one-frame lag - A cycle
A -> B -> Afails at load naming both nodes text.caretstill works unchanged; it already covers the caret case and is not re-implemented here
Activity
[-]WS-2 expressions: an arithmetic layer for scenario values[/-][+]WS-3 references: node identity, cross-node reads and text measurement[/+][-]WS-3 references: node identity, cross-node reads and text measurement[/-][+]Let a node read another node's geometry and a text's measurements[/+]LeadcodeDev commentedon Sep 26, 2026
Delivered on
mainat 187cf7c (squash of #340). Verified present onmain, not taken on the PR's word.