///|
/// Builds the platform tree from element/layout state without invoking paint.
/// Clean subtrees reuse their immutable cached node, while a dirty route is
/// rebuilt in DFS order so host placement ordering stays stable.
fn ElementNode::platform_with_environment(
self : ElementNode,
placed : PlacedNode,
environment : RenderEnvironment,
) -> PlatformNode {
if !self.has_dirty_platform() &&
self.platform_cache.frame == Some(placed.frame) &&
self.platform_cache.environment == Some(environment.environment) &&
self.platform_cache.style == Some(environment.style) {
match self.platform_cache.node {
Some(node) => return node
None => ()
}
}
let cache_key_matches = self.platform_cache.frame == Some(placed.frame) &&
self.platform_cache.environment == Some(environment.environment) &&
self.platform_cache.style == Some(environment.style)
let placements = if !self.dirty.needs_platform && cache_key_matches {
match self.platform_cache.node {
Some(node) => node.placements.copy()
None =>
self.view_node.platform_views({
frame: placed.frame,
child_frames: placed.children.map(child => child.frame),
environment: environment.environment,
style: environment.style,
})
}
} else {
self.view_node.platform_views({
frame: placed.frame,
child_frames: placed.children.map(child => child.frame),
environment: environment.environment,
style: environment.style,
})
}
let children : Array[PlatformNode] = []
let child_environment = environment.with_child_context(self.view_node)
for index, child in self.children {
if index < placed.children.length() {
children.push(
child.platform_with_environment(
placed.children[index],
child_environment,
),
)
}
}
let node = PlatformNode::{ placements, children, }
self.dirty.needs_platform = false
self.refresh_descendant_dirty_flags()
self.platform_cache.frame = Some(placed.frame)
self.platform_cache.environment = Some(environment.environment)
self.platform_cache.style = Some(environment.style)
self.platform_cache.node = Some(node)
node
}
///|
fn PlatformNode::collect_placements(
self : PlatformNode,
output : Array[PlatformViewPlacement],
) -> Unit {
output.append(self.placements)
for child in self.children {
child.collect_placements(output)
}
}
///|
fn PlatformTree::placements(
self : PlatformTree,
) -> Array[PlatformViewPlacement] {
let output : Array[PlatformViewPlacement] = []
self.root.collect_placements(output)
output
}