nodes.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. use crate::{any_props::AnyProps, arena::ElementId};
  2. use std::{any::Any, cell::Cell, hash::Hasher};
  3. pub type TemplateId = &'static str;
  4. /// A reference to a template along with any context needed to hydrate it
  5. pub struct VNode<'a> {
  6. // The ID assigned for the root of this template
  7. pub node_id: Cell<ElementId>,
  8. // When rendered, this template will be linked to its parent
  9. pub parent: Option<(*mut VNode<'static>, usize)>,
  10. pub template: Template<'static>,
  11. pub root_ids: &'a [Cell<ElementId>],
  12. /// All the dynamic nodes for a template
  13. pub dynamic_nodes: &'a mut [DynamicNode<'a>],
  14. pub dynamic_attrs: &'a mut [AttributeLocation<'a>],
  15. }
  16. #[derive(Debug, Clone, Copy)]
  17. pub struct Template<'a> {
  18. pub id: &'a str,
  19. pub roots: &'a [TemplateNode<'a>],
  20. }
  21. impl<'a> std::hash::Hash for Template<'a> {
  22. fn hash<H: Hasher>(&self, state: &mut H) {
  23. self.id.hash(state);
  24. }
  25. }
  26. impl PartialEq for Template<'_> {
  27. fn eq(&self, other: &Self) -> bool {
  28. self.id == other.id
  29. }
  30. }
  31. impl Eq for Template<'_> {}
  32. impl PartialOrd for Template<'_> {
  33. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  34. self.id.partial_cmp(other.id)
  35. }
  36. }
  37. impl Ord for Template<'_> {
  38. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  39. self.id.cmp(other.id)
  40. }
  41. }
  42. /// A weird-ish variant of VNodes with way more limited types
  43. #[derive(Debug, Clone, Copy)]
  44. pub enum TemplateNode<'a> {
  45. Element {
  46. tag: &'a str,
  47. namespace: Option<&'a str>,
  48. attrs: &'a [TemplateAttribute<'a>],
  49. children: &'a [TemplateNode<'a>],
  50. },
  51. Text(&'a str),
  52. Dynamic(usize),
  53. DynamicText(usize),
  54. }
  55. pub struct DynamicNode<'a> {
  56. pub path: &'static [u8],
  57. pub kind: DynamicNodeKind<'a>,
  58. }
  59. pub enum DynamicNodeKind<'a> {
  60. // Anything declared in component form
  61. // IE in caps or with underscores
  62. Component {
  63. name: &'static str,
  64. props: *mut dyn AnyProps,
  65. },
  66. // Comes in with string interpolation or from format_args, include_str, etc
  67. Text {
  68. id: Cell<ElementId>,
  69. value: &'a str,
  70. },
  71. // Anything that's coming in as an iterator
  72. Fragment {
  73. children: &'a [VNode<'a>],
  74. },
  75. }
  76. #[derive(Debug)]
  77. pub enum TemplateAttribute<'a> {
  78. Static {
  79. name: &'static str,
  80. value: &'a str,
  81. namespace: Option<&'static str>,
  82. volatile: bool,
  83. },
  84. Dynamic {
  85. name: &'static str,
  86. index: usize,
  87. },
  88. }
  89. pub struct AttributeLocation<'a> {
  90. pub mounted_element: Cell<ElementId>,
  91. pub attrs: &'a mut [Attribute<'a>],
  92. pub listeners: &'a mut [Listener<'a>],
  93. pub path: &'static [u8],
  94. }
  95. #[derive(Debug)]
  96. pub struct Attribute<'a> {
  97. pub name: &'static str,
  98. pub value: &'a str,
  99. pub namespace: Option<&'static str>,
  100. }
  101. pub enum AttributeValue<'a> {
  102. Text(&'a str),
  103. Float(f32),
  104. Int(i32),
  105. Bool(bool),
  106. Any(&'a dyn AnyValue),
  107. }
  108. pub trait AnyValue {
  109. fn any_cmp(&self, other: &dyn Any) -> bool;
  110. }
  111. impl<T> AnyValue for T
  112. where
  113. T: PartialEq + Any,
  114. {
  115. fn any_cmp(&self, other: &dyn Any) -> bool {
  116. if self.type_id() != other.type_id() {
  117. return false;
  118. }
  119. self == unsafe { &*(other as *const _ as *const T) }
  120. }
  121. }
  122. pub struct Listener<'a> {
  123. pub name: &'static str,
  124. pub callback: &'a mut dyn FnMut(&dyn Any),
  125. }
  126. #[test]
  127. fn what_are_the_sizes() {
  128. dbg!(std::mem::size_of::<VNode>());
  129. dbg!(std::mem::size_of::<Template>());
  130. dbg!(std::mem::size_of::<TemplateNode>());
  131. }