Skip to content

Commit

Permalink
debug: there seems to be 2 instance of stateful component
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanceras committed Apr 13, 2024
1 parent 83f5bb0 commit 0dc62d7
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 36 deletions.
40 changes: 36 additions & 4 deletions crates/core/src/dom/application/skip_diff.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::dom::DomNode;
use crate::vdom::TreePath;

/// specifies how attributes will be skipped
Expand Down Expand Up @@ -101,24 +102,55 @@ pub fn skip_if(shall: bool, children: impl IntoIterator<Item = SkipDiff>) -> Ski
}
}

/// target to apply the patch
#[derive(Debug)]
pub struct PatchTarget {
pub(crate) path: TreePath,
/// a provided target node, in the case for stateful component
pub(crate) target_node: Option<DomNode>,
}

impl PatchTarget {
pub(crate) fn traverse(&self, idx: usize) -> Self {
Self {
path: self.path.traverse(idx),
target_node: self.target_node.clone(),
}
}

pub(crate) fn backtrack(&self) -> Self {
Self {
path: self.path.backtrack(),
target_node: self.target_node.clone(),
}
}
}

/// combination of TreePath and SkipDiff
#[derive(Debug)]
pub struct SkipPath {
pub(crate) path: TreePath,
pub(crate) target: PatchTarget,
pub(crate) skip_diff: Option<SkipDiff>,
}

impl SkipPath {
pub(crate) fn new(path: TreePath, skip_diff: SkipDiff) -> Self {
Self {
path,
target: PatchTarget {
path,
target_node: None,
},
skip_diff: Some(skip_diff),
}
}

pub(crate) fn path(&self) -> TreePath {
self.target.path.clone()
}

pub(crate) fn traverse(&self, idx: usize) -> Self {
Self {
path: self.path.traverse(idx),
target: self.target.traverse(idx),
skip_diff: if let Some(skip_diff) = self.skip_diff.as_ref() {
skip_diff.traverse(idx).cloned()
} else {
Expand All @@ -129,7 +161,7 @@ impl SkipPath {

pub(crate) fn backtrack(&self) -> Self {
Self {
path: self.path.backtrack(),
target: self.target.backtrack(),
//TODO: here the skip_diff can not back track as we lose that info already
skip_diff: None,
}
Expand Down
15 changes: 13 additions & 2 deletions crates/core/src/dom/component/stateful_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub trait StatefulComponent {
/// remove the attribute with this name
fn remove_attribute(&mut self, _attr_name: AttributeName) {}

/// return the DomNode which contains the children DomNode
fn child_container(&self) -> Option<DomNode>;

/// append a child into this component
fn append_children(&mut self, _children: Vec<DomNode>) {}

Expand Down Expand Up @@ -54,7 +57,11 @@ pub struct StatefulModel<MSG> {

impl<MSG> fmt::Debug for StatefulModel<MSG> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "StatefuleMode")
f.debug_struct("StatefulModel")
.field("type_id", &self.type_id)
.field("attrs", &self.attrs)
.field("children", &self.children)
.finish()
}
}

Expand All @@ -81,6 +88,11 @@ impl<MSG> StatefulModel<MSG> {
.collect(),
}
}

/// return the stateful component child container
pub fn child_container(&self) -> Option<DomNode> {
self.comp.borrow().child_container()
}
}

impl<MSG> Clone for StatefulModel<MSG> {
Expand Down Expand Up @@ -151,7 +163,6 @@ where
let children: Vec<Node<MSG>> = children.into_iter().collect();
let mount_event = on_mount(move |me| {
let mut program = program.clone();
log::info!("stateful component is now mounted...");
program.mount(&me.target_node.as_node(), MountProcedure::append());
MSG::default()
});
Expand Down
5 changes: 5 additions & 0 deletions crates/core/src/dom/dom_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ impl DomNode {
match &self.inner {
DomInner::Element { children, .. } => Some(children.borrow()),
DomInner::Fragment { children, .. } => Some(children.borrow()),
DomInner::StatefulComponent(_comp) => todo!("children of stateful component.."),
_ => None,
}
}
Expand Down Expand Up @@ -737,6 +738,9 @@ where
parent_node: Rc<Option<DomNode>>,
comp: &StatefulModel<APP::MSG>,
) -> DomNode {
log::info!("Creating stateful component... without template..");
log::info!("comp is: {:#?}", comp);
log::info!("comp child container: {:?}", comp.child_container());
let comp_node = self.create_dom_node(
Rc::clone(&parent_node),
&crate::html::div(
Expand Down Expand Up @@ -838,6 +842,7 @@ where
}

pub(crate) fn find_node(target_node: &DomNode, path: &mut TreePath) -> Option<DomNode> {
log::info!("finding from target node: {:?}", target_node);
if path.is_empty() {
Some(target_node.clone())
} else {
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/dom/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ where

/// execute DOM changes in order to reflect the APP's view into the browser representation
pub fn update_dom(&mut self) -> Result<(), JsValue> {
log::warn!("-------->>>> Calling update dom..");
let t1 = now();
// a new view is created due to the app update
let view = self.app_context.view();
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/dom/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Window {
{
let (mut tx, rx) = mpsc::unbounded();
let resize_callback: Closure<dyn FnMut(web_sys::Event)> =
Closure::new(move |e: web_sys::Event| {
Closure::new(move |_e: web_sys::Event| {
let (w, h) = util::get_window_size();
let msg = cb(w, h);
tx.start_send(msg).expect("send");
Expand Down
38 changes: 27 additions & 11 deletions crates/core/src/vdom/diff.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! provides diffing algorithm which returns patches
use super::{diff_lis, Attribute, Element, Node, Patch, TreePath};
use super::{Tag, KEY, REPLACE, SKIP, SKIP_CRITERIA};
use crate::dom::skip_diff::PatchTarget;
use crate::dom::skip_diff::SkipAttrs;
use crate::dom::SkipPath;
use crate::vdom::AttributeValue;
Expand Down Expand Up @@ -55,7 +56,10 @@ pub fn diff<'a, MSG>(old_node: &'a Node<MSG>, new_node: &'a Node<MSG>) -> Vec<Pa
old_node,
new_node,
&SkipPath {
path: TreePath::root(),
target: PatchTarget {
path: TreePath::root(),
target_node: None,
},
skip_diff: None,
},
)
Expand Down Expand Up @@ -143,7 +147,7 @@ pub fn diff_recursive<'a, MSG>(
if should_replace(old_node, new_node) {
return vec![Patch::replace_node(
old_node.tag(),
path.path.clone(),
path.path(),
vec![new_node],
)];
}
Expand All @@ -160,7 +164,7 @@ pub fn diff_recursive<'a, MSG>(
| (Leaf::Comment(_), Leaf::Comment(_))
| (Leaf::DocType(_), Leaf::DocType(_)) => {
if old_leaf != new_leaf {
let patch = Patch::replace_node(None, path.path.clone(), vec![new_node]);
let patch = Patch::replace_node(None, path.path(), vec![new_node]);
patches.push(patch);
}
}
Expand All @@ -175,7 +179,10 @@ pub fn diff_recursive<'a, MSG>(
}
(Leaf::StatelessComponent(old_comp), Leaf::StatelessComponent(new_comp)) => {
let new_path = SkipPath {
path: path.path.clone(),
target: PatchTarget {
path: path.path(),
target_node: None,
},
skip_diff: old_comp.view.skip_diff(),
};

Expand All @@ -194,7 +201,16 @@ pub fn diff_recursive<'a, MSG>(
patches.extend(patch);
}
(Leaf::StatefulComponent(old_comp), Leaf::StatefulComponent(new_comp)) => {
let patch = diff_nodes(None, &old_comp.children, &new_comp.children, path);
let target_node = old_comp.child_container();
let new_path = SkipPath {
target: PatchTarget{
path: path.path(),
target_node,
},
skip_diff: None,
};
log::info!("new_path: {:#?}", new_path);
let patch = diff_nodes(None, &old_comp.children, &new_comp.children, &new_path);
patches.extend(patch);
}
(Leaf::TemplatedView(_old_view), _) => {
Expand All @@ -204,7 +220,7 @@ pub fn diff_recursive<'a, MSG>(
unreachable!("templated view should not be diffed..")
}
_ => {
let patch = Patch::replace_node(None, path.path.clone(), vec![new_node]);
let patch = Patch::replace_node(None, path.path(), vec![new_node]);
patches.push(patch);
}
}
Expand Down Expand Up @@ -278,7 +294,7 @@ fn diff_non_keyed_nodes<'a, MSG>(

// if there is no new children, then clear the children of this element
if old_child_count > 0 && new_child_count == 0 {
return vec![Patch::clear_children(old_element_tag, path.path.clone())];
return vec![Patch::clear_children(old_element_tag, path.path())];
}

let min_count = cmp::min(old_child_count, new_child_count);
Expand All @@ -298,7 +314,7 @@ fn diff_non_keyed_nodes<'a, MSG>(
if new_child_count > old_child_count {
patches.push(Patch::append_children(
old_element_tag,
path.path.clone(),
path.path(),
new_children.iter().skip(old_child_count).collect(),
));
}
Expand All @@ -309,7 +325,7 @@ fn diff_non_keyed_nodes<'a, MSG>(
.skip(new_child_count)
.enumerate()
.map(|(i, old_child)| {
Patch::remove_node(old_child.tag(), path.traverse(new_child_count + i).path)
Patch::remove_node(old_child.tag(), path.traverse(new_child_count + i).path())
})
.collect::<Vec<_>>();

Expand Down Expand Up @@ -412,14 +428,14 @@ fn create_attribute_patches<'a, MSG>(
if !add_attributes.is_empty() {
patches.push(Patch::add_attributes(
&old_element.tag,
path.path.clone(),
path.path(),
add_attributes,
));
}
if !remove_attributes.is_empty() {
patches.push(Patch::remove_attributes(
&old_element.tag,
path.path.clone(),
path.path(),
remove_attributes,
));
}
Expand Down
Loading

0 comments on commit 0dc62d7

Please sign in to comment.