Skip to content

Commit

Permalink
allow Rc inside tree for sharing; tag 0.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed May 28, 2022
1 parent 9dafbd5 commit 9b845a6
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "respo"
version = "0.0.5"
version = "0.0.6"
edition = "2021"
description = "a tiny virtual DOM library migrated from ClojureScript"
license = "Apache-2.0"
Expand Down
93 changes: 48 additions & 45 deletions src/app/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,51 +58,54 @@ pub fn comp_task(
Ok(())
};

Ok(RespoNode::Component(
"tasks".to_owned(),
vec![RespoEffect::new(
vec![cast_into_json(task)],
move |args, effect_type, _el| -> Result<(), String> {
let t: Task = cast_from_json(&args[0]);
util::log!("effect {:?} task: {:?}", effect_type, t);
// TODO
Ok(())
},
)],
Box::new(
div()
.class_list(&[ui_row_middle(), style_task_container()])
.add_children([
div()
.class(style_done_button())
.add_style(if task.done {
RespoStyle::default().background_color(CssColor::Blue).to_owned()
} else {
RespoStyle::default()
})
.on_click(on_toggle)
.to_owned(),
div().inner_text(task.content.to_owned()).to_owned(),
span()
.class_list(&[ui_center(), style_remove_button()])
.inner_text("✕")
.on_click(on_remove)
.to_owned(),
div()
.add_style(RespoStyle::default().margin4(0.0, 0.0, 0.0, 20.0).to_owned())
.to_owned(),
input()
.class(ui_input())
.insert_attr("value", state.draft)
.insert_attr("placeholder", "something to update...")
.on_input(on_input)
.to_owned(),
space(Some(8), None),
button().class(ui_button()).inner_text("Update").on_click(on_update).to_owned(),
])
.to_owned(),
),
))
Ok(
RespoNode::Component(
"tasks".to_owned(),
vec![RespoEffect::new(
vec![cast_into_json(task)],
move |args, effect_type, _el| -> Result<(), String> {
let t: Task = cast_from_json(&args[0]);
util::log!("effect {:?} task: {:?}", effect_type, t);
// TODO
Ok(())
},
)],
Box::new(
div()
.class_list(&[ui_row_middle(), style_task_container()])
.add_children([
div()
.class(style_done_button())
.add_style(if task.done {
RespoStyle::default().background_color(CssColor::Blue).to_owned()
} else {
RespoStyle::default()
})
.on_click(on_toggle)
.to_owned(),
div().inner_text(task.content.to_owned()).to_owned(),
span()
.class_list(&[ui_center(), style_remove_button()])
.inner_text("✕")
.on_click(on_remove)
.to_owned(),
div()
.add_style(RespoStyle::default().margin4(0.0, 0.0, 0.0, 20.0).to_owned())
.to_owned(),
input()
.class(ui_input())
.insert_attr("value", state.draft)
.insert_attr("placeholder", "something to update...")
.on_input(on_input)
.to_owned(),
space(Some(8), None),
button().class(ui_button()).inner_text("Update").on_click(on_update).to_owned(),
])
.to_owned(),
),
)
.share_with_ref(),
)
}

static_styles!(
Expand Down
8 changes: 7 additions & 1 deletion src/respo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ where
{
// util::log!("looking for {:?}\n {}", coord, &tree);
if coord.is_empty() {
Ok(tree.to_owned())
match tree {
RespoNode::Referenced(cell) => Ok((**cell).clone()),
_ => Ok(tree.clone()),
}
} else {
let branch = coord.first().ok_or("to get first branch of coord")?;
match (tree, branch) {
Expand All @@ -144,6 +147,7 @@ where
(RespoNode::Element { .. }, RespoCoord::Comp(..)) => {
Err(format!("expected component at {:?}, found target being an element", coord))
}
(RespoNode::Referenced(cell), _) => load_coord_target_tree(cell, coord),
}
}
}
Expand All @@ -160,6 +164,7 @@ where
Some(v) => Ok((*v).to_owned()),
None => Err(format!("no handler for event:{} on {} {:?}", &event_name, tag_name, event,)),
},
RespoNode::Referenced(cell) => request_for_target_handler(&cell, event_name, coord),
}
}

Expand Down Expand Up @@ -214,5 +219,6 @@ where

Ok(element.dyn_ref::<Node>().expect("converting to Node").clone())
}
RespoNode::Referenced(cell) => build_dom_tree(cell, coord, handle_event),
}
}
32 changes: 32 additions & 0 deletions src/respo/diff.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::rc::Rc;

use crate::respo::primes::*;

Expand Down Expand Up @@ -109,6 +110,20 @@ where
diff_children(children, old_children, coord, dom_path, changes)?;
}
}
(RespoNode::Referenced(new_cell), RespoNode::Referenced(old_cell)) => {
// pointer compare https://stackoverflow.com/a/60241585/883571
if Rc::ptr_eq(new_cell, old_cell) {
return Ok(());
} else {
diff_tree(new_cell, old_cell, coord, dom_path, changes)?;
}
}
(RespoNode::Referenced(new_cell), b) => {
diff_tree(new_cell, b, coord, dom_path, changes)?;
}
(a, RespoNode::Referenced(old_cell)) => {
diff_tree(a, old_cell, coord, dom_path, changes)?;
}
}

Ok(())
Expand Down Expand Up @@ -378,6 +393,10 @@ where
}
Ok(())
}
RespoNode::Referenced(cell) => {
collect_effects_outside_in_as(cell, coord, dom_path, effect_type, changes)?;
Ok(())
}
}
}

Expand Down Expand Up @@ -413,6 +432,11 @@ where
}
Ok(())
}

RespoNode::Referenced(cell) => {
collect_effects_inside_out_as(cell, coord, dom_path, effect_type, changes)?;
Ok(())
}
}
}

Expand Down Expand Up @@ -448,6 +472,10 @@ where
}
Ok(())
}
RespoNode::Referenced(cell) => {
nested_effects_outside_in_as(cell, coord, dom_path, effect_type, operations)?;
Ok(())
}
}
}

Expand Down Expand Up @@ -483,5 +511,9 @@ where
}
Ok(())
}
RespoNode::Referenced(cell) => {
nested_effects_inside_out_as(cell, coord, dom_path, effect_type, operations)?;
Ok(())
}
}
}
33 changes: 33 additions & 0 deletions src/respo/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ where
/// they are used in diffing, so it's better to be distinct, although not required to be.
children: Vec<(RespoIndexKey, RespoNode<T>)>,
},
Referenced(Rc<RespoNode<T>>),
}

impl<T> From<RespoNode<T>> for Cirru
Expand All @@ -48,6 +49,7 @@ where
.collect(),
),
]),
RespoNode::Referenced(cell) => (*cell).to_owned().into(),
}
}
}
Expand Down Expand Up @@ -106,6 +108,9 @@ where
style.0.push((k.to_owned(), v.to_owned()));
}
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -122,6 +127,9 @@ where
RespoNode::Element { ref mut attrs, .. } => {
attrs.insert(property.into(), value.into());
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -140,6 +148,9 @@ where
attrs.insert(k.into(), v.into());
}
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -154,6 +165,9 @@ where
RespoNode::Element { ref mut event, .. } => {
event.insert("click".into(), RespoEventHandler::new(handler));
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -168,6 +182,9 @@ where
RespoNode::Element { ref mut event, .. } => {
event.insert("input".into(), RespoEventHandler::new(handler));
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -185,6 +202,9 @@ where
event.insert(k.into(), v.to_owned());
}
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -202,6 +222,9 @@ where
children.push((idx.into(), v));
}
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -218,6 +241,9 @@ where
children.push((idx, v));
}
}
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
self
}
Expand All @@ -232,6 +258,9 @@ where
self
}
RespoNode::Element { .. } => unreachable!("effects are on components"),
RespoNode::Referenced(_) => {
unreachable!("should not be called on a referenced node");
}
}
}
/// attach a class name for adding styles
Expand Down Expand Up @@ -269,6 +298,10 @@ where
self.insert_attr("innerHTML", content.into());
self
}
/// wrap with a `Rc<RefCell<T>>` to enable memory reuse and skipping in diff
pub fn share_with_ref(&self) -> Self {
Self::Referenced(Rc::new(self.clone()))
}
}

pub(crate) type StrDict = HashMap<String, String>;
Expand Down

0 comments on commit 9b845a6

Please sign in to comment.