diff_stack.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. use crate::innerlude::*;
  2. use smallvec::{smallvec, SmallVec};
  3. /// The stack instructions we use to diff and create new nodes.
  4. #[derive(Debug)]
  5. pub enum DiffInstruction<'a> {
  6. DiffNode {
  7. old: &'a VNode<'a>,
  8. new: &'a VNode<'a>,
  9. },
  10. DiffChildren {
  11. old: &'a [VNode<'a>],
  12. new: &'a [VNode<'a>],
  13. },
  14. Create {
  15. node: &'a VNode<'a>,
  16. },
  17. /// pushes the node elements onto the stack for use in mount
  18. PrepareMoveNode {
  19. node: &'a VNode<'a>,
  20. },
  21. Mount {
  22. and: MountType<'a>,
  23. },
  24. PopScope,
  25. }
  26. #[derive(Debug, Clone, Copy)]
  27. pub enum MountType<'a> {
  28. Absorb,
  29. Append,
  30. Replace { old: &'a VNode<'a> },
  31. ReplaceByElementId { el: ElementId },
  32. InsertAfter { other_node: &'a VNode<'a> },
  33. InsertBefore { other_node: &'a VNode<'a> },
  34. }
  35. pub struct DiffStack<'bump> {
  36. instructions: Vec<DiffInstruction<'bump>>,
  37. nodes_created_stack: SmallVec<[usize; 10]>,
  38. pub scope_stack: SmallVec<[ScopeId; 5]>,
  39. }
  40. impl<'bump> DiffStack<'bump> {
  41. pub fn new() -> Self {
  42. Self {
  43. instructions: Vec::with_capacity(1000),
  44. nodes_created_stack: smallvec![],
  45. scope_stack: smallvec![],
  46. }
  47. }
  48. pub fn pop(&mut self) -> Option<DiffInstruction<'bump>> {
  49. self.instructions.pop()
  50. }
  51. pub fn pop_scope(&mut self) -> Option<ScopeId> {
  52. self.scope_stack.pop()
  53. }
  54. pub fn push(&mut self, instruction: DiffInstruction<'bump>) {
  55. self.instructions.push(instruction)
  56. }
  57. pub fn create_children(&mut self, children: &'bump [VNode<'bump>], and: MountType<'bump>) {
  58. self.nodes_created_stack.push(0);
  59. self.instructions.push(DiffInstruction::Mount { and });
  60. for child in children.into_iter().rev() {
  61. self.instructions
  62. .push(DiffInstruction::Create { node: child });
  63. }
  64. }
  65. pub fn push_nodes_created(&mut self, count: usize) {
  66. self.nodes_created_stack.push(count);
  67. }
  68. pub fn create_node(&mut self, node: &'bump VNode<'bump>, and: MountType<'bump>) {
  69. self.nodes_created_stack.push(0);
  70. self.instructions.push(DiffInstruction::Mount { and });
  71. self.instructions.push(DiffInstruction::Create { node });
  72. }
  73. pub fn add_child_count(&mut self, count: usize) {
  74. *self.nodes_created_stack.last_mut().unwrap() += count;
  75. }
  76. pub fn pop_nodes_created(&mut self) -> usize {
  77. self.nodes_created_stack.pop().unwrap()
  78. }
  79. pub fn current_scope(&self) -> Option<ScopeId> {
  80. self.scope_stack.last().map(|f| f.clone())
  81. }
  82. pub fn create_component(&mut self, idx: ScopeId, node: &'bump VNode<'bump>) {
  83. // Push the new scope onto the stack
  84. self.scope_stack.push(idx);
  85. self.instructions.push(DiffInstruction::PopScope);
  86. // Run the creation algorithm with this scope on the stack
  87. // ?? I think we treat components as framgnets??
  88. self.instructions.push(DiffInstruction::Create { node });
  89. }
  90. }