arena.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. use crate::{
  2. innerlude::DirtyScope, nodes::RenderReturn, nodes::VNode, virtual_dom::VirtualDom, DynamicNode,
  3. ScopeId,
  4. };
  5. /// An Element's unique identifier.
  6. ///
  7. /// `ElementId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
  8. /// unmounted, then the `ElementId` will be reused for a new component.
  9. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  10. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
  11. pub struct ElementId(pub usize);
  12. /// An Element that can be bubbled to's unique identifier.
  13. ///
  14. /// `BubbleId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
  15. /// unmounted, then the `BubbleId` will be reused for a new component.
  16. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  17. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
  18. pub struct VNodeId(pub usize);
  19. #[derive(Debug, Clone)]
  20. pub struct ElementRef {
  21. // the pathway of the real element inside the template
  22. pub(crate) path: ElementPath,
  23. // the scope that this element belongs to
  24. pub(crate) scope: ScopeId,
  25. // The actual element
  26. pub(crate) element: VNode,
  27. }
  28. #[derive(Clone, Copy, Debug)]
  29. pub struct ElementPath {
  30. pub(crate) path: &'static [u8],
  31. }
  32. impl VirtualDom {
  33. pub(crate) fn next_element(&mut self) -> ElementId {
  34. ElementId(self.elements.insert(None))
  35. }
  36. pub(crate) fn reclaim(&mut self, el: ElementId) {
  37. self.try_reclaim(el)
  38. .unwrap_or_else(|| panic!("cannot reclaim {:?}", el));
  39. }
  40. pub(crate) fn try_reclaim(&mut self, el: ElementId) -> Option<()> {
  41. if el.0 == 0 {
  42. panic!(
  43. "Cannot reclaim the root element - {:#?}",
  44. std::backtrace::Backtrace::force_capture()
  45. );
  46. }
  47. self.elements.try_remove(el.0).map(|_| ())
  48. }
  49. // Drop a scope and all its children
  50. //
  51. // Note: This will not remove any ids from the arena
  52. pub(crate) fn drop_scope(&mut self, id: ScopeId, recursive: bool) {
  53. // todo: Do we need this now that we don't have a bunch of unsafe code?
  54. // self.dirty_scopes.remove(&DirtyScope {
  55. // height: self.scopes[id.0].height(),
  56. // id,
  57. // });
  58. // if recursive {
  59. // if let Some(root) = self.scopes[id.0].try_root_node() {
  60. // if let RenderReturn::Ready(node) = root {
  61. // self.drop_scope_inner(node)
  62. // }
  63. // }
  64. // }
  65. // self.scopes.remove(id.0);
  66. }
  67. fn drop_scope_inner(&mut self, node: &VNode) {
  68. node.dynamic_nodes.iter().for_each(|node| match node {
  69. DynamicNode::Component(c) => {
  70. if let Some(f) = c.scope.get() {
  71. self.drop_scope(f, true);
  72. }
  73. }
  74. DynamicNode::Fragment(nodes) => {
  75. nodes.iter().for_each(|node| self.drop_scope_inner(node))
  76. }
  77. DynamicNode::Placeholder(_) => {}
  78. DynamicNode::Text(_) => {}
  79. });
  80. }
  81. }
  82. impl ElementPath {
  83. pub(crate) fn is_decendant(&self, small: &&[u8]) -> bool {
  84. small.len() <= self.path.len() && *small == &self.path[..small.len()]
  85. }
  86. }
  87. impl PartialEq<&[u8]> for ElementPath {
  88. fn eq(&self, other: &&[u8]) -> bool {
  89. self.path.eq(*other)
  90. }
  91. }