scope_arena.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. use crate::{
  2. any_props::AnyProps,
  3. arena::ElementId,
  4. bump_frame::BumpFrame,
  5. factory::RenderReturn,
  6. nodes::VNode,
  7. scopes::{ScopeId, ScopeState},
  8. virtualdom::VirtualDom,
  9. };
  10. impl VirtualDom {
  11. pub fn new_scope(&mut self, props: *mut dyn AnyProps<'static>) -> ScopeId {
  12. let parent = self.acquire_current_scope_raw();
  13. let container = self.acquire_current_container();
  14. let entry = self.scopes.vacant_entry();
  15. let height = unsafe { parent.map(|f| (*f).height).unwrap_or(0) + 1 };
  16. let id = ScopeId(entry.key());
  17. entry.insert(ScopeState {
  18. parent,
  19. container,
  20. id,
  21. height,
  22. props,
  23. tasks: self.pending_futures.clone(),
  24. node_arena_1: BumpFrame::new(50),
  25. node_arena_2: BumpFrame::new(50),
  26. render_cnt: Default::default(),
  27. hook_arena: Default::default(),
  28. hook_vals: Default::default(),
  29. hook_idx: Default::default(),
  30. shared_contexts: Default::default(),
  31. });
  32. id
  33. }
  34. pub fn acquire_current_container(&self) -> ElementId {
  35. self.element_stack
  36. .last()
  37. .copied()
  38. .expect("Always have a container")
  39. }
  40. fn acquire_current_scope_raw(&mut self) -> Option<*mut ScopeState> {
  41. self.scope_stack
  42. .last()
  43. .copied()
  44. .and_then(|id| self.scopes.get_mut(id.0).map(|f| f as *mut ScopeState))
  45. }
  46. pub fn run_scope(&mut self, id: ScopeId) -> &mut RenderReturn {
  47. let scope = &mut self.scopes[id.0];
  48. scope.hook_idx.set(0);
  49. let res = {
  50. let props = unsafe { &mut *scope.props };
  51. let props: &mut dyn AnyProps = unsafe { std::mem::transmute(props) };
  52. let res: RenderReturn = props.render(scope);
  53. let res: RenderReturn<'static> = unsafe { std::mem::transmute(res) };
  54. res
  55. };
  56. let frame = match scope.render_cnt % 2 {
  57. 0 => &mut scope.node_arena_1,
  58. 1 => &mut scope.node_arena_2,
  59. _ => unreachable!(),
  60. };
  61. // set the head of the bump frame
  62. let alloced = frame.bump.alloc(res);
  63. frame.node.set(alloced);
  64. // rebind the lifetime now that its stored internally
  65. unsafe { std::mem::transmute(alloced) }
  66. }
  67. }