2021-08-23 14:43:49 +00:00
|
|
|
use crate::innerlude::*;
|
|
|
|
use smallvec::{smallvec, SmallVec};
|
|
|
|
|
|
|
|
/// The stack instructions we use to diff and create new nodes.
|
|
|
|
#[derive(Debug)]
|
2021-09-10 00:58:48 +00:00
|
|
|
pub(crate) enum DiffInstruction<'a> {
|
|
|
|
Diff {
|
2021-08-23 14:43:49 +00:00
|
|
|
old: &'a VNode<'a>,
|
|
|
|
new: &'a VNode<'a>,
|
|
|
|
},
|
|
|
|
|
|
|
|
Create {
|
|
|
|
node: &'a VNode<'a>,
|
|
|
|
},
|
|
|
|
|
2021-08-23 19:35:26 +00:00
|
|
|
/// pushes the node elements onto the stack for use in mount
|
2021-09-10 00:58:48 +00:00
|
|
|
PrepareMove {
|
2021-08-23 19:35:26 +00:00
|
|
|
node: &'a VNode<'a>,
|
|
|
|
},
|
|
|
|
|
2021-08-23 14:43:49 +00:00
|
|
|
Mount {
|
|
|
|
and: MountType<'a>,
|
|
|
|
},
|
|
|
|
|
|
|
|
PopScope,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub enum MountType<'a> {
|
|
|
|
Absorb,
|
|
|
|
Append,
|
|
|
|
Replace { old: &'a VNode<'a> },
|
2021-09-10 00:58:48 +00:00
|
|
|
ReplaceByElementId { el: Option<ElementId> },
|
2021-08-23 16:11:45 +00:00
|
|
|
InsertAfter { other_node: &'a VNode<'a> },
|
|
|
|
InsertBefore { other_node: &'a VNode<'a> },
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
|
2021-08-27 13:40:04 +00:00
|
|
|
pub(crate) struct DiffStack<'bump> {
|
2021-08-23 16:11:45 +00:00
|
|
|
instructions: Vec<DiffInstruction<'bump>>,
|
|
|
|
nodes_created_stack: SmallVec<[usize; 10]>,
|
2021-08-23 14:43:49 +00:00
|
|
|
pub scope_stack: SmallVec<[ScopeId; 5]>,
|
2021-09-20 16:32:21 +00:00
|
|
|
pub element_id_stack: SmallVec<[ElementId; 5]>,
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'bump> DiffStack<'bump> {
|
2021-08-26 05:52:50 +00:00
|
|
|
pub fn new() -> Self {
|
2021-08-23 14:43:49 +00:00
|
|
|
Self {
|
|
|
|
instructions: Vec::with_capacity(1000),
|
|
|
|
nodes_created_stack: smallvec![],
|
2021-08-26 05:52:50 +00:00
|
|
|
scope_stack: smallvec![],
|
2021-09-20 16:32:21 +00:00
|
|
|
element_id_stack: smallvec![],
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 07:33:38 +00:00
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.instructions.is_empty()
|
|
|
|
}
|
|
|
|
|
2021-08-23 14:43:49 +00:00
|
|
|
pub fn pop(&mut self) -> Option<DiffInstruction<'bump>> {
|
|
|
|
self.instructions.pop()
|
|
|
|
}
|
|
|
|
|
2021-09-10 00:58:48 +00:00
|
|
|
pub fn pop_off_scope(&mut self) {
|
|
|
|
self.scope_stack.pop();
|
|
|
|
}
|
|
|
|
|
2021-08-23 14:43:49 +00:00
|
|
|
pub fn push(&mut self, instruction: DiffInstruction<'bump>) {
|
|
|
|
self.instructions.push(instruction)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_children(&mut self, children: &'bump [VNode<'bump>], and: MountType<'bump>) {
|
|
|
|
self.nodes_created_stack.push(0);
|
|
|
|
self.instructions.push(DiffInstruction::Mount { and });
|
|
|
|
|
|
|
|
for child in children.into_iter().rev() {
|
2021-08-23 16:11:45 +00:00
|
|
|
self.instructions
|
|
|
|
.push(DiffInstruction::Create { node: child });
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-23 19:35:26 +00:00
|
|
|
pub fn push_nodes_created(&mut self, count: usize) {
|
|
|
|
self.nodes_created_stack.push(count);
|
|
|
|
}
|
|
|
|
|
2021-09-20 16:32:21 +00:00
|
|
|
pub fn push_element_id(&mut self, id: ElementId) {
|
|
|
|
self.element_id_stack.push(id);
|
|
|
|
}
|
|
|
|
|
2021-08-23 14:43:49 +00:00
|
|
|
pub fn create_node(&mut self, node: &'bump VNode<'bump>, and: MountType<'bump>) {
|
|
|
|
self.nodes_created_stack.push(0);
|
|
|
|
self.instructions.push(DiffInstruction::Mount { and });
|
2021-08-23 16:11:45 +00:00
|
|
|
self.instructions.push(DiffInstruction::Create { node });
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_child_count(&mut self, count: usize) {
|
|
|
|
*self.nodes_created_stack.last_mut().unwrap() += count;
|
|
|
|
}
|
|
|
|
|
2021-08-23 16:11:45 +00:00
|
|
|
pub fn pop_nodes_created(&mut self) -> usize {
|
|
|
|
self.nodes_created_stack.pop().unwrap()
|
|
|
|
}
|
|
|
|
|
2021-08-23 14:43:49 +00:00
|
|
|
pub fn current_scope(&self) -> Option<ScopeId> {
|
|
|
|
self.scope_stack.last().map(|f| f.clone())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_component(&mut self, idx: ScopeId, node: &'bump VNode<'bump>) {
|
|
|
|
// Push the new scope onto the stack
|
|
|
|
self.scope_stack.push(idx);
|
|
|
|
|
|
|
|
self.instructions.push(DiffInstruction::PopScope);
|
|
|
|
|
|
|
|
// Run the creation algorithm with this scope on the stack
|
|
|
|
// ?? I think we treat components as framgnets??
|
2021-08-23 16:11:45 +00:00
|
|
|
self.instructions.push(DiffInstruction::Create { node });
|
2021-08-23 14:43:49 +00:00
|
|
|
}
|
|
|
|
}
|