Skip to content

Commit

Permalink
Impl ViewBuilder and Tree for Option and a tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed May 5, 2024
1 parent bff9374 commit 852d413
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 12 deletions.
10 changes: 10 additions & 0 deletions examples/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
use actuate::{use_state, virtual_dom, Scope, View, ViewBuilder};

struct A;

impl View for A {
fn body(&self, cx: &Scope) -> impl ViewBuilder {
dbg!("A!");
}
}

struct Counter {
initial: i32,
}
Expand All @@ -11,6 +19,8 @@ impl View for Counter {
set_count.set(count + 1);

dbg!(count);

(*count == 2).then_some(A)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<T> VirtualDom<T> {
}

self.tree
.rebuild(&mut self.cx, state.downcast_mut().unwrap())
.rebuild(&mut self.cx, state.downcast_mut().unwrap(), &mut self.roots)
} else {
let state = self.tree.build(&mut self.cx, &mut self.roots);
self.state = Some(Box::new(state));
Expand All @@ -118,7 +118,7 @@ impl<T> VirtualDom<T> {
}

impl<T> fmt::Debug for VirtualDom<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut t = f.debug_tuple("VirtualDom");

for key in &self.roots {
Expand Down
80 changes: 74 additions & 6 deletions src/tree.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,87 @@
use crate::{Context, Inner, Scope, View, ViewBuilder};
use slotmap::DefaultKey;
use std::{cell::UnsafeCell, mem};

use crate::{Context, Inner, Scope, View};

pub trait Tree {
type State: 'static;

fn build(&mut self, cx: &mut Context, children: &mut Vec<DefaultKey>) -> Self::State;

fn rebuild(&mut self, cx: &mut Context, state: &mut Self::State);
fn rebuild(
&mut self,
cx: &mut Context,
state: &mut Self::State,
children: &mut Vec<DefaultKey>,
);
}

impl Tree for () {
type State = ();

fn build(&mut self, cx: &mut Context, children: &mut Vec<DefaultKey>) -> Self::State {
let _ = children;
let _ = cx;
}

fn rebuild(&mut self, cx: &mut Context, state: &mut Self::State) {
fn rebuild(
&mut self,
cx: &mut Context,
state: &mut Self::State,
children: &mut Vec<DefaultKey>,
) {
let _ = children;
let _ = state;
let _ = cx;
}
}

impl<T: Tree> Tree for Option<T> {
type State = Option<T::State>;

fn build(&mut self, cx: &mut Context, children: &mut Vec<DefaultKey>) -> Self::State {
if let Some(tree) = self {
Some(tree.build(cx, children))
} else {
None
}
}

fn rebuild(
&mut self,
cx: &mut Context,
state: &mut Self::State,
children: &mut Vec<DefaultKey>,
) {
if let Some(tree) = self {
if let Some(state) = state {
tree.rebuild(cx, state, children);
} else {
*state = Some(tree.build(cx, children));
}
} else if let Some(state) = state {
todo!()
}
}
}

impl<T1: Tree, T2: Tree> Tree for (T1, T2) {
type State = (T1::State, T2::State);

fn build(&mut self, cx: &mut Context, children: &mut Vec<DefaultKey>) -> Self::State {
(self.0.build(cx, children), self.1.build(cx, children))
}

fn rebuild(
&mut self,
cx: &mut Context,
state: &mut Self::State,
children: &mut Vec<DefaultKey>,
) {
self.0.rebuild(cx, &mut state.0, children);
self.1.rebuild(cx, &mut state.1, children);
}
}

pub struct ViewTree<V, B, F> {
pub(crate) view: V,
pub(crate) body: Option<B>,
Expand Down Expand Up @@ -66,7 +124,12 @@ where
(key, scope, body_state)
}

fn rebuild(&mut self, cx: &mut Context, state: &mut Self::State) {
fn rebuild(
&mut self,
cx: &mut Context,
state: &mut Self::State,
children: &mut Vec<DefaultKey>,
) {
{
let scope = unsafe { &mut *state.1.inner.get() };
scope.idx = 0;
Expand All @@ -83,7 +146,12 @@ where
let body = (self.f)(view_ref, scope_ref);
self.body = Some(body);

self.body.as_mut().unwrap().rebuild(cx, &mut state.2);
let mut inner_children = Vec::new();
self.body
.as_mut()
.unwrap()
.rebuild(cx, &mut state.2, &mut inner_children);
cx.nodes.get_mut(state.0).unwrap().children = inner_children;

let node = cx.nodes.get_mut(state.0).unwrap();
node.view = &self.view as _;
Expand Down
20 changes: 16 additions & 4 deletions src/view_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ pub trait ViewBuilder {
fn into_tree(self) -> impl Tree;
}

impl ViewBuilder for () {
fn into_tree(self) -> impl Tree {}
}

impl<V: View> ViewBuilder for V {
fn into_tree(self) -> impl Tree {
ViewTree {
Expand All @@ -17,3 +13,19 @@ impl<V: View> ViewBuilder for V {
}
}
}

impl ViewBuilder for () {
fn into_tree(self) -> impl Tree {}
}

impl<VB: ViewBuilder> ViewBuilder for Option<VB> {
fn into_tree(self) -> impl Tree {
self.map(VB::into_tree)
}
}

impl<VB1: ViewBuilder, VB2: ViewBuilder> ViewBuilder for (VB1, VB2) {
fn into_tree(self) -> impl Tree {
(self.0.into_tree(), self.1.into_tree())
}
}

0 comments on commit 852d413

Please sign in to comment.