You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: After I finished writing all these, I realised it might be too complicated to have the idea actually implemented as-is in iced. But anyway it is just a rough idea, and I believe at least the motivating problem is worth some discussions.
Currently, a Node keeps all its children Nodes in a Vec. If, for instance (for a hypothetical Table widget), we have a long Column with a lot of children widgets (table rows), keeping all the children in memory is very inefficient.
Consider the following situation:
(in Widget::layout) Table measures the height of its children (the table rows), and generate the layout nodes;
(in Widget::draw) Table traverses the children Layout nodes, and draw only the children in the viewport;
Assuming all the children share the same size (which is often the case for tables; even if the assumption is not true, it is a reasonable approximation for optimisation), the layout nodes could be generated on the fly during the rendering process (i.e., in Widget::draw).
What if instead of a Vec<Node>, we store an iterator of Node (or more precisely, a function that returns an iterator, because it needs to repeatedly provide the same iterator to be traversed), and let the iterator generate the nodes on demand? Specifically, we replace children: Vec<Node> with the following:
Using this approach, the layout logic and the rendering logic are still clearly separated, but the actual computation for the layout nodes are postponed to the rendering phase, and the layout nodes are discarded immediately after their use. The downside is the potential performance loss due to the use of trait objects.
Note: The Nodes generated on the fly are necessarily owned (therefore by-value); the Nodes from a Vec had better be borrowed instead of cloned (therefore by-reference). To unify them, we might need the version with Cow<Node>. From a different perspective, this dilemma could also be solved using a "lending iterator":
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Note: After I finished writing all these, I realised it might be too complicated to have the idea actually implemented as-is in
iced
. But anyway it is just a rough idea, and I believe at least the motivating problem is worth some discussions.Currently, a
Node
keeps all its childrenNode
s in aVec
. If, for instance (for a hypotheticalTable
widget), we have a longColumn
with a lot of children widgets (table rows), keeping all the children in memory is very inefficient.Consider the following situation:
Widget::layout
)Table
measures the height of its children (the table rows), and generate the layout nodes;Widget::draw
)Table
traverses the childrenLayout
nodes, and draw only the children in the viewport;Assuming all the children share the same size (which is often the case for tables; even if the assumption is not true, it is a reasonable approximation for optimisation), the layout nodes could be generated on the fly during the rendering process (i.e., in
Widget::draw
).What if instead of a
Vec<Node>
, we store an iterator ofNode
(or more precisely, a function that returns an iterator, because it needs to repeatedly provide the same iterator to be traversed), and let the iterator generate the nodes on demand? Specifically, we replacechildren: Vec<Node>
with the following:Original definition for
Node
(linked for reference):iced/core/src/layout/node.rs
Lines 4 to 8 in b5f102c
This is strictly more general than the current implementation: in the new strategy, we replace a vector
xs
withBox::new(VecChildren(xs))
:Using this approach, the layout logic and the rendering logic are still clearly separated, but the actual computation for the layout nodes are postponed to the rendering phase, and the layout nodes are discarded immediately after their use. The downside is the potential performance loss due to the use of trait objects.
Note: The
Node
s generated on the fly are necessarily owned (therefore by-value); theNode
s from aVec
had better be borrowed instead of cloned (therefore by-reference). To unify them, we might need the version withCow<Node>
. From a different perspective, this dilemma could also be solved using a "lending iterator":Beta Was this translation helpful? Give feedback.
All reactions