Skip to main content

resolve_layout_direction

Function resolve_layout_direction 

Source
pub fn resolve_layout_direction(
    commands: Commands<'_, '_>,
    default_dir: Option<Res<'_, DefaultLayoutDirection>>,
    dirs: Query<'_, '_, &LayoutDirection>,
    parents: Query<'_, '_, &ChildOf>,
    all: Query<'_, '_, Entity, Without<IsResource>>,
    resolved_q: Query<'_, '_, &ResolvedDirection>,
    changed_inputs: Query<'_, '_, (), Or<(Changed<LayoutDirection>, Changed<ChildOf>)>>,
    unstamped: Query<'_, '_, (), Without<ResolvedDirection>>,
    removed_dirs: RemovedComponents<'_, '_, LayoutDirection>,
    removed_parents: RemovedComponents<'_, '_, ChildOf>,
)
Expand description

Resolve every entity’s LayoutDirection (defaulting to LayoutDirection::Auto when the component is absent) against its ancestor chain and stamp the answer into ResolvedDirection.

Roots whose direction is Auto fall back to the DefaultLayoutDirection resource. Runs in crate::tick::TickStage::LayoutSync before the layout backend reads ResolvedDirection.

Algorithm: one pass over every entity. For each entity, walk ChildOf to the nearest ancestor that either (a) has an explicit Ltr / Rtl direction, or (b) is the root. Honour the override or the resource default. Time is O(depth) per entity; with shallow UI trees (<= 16 levels) this is cheap and avoids any allocation.

D9: the pass is gated on its actual inputs - an explicit LayoutDirection changing / appearing / disappearing, a hierarchy edit (ChildOf changed or removed), the DefaultLayoutDirection resource changing, or entities that have never been stamped. Steady ticks cost a handful of empty-query checks. When the pass does run, ResolvedDirection is only (re)inserted when the value actually differs, so Changed<ResolvedDirection> downstream (the layout backend’s D8 hook) fires exclusively on real flips.