Skip to content

Commit

Permalink
Don't store modifiers in an adjacent List (#2047)
Browse files Browse the repository at this point in the history
There's a 'context' field in Node that's a better fit.

The problem with storing modifiers in an adjacent list is that
Yoga occasionally will create a mutable copy of the layout nodes
to do some layout calculation, and this mutable copy may drift
from our true copy with respect to child counts.
  • Loading branch information
squarejesse authored May 21, 2024
1 parent 281a1d4 commit a891de3
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,9 @@ import platform.darwin.NSInteger
internal class UIViewFlexContainer(
direction: FlexDirection,
) : YogaFlexContainer<UIView>, ChangeListener {
private val modifiers = mutableListOf<Modifier>()
private val yogaView: YogaUIView = YogaUIView(
applyModifier = { node, index ->
node.applyModifier(modifiers[index], Density.Default)
node.applyModifier(node.context as Modifier, Density.Default)
},
)
override val rootNode: Node get() = yogaView.rootNode
Expand All @@ -43,19 +42,17 @@ internal class UIViewFlexContainer(
override val children: UIViewChildren = UIViewChildren(
container = value,
insert = { view, modifier, index ->
modifiers.add(index, modifier)
yogaView.rootNode.children.add(index, view.asNode())
yogaView.rootNode.children.add(index, view.asNode(context = modifier))
value.insertSubview(view, index.convert<NSInteger>())
},
remove = { index, count ->
modifiers.remove(index, count)
yogaView.rootNode.children.remove(index, count)
Array(count) {
value.typedSubviews[index].also(UIView::removeFromSuperview)
}
},
updateModifier = { modifier, index ->
modifiers[index] = modifier
yogaView.rootNode.children[index].context = modifier
},
)
override var modifier: Modifier = Modifier
Expand All @@ -82,8 +79,9 @@ internal class UIViewFlexContainer(
}
}

private fun UIView.asNode(): Node {
private fun UIView.asNode(context: Any?): Node {
val childNode = Node()
childNode.measureCallback = UIViewMeasureCallback(this)
childNode.context = context
return childNode
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public class Node internal constructor(

// Inputs
public val children: MutableList<Node> = Children()
public var context: Any?
get() = native.context
set(value) {
native.context = value
}
public val owner: Node?
get() = native.owner?.let(::Node)
public var direction: Direction
Expand Down

0 comments on commit a891de3

Please sign in to comment.