Skip to content

Commit

Permalink
refactor(core): 💡 remove the BuildCtx parameter from the function w…
Browse files Browse the repository at this point in the history
…idget
  • Loading branch information
M-Adoo committed Nov 7, 2024
1 parent 4eca31d commit 6b1155f
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 60 deletions.
19 changes: 8 additions & 11 deletions core/src/builtin_widgets/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl<'c> ComposeChild<'c> for Class {

fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> Widget<'c> {
let f = move |ctx: &mut BuildCtx| match this.try_into_value() {
Ok(c) => c.apply_style(child, ctx),
Ok(c) => c.apply_style(child),
Err(this) => {
let this2 = this.clone_watcher();
let cls_child = ClassChild::new(ctx.tree().dummy_id());
Expand All @@ -146,7 +146,7 @@ impl<'c> ComposeChild<'c> for Class {

this
.read()
.apply_style(child, ctx)
.apply_style(child)
.on_build(move |child_id, ctx| cls_child.set_child_id(child_id, ctx))
}
};
Expand All @@ -155,9 +155,9 @@ impl<'c> ComposeChild<'c> for Class {
}

impl Class {
pub fn apply_style<'a>(&self, w: Widget<'a>, ctx: &BuildCtx) -> Widget<'a> {
pub fn apply_style<'a>(&self, w: Widget<'a>) -> Widget<'a> {
let class = self.class.and_then(|cls| {
ctx
BuildCtx::get()
.all_providers::<Classes>()
.find_map(|c| QueryRef::filter_map(c, |c| c.store.get(&cls)).ok())
});
Expand Down Expand Up @@ -209,17 +209,14 @@ impl ClassChild {
AppCtx::get_window(wnd_id).expect("This handle is not valid because the window is closed");
let InnerClassChild { child, child_id, orig_id } = self.inner();
let _guard = BuildCtx::set_ctx_for(*child_id, wnd.tree);
let ctx = BuildCtx::get_mut();
let cls_holder = child_id.place_holder(ctx.tree());
let n_orig = BuildCtx::get_mut().alloc(Box::new(orig.clone()));
let tree = BuildCtx::get_mut().tree_mut();
let cls_holder = child_id.place_holder(tree);

// Extract the child from this node, retaining only the external information
// linked from the parent to create a clean context for applying the class.
let child_node = self.take_inner();
let n_orig = ctx.alloc(Box::new(orig.clone()));
let new_id = class
.apply_style(Widget::from_id(n_orig), ctx)
.build(ctx);
let tree = ctx.tree_mut();
let new_id = class.apply_style(Widget::from_id(n_orig)).build();
// Place the inner child node within the old ID for disposal, then utilize the
// class node to wrap the new child in the new ID.
// This action should be taken before modifying the `orig_id`, as the `orig_id`
Expand Down
2 changes: 1 addition & 1 deletion core/src/context/build_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ptr::NonNull;
use smallvec::SmallVec;
use widget_id::{RenderQueryable, new_node};

use crate::{local_sender::LocalSender, prelude::*, render_helper::PureRender};
use crate::{local_sender::LocalSender, prelude::*};

/// A context provide during build the widget tree.
pub struct BuildCtx {
Expand Down
13 changes: 6 additions & 7 deletions core/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,10 @@ impl Overlay {
};

let _guard = BuildCtx::set_ctx_for(wnd.tree().root(), wnd.tree);
let ctx = BuildCtx::get_mut();
let id = gen(ctx).build(ctx);
let id = gen(BuildCtx::get_mut()).build();
self.0.borrow_mut().showing = Some(ShowingInfo { id, generator: gen.into(), wnd_id: wnd.id() });

let showing_overlays = Provider::of::<ShowingOverlays>(&*ctx).unwrap();
let showing_overlays = Provider::of::<ShowingOverlays>(BuildCtx::get()).unwrap();
showing_overlays.add(self.clone());

let tree = wnd.tree_mut();
Expand All @@ -234,14 +233,14 @@ impl Overlay {
pub(crate) struct ShowingOverlays(RefCell<Vec<Overlay>>);

impl ShowingOverlays {
pub(crate) fn rebuild(&self, ctx: &mut BuildCtx) {
pub(crate) fn rebuild(&self) {
for o in self.0.borrow().iter() {
let mut o = o.0.borrow_mut();
let ShowingInfo { id, generator, .. } = o.showing.as_mut().unwrap();

id.dispose_subtree(ctx.tree_mut());
*id = generator.gen_widget().build(ctx);
let tree = ctx.tree_mut();
let tree = BuildCtx::get_mut().tree_mut();
id.dispose_subtree(tree);
*id = generator.gen_widget().build();
tree.root().append(*id, tree);
id.on_mounted_subtree(tree);
}
Expand Down
14 changes: 6 additions & 8 deletions core/src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub(crate) trait InnerPipe: Pipe + Sized {

let ctx = BuildCtx::get_mut();
let old_node = pipe_node.remove_old_data();
let new = w.into_widget().build(ctx);
let new = w.into_widget().build();
let tree = ctx.tree_mut();
pipe_node.transplant_to_new(old_node, new, tree);

Expand Down Expand Up @@ -169,20 +169,18 @@ pub(crate) trait InnerPipe: Pipe + Sized {
};

let _guard = BuildCtx::set_ctx_for(old[0], tree);
let ctx = BuildCtx::get_mut();

let tree = BuildCtx::get_mut().tree_mut();
let old_node = pipe_node.remove_old_data();
let mut new = vec![];
for (idx, w) in m.into_iter().enumerate() {
let id = w.into_widget().build(ctx);
let id = w.into_widget().build();
new.push(id);
set_pos_of_multi(id, idx, ctx.tree());
set_pos_of_multi(id, idx, tree);
}
if new.is_empty() {
new.push(Void.into_widget().build(ctx));
new.push(Void.into_widget().build());
}

let tree = ctx.tree_mut();
pipe_node.transplant_to_new(old_node, new[0], tree);

query_outside_infos(new[0], &info, tree)
Expand Down Expand Up @@ -268,7 +266,7 @@ pub(crate) trait InnerPipe: Pipe + Sized {
let ctx = BuildCtx::get_mut();

let old_node = pipe_node.remove_old_data();
let p = w.into_widget().build(ctx);
let p = w.into_widget().build();
let tree = ctx.tree_mut();
pipe_node.transplant_to_new(old_node, p, tree);

Expand Down
49 changes: 24 additions & 25 deletions core/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ enum Node<'w> {

enum PureNode<'w> {
Render(Box<dyn RenderQueryable>),
LazyBuild(Box<dyn FnOnce(&mut BuildCtx) -> WidgetId + 'w>),
LazyBuild(Box<dyn FnOnce() -> WidgetId + 'w>),
}

/// This serves as a wrapper for `Box<dyn FnOnce(&BuildCtx) -> Node<'w> +
Expand All @@ -87,7 +87,7 @@ impl<'w> LazyNode<'w> {
Self(f)
}

fn consume(self, ctx: &mut BuildCtx) -> Widget<'w> { (self.0)(ctx) }
fn consume(self) -> Widget<'w> { (self.0)(BuildCtx::get_mut()) }
}

/// A boxed function widget that can be called multiple times to regenerate
Expand Down Expand Up @@ -184,8 +184,9 @@ impl<'w> Widget<'w> {
/// ID and build context as parameters.
pub fn on_build(self, f: impl FnOnce(WidgetId, &mut BuildCtx) + 'w) -> Self {
self.wrap_root(move |n: PureNode<'_>| {
let lazy = move |ctx: &mut BuildCtx| {
let id = n.alloc(ctx);
let lazy = move || {
let ctx = BuildCtx::get_mut();
let id = n.alloc();
f(id, ctx);
id
};
Expand All @@ -196,12 +197,11 @@ impl<'w> Widget<'w> {

/// Build the root node of the widget only.
pub(crate) fn consume_root(self) -> (Self, WidgetId) {
let ctx = BuildCtx::get_mut();
let mut root_id = None;
let node = self.into_node(ctx).wrap_root(|n| {
let id = n.alloc(ctx);
let node = self.into_node().wrap_root(|n| {
let id = n.alloc();
root_id = Some(id);
PureNode::LazyBuild(Box::new(move |_| id))
PureNode::LazyBuild(Box::new(move || id))
});

(Widget(InnerWidget::Node(node)), root_id.unwrap())
Expand Down Expand Up @@ -233,28 +233,27 @@ impl<'w> Widget<'w> {
self.attach_data(data)
}

pub(crate) fn build(self, ctx: &mut BuildCtx) -> WidgetId {
pub(crate) fn build(self) -> WidgetId {
let mut subtrees = vec![];
let root = self.into_node(ctx).build(&mut subtrees, ctx);
let root = self.into_node().build(&mut subtrees);
let ctx = BuildCtx::get_mut();
while let Some((p, child)) = subtrees.pop() {
if ctx.providers.last() == Some(&p) && subtrees.last().map(|(p, _)| p) != Some(&p) {
ctx.providers.pop();
} else if ctx.providers.last() != Some(&p) && p.queryable(ctx.tree()) {
ctx.providers.push(p);
}
let c = child.into_node(ctx).build(&mut subtrees, ctx);
let c = child.into_node().build(&mut subtrees);
p.append(c, ctx.tree_mut());
}
root
}

pub(crate) fn directly_compose_children(
self, children: Vec<Widget<'w>>, ctx: &mut BuildCtx,
) -> Widget<'w> {
pub(crate) fn directly_compose_children(self, children: Vec<Widget<'w>>) -> Widget<'w> {
let mut list: SmallVec<[PureNode<'w>; 1]> = SmallVec::default();
let mut node = Some(self);
while let Some(n) = node.take() {
match n.into_node(ctx) {
match n.into_node() {
Node::Leaf(r) => list.push(r),
Node::Tree { parent, mut children } => {
list.push(parent);
Expand Down Expand Up @@ -283,23 +282,23 @@ impl<'w> Widget<'w> {
/// are certain that the entire logic is suitable for creating this widget
/// from an ID.
pub(crate) fn from_id(id: WidgetId) -> Widget<'static> {
let node = Node::Leaf(PureNode::LazyBuild(Box::new(move |_| id)));
let node = Node::Leaf(PureNode::LazyBuild(Box::new(move || id)));
Widget(InnerWidget::Node(node))
}

fn into_node(self, ctx: &mut BuildCtx) -> Node<'w> {
fn into_node(self) -> Node<'w> {
let mut w = self;
loop {
match w.0 {
InnerWidget::Node(node) => break node,
InnerWidget::Lazy(l) => w = l.consume(ctx),
InnerWidget::Lazy(l) => w = l.consume(),
}
}
}

fn wrap_root(self, f: impl FnOnce(PureNode<'w>) -> PureNode<'w> + 'w) -> Self {
let lazy = move |ctx: &mut BuildCtx| {
let node = self.into_node(ctx).wrap_root(f);
let node = self.into_node().wrap_root(f);
Widget(InnerWidget::Node(node))
};

Expand All @@ -308,11 +307,11 @@ impl<'w> Widget<'w> {
}

impl<'w> Node<'w> {
fn build(self, subtrees: &mut Vec<(WidgetId, Widget<'w>)>, ctx: &mut BuildCtx) -> WidgetId {
fn build(self, subtrees: &mut Vec<(WidgetId, Widget<'w>)>) -> WidgetId {
match self {
Node::Leaf(r) => r.alloc(ctx),
Node::Leaf(r) => r.alloc(),
Node::Tree { parent, children } => {
let p = parent.alloc(ctx);
let p = parent.alloc();
for c in children.into_iter().rev() {
subtrees.push((p, c))
}
Expand All @@ -332,10 +331,10 @@ impl<'w> Node<'w> {
}

impl<'w> PureNode<'w> {
fn alloc(self, ctx: &mut BuildCtx) -> WidgetId {
fn alloc(self) -> WidgetId {
match self {
PureNode::Render(r) => ctx.alloc(r),
PureNode::LazyBuild(l) => l(ctx),
PureNode::Render(r) => BuildCtx::get_mut().alloc(r),
PureNode::LazyBuild(l) => l(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/widget_children/multi_child_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<'w> IntoWidgetStrict<'w, FN> for MultiPair<'w> {
fn into_widget_strict(self) -> Widget<'w> {
let f = move |ctx: &mut BuildCtx| {
let MultiPair { parent, children } = self;
parent.directly_compose_children(children, ctx)
parent.directly_compose_children(children)
};

f.into_widget()
Expand Down
2 changes: 1 addition & 1 deletion core/src/widget_children/single_child_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'w, W: SingleIntoParent> IntoWidgetStrict<'w, RENDER> for WidgetOf<'w, W> {

parent
.into_parent()
.directly_compose_children(vec![child], ctx)
.directly_compose_children(vec![child])
};

f.into_widget()
Expand Down
9 changes: 3 additions & 6 deletions core/src/widget_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,20 @@ impl WidgetTree {
current_providers: <_>::default(),
});

let ctx = BuildCtx::get_mut();

let theme = AppCtx::app_theme().clone_writer();
let overlays = Queryable(ShowingOverlays::default());
let root = Provider::new(Box::new(overlays))
.with_child(fn_widget! {
theme.with_child(fn_widget!{
let ctx = unsafe { &*(ctx!() as *mut BuildCtx) };
let overlays = Provider::of::<ShowingOverlays>(ctx).unwrap();
overlays.rebuild(ctx!());
let overlays = Provider::of::<ShowingOverlays>(BuildCtx::get()).unwrap();
overlays.rebuild();
@Root {
@{ content.gen_widget() }
}
})
})
.into_widget()
.build(ctx);
.build();

self.root = root;
self.mark_dirty(root);
Expand Down

0 comments on commit 6b1155f

Please sign in to comment.