Replies: 3 comments 3 replies
-
|
It would be greate to have subcomposition in compose-rt, but I don't have idea how it can be implement yet main idea of SubcomposeLayout
|
Beta Was this translation helpful? Give feedback.
-
|
and currently compose-rt only has composition phase by calling recompose, the layout and drawing phase is not part of compose-rt. |
Beta Was this translation helpful? Give feedback.
-
|
Draft example and list unresolved questions, maybe a good start to identify what is missing in compose-rt. use std::env;
use compose_rt::{ComposeNode, Composer, Root};
#[derive(Debug, Clone)]
pub struct Style {
width: usize,
height: usize,
}
#[derive(Debug)]
pub enum LayoutNode {
Eager(Style),
// TODO: what should be here, or LayoutNode should be a Trait?
Lazy,
}
impl ComposeNode for LayoutNode {
type Context = ();
}
type Scope<S> = compose_rt::Scope<S, LayoutNode>;
pub struct Container;
fn container<P, C>(s: Scope<P>, style: Style, content: C)
where
P: 'static,
C: Fn(Scope<Container>) + Clone + 'static,
{
let child_scope = s.child::<Container>();
s.create_node(
child_scope,
content,
move || style.clone(),
|style, _| LayoutNode::Egar(style),
|_, _, _| {},
);
}
pub struct Leaf;
fn leaf<P>(s: Scope<P>, style: Style)
where
P: 'static,
{
let child_scope = s.child::<Leaf>();
s.create_node(
child_scope,
|_| {},
|| {},
move |_, _| LayoutNode::Egar(style.clone()),
|_, _, _| {},
);
}
// TODO: what should SubcomposeLayout
pub struct SubcomposeLayout;
fn subcompose<P, C>(s: Scope<P>, content: C)
where
P: 'static,
C: Fn(Scope<SubcomposeLayout>) + Clone + 'static,
{
let child_scope = s.child::<SubcomposeLayout>();
s.create_node(
child_scope,
|_| {},
|| {},
move |_, _| LayoutNode::Lazy,
|_, _, _| {},
);
}
fn app(s: Scope<Root>) {
container(
s,
Style {
width: 2,
height: 2,
},
|s| {
leaf(
s,
Style {
width: 1,
height: 1,
},
);
subcompose(s, |s| {
// TODO 1: this component need to access parent scope's child measure result in Layout phase
// 1: s.with_child().iter().fold(0, |max_w, child| max(max_w, match child)) ?, but how
let max_width = todo!();
// TODO 2: delay subcompose's content composition until Layout phase, for lazy list use case
leaf(
s,
Style {
width: max_width,
height: 2,
},
);
});
leaf(
s,
Style {
width: 3,
height: 1,
},
);
},
)
}
fn main() {
let mut recomposer = Composer::compose(app, ());
recomposer.recompose();
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
So, in Compose Runtime we have the ability to create subcompositions. This is quite useful if we want to achieve virtualization, for example. However, this does not seem to be possible in
compose-rt. More precisely, it is possible to simulate subcomposition by creating newRecomposers and storing them inside a type that implementsComposeNode(or inState), but this is fraught with issues. The main issue is that all the states of the main composer will not be available in the child composer. And if we imagine that we implementSubcomposeLayout, then using external states created outside the current composer in itscontentwill result in anAlreadyBorrowederror, since theLayoutphase needs to borrow the current composer, and the external state incontentwill also try to borrow, causing an error.Compose Runtime seems to solve this with the
Compositioninterface, but I'm not sure as I haven't looked into it much.Beta Was this translation helpful? Give feedback.
All reactions