Skip to content

Commit

Permalink
Replace Stack trait with Change enum
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed May 10, 2024
1 parent a89c6ac commit ef87a8e
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 103 deletions.
2 changes: 1 addition & 1 deletion examples/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl View for App {
#[tokio::main]
async fn main() {
tokio::spawn(async move {
let mut vdom: VirtualDom<_, _, ()> = VirtualDom::new(App.into_node());
let mut vdom = VirtualDom::new(App.into_node());

vdom.run().await;
vdom.run().await;
Expand Down
3 changes: 0 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ mod scope;
pub use self::scope::Scope;
use self::scope::{Update, UpdateKind};

mod stack;
pub use self::stack::{Stack, VecStack};

mod use_context;
pub use self::use_context::use_context;

Expand Down
58 changes: 41 additions & 17 deletions src/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::{scope::AnyClone, Stack};
use crate::scope::AnyClone;
use std::{
any::TypeId,
collections::HashMap,
task::{Context, Poll},
};

pub enum Change {}

#[derive(Default)]
pub struct ViewContext {
pub(crate) contexts: HashMap<TypeId, Box<dyn AnyClone>>,
Expand All @@ -23,17 +25,21 @@ impl Clone for ViewContext {
}

pub trait Element: Send {
fn remove(&self, stack: &mut dyn Stack);
fn remove(&self) -> Option<Vec<Change>>;
}

impl Element for () {
fn remove(&self, _stack: &mut dyn Stack) {}
fn remove(&self) -> Option<Vec<Change>> {
None
}
}

impl<S: Element> Element for Option<S> {
fn remove(&self, stack: &mut dyn Stack) {
fn remove(&self) -> Option<Vec<Change>> {
if let Some(state) = self {
state.remove(stack)
state.remove()
} else {
None
}
}
}
Expand All @@ -50,7 +56,7 @@ pub trait Node: Send + 'static {
is_changed: bool,
) -> Poll<()>;

fn view(&self, cx: &mut ViewContext, stack: &mut dyn Stack, element: &mut Self::Element);
fn view(&self, cx: &mut ViewContext, element: &mut Self::Element) -> Option<Vec<Change>>;
}

impl Node for () {
Expand All @@ -67,7 +73,9 @@ impl Node for () {
Poll::Pending
}

fn view(&self, _cx: &mut ViewContext, _stack: &mut dyn Stack, _element: &mut Self::Element) {}
fn view(&self, cx: &mut ViewContext, element: &mut Self::Element) -> Option<Vec<Change>> {
None
}
}

impl<V: Node> Node for Option<V> {
Expand All @@ -92,27 +100,36 @@ impl<V: Node> Node for Option<V> {
Poll::Ready(())
}

fn view(&self, cx: &mut ViewContext, stack: &mut dyn Stack, element: &mut Self::Element) {
fn view(&self, cx: &mut ViewContext, element: &mut Self::Element) -> Option<Vec<Change>> {
if let Some(view) = self {
if let Some(state) = element {
view.view(cx, stack, state);
return view.view(cx, state);
} else {
let mut new_state = view.build();
view.view(cx, stack, &mut new_state);
let changes = view.view(cx, &mut new_state);
*element = Some(new_state);
return changes;
}
} else if let Some(state) = element {
state.remove(stack)
return state.remove();
}

None
}
}

pub struct TupleState<S1, S2>(S1, S2, bool);

impl<S1: Element, S2: Element> Element for TupleState<S1, S2> {
fn remove(&self, stack: &mut dyn Stack) {
self.0.remove(stack);
self.1.remove(stack);
fn remove(&self) -> Option<Vec<Change>> {
let a = self.0.remove();
let b = self.1.remove();
a.map(|mut a| {
if let Some(b) = b {
a.extend(b);
}
a
})
}
}

Expand Down Expand Up @@ -141,8 +158,15 @@ impl<V1: Node, V2: Node> Node for (V1, V2) {
}
}

fn view(&self, cx: &mut ViewContext, stack: &mut dyn Stack, element: &mut Self::Element) {
self.0.view(cx, stack, &mut element.0);
self.1.view(cx, stack, &mut element.1);
fn view(&self, cx: &mut ViewContext, element: &mut Self::Element) -> Option<Vec<Change>> {
let a = self.0.view(cx, &mut element.0);
let b = self.1.view(cx, &mut element.1);

a.map(|mut a| {
if let Some(b) = b {
a.extend(b);
}
a
})
}
}
60 changes: 0 additions & 60 deletions src/stack.rs

This file was deleted.

16 changes: 5 additions & 11 deletions src/vdom.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use crate::{node::ViewContext, Node, VecStack};
use crate::{node::ViewContext, Node};
use std::future;

pub struct VirtualDom<V, S, E> {
pub struct VirtualDom<V, S> {
view: V,
state: S,
elements: VecStack<E>,
cx: ViewContext,
}

impl<V, S, E> VirtualDom<V, S, E> {
impl<V, S> VirtualDom<V, S> {
pub fn new(view: V) -> Self
where
V: Node<Element = S>,
Expand All @@ -17,21 +16,16 @@ impl<V, S, E> VirtualDom<V, S, E> {
Self {
view,
state,
elements: VecStack {
items: Vec::new(),
idx: 0,
},

cx: ViewContext::default(),
}
}

pub async fn run(&mut self)
where
V: Node<Element = S>,
E: 'static,
{
future::poll_fn(|cx| self.view.poll_ready(cx, &mut self.state, false)).await;
self.view
.view(&mut self.cx, &mut self.elements, &mut self.state);
self.view.view(&mut self.cx, &mut self.state);
}
}
34 changes: 23 additions & 11 deletions src/view.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
node::{Element, ViewContext},
scope::ScopeInner,
Node, Scope, Stack, Update, UpdateKind,
Node, Scope, Update, UpdateKind,
};
use std::{
cell::UnsafeCell,
Expand Down Expand Up @@ -59,8 +59,12 @@ impl<T: Node> Node for WrapNode<T> {
self.0.poll_ready(cx, element, is_changed)
}

fn view(&self, cx: &mut ViewContext, stack: &mut dyn Stack, element: &mut Self::Element) {
self.0.view(cx, stack, element)
fn view(
&self,
cx: &mut ViewContext,
element: &mut Self::Element,
) -> Option<Vec<crate::node::Change>> {
self.0.view(cx, element)
}
}

Expand Down Expand Up @@ -95,9 +99,11 @@ where
V: Node,
S: Element,
{
fn remove(&self, stack: &mut dyn Stack) {
fn remove(&self) -> Option<Vec<crate::node::Change>> {
if let Some(ref state) = self.0 {
state.view_state.remove(stack);
state.view_state.remove()
} else {
None
}
}
}
Expand Down Expand Up @@ -241,7 +247,11 @@ where
}
}

fn view(&self, cx: &mut ViewContext, stack: &mut dyn Stack, element: &mut Self::Element) {
fn view(
&self,
cx: &mut ViewContext,
element: &mut Self::Element,
) -> Option<Vec<crate::node::Change>> {
if let Some(ref mut state) = element.0 {
if state.is_rx_ready {
let scope = unsafe { &mut *state.scope.inner.get() };
Expand All @@ -255,9 +265,9 @@ where
}

if state.is_rx_ready || state.is_body_ready {
state
.view
.view(&mut state.view_cx, stack, &mut state.view_state);
state.view.view(&mut state.view_cx, &mut state.view_state)
} else {
None
}
} else {
let mut view_cx = cx.clone();
Expand All @@ -278,7 +288,7 @@ where
view_cx.contexts = scope.inner.get_mut().contexts.take().unwrap();

let mut view_state = body.build();
body.view(&mut view_cx, stack, &mut view_state);
let changes = body.view(&mut view_cx, &mut view_state);

element.0 = Some(FnStateInner {
view: body,
Expand All @@ -290,7 +300,9 @@ where
rx_waker: None,
is_body_ready: false,
is_rx_ready: false,
})
});

changes
}
}
}

0 comments on commit ef87a8e

Please sign in to comment.