Files
dioxus/packages/core/src/scopearena.rs
T

106 lines
3.0 KiB
Rust

use std::cell::{Cell, RefCell};
use bumpalo::{boxed::Box as BumpBox, Bump};
use futures_channel::mpsc::UnboundedSender;
use crate::innerlude::*;
pub type FcSlot = *const ();
// pub heuristics: FxHashMap<FcSlot, Heuristic>,
pub struct Heuristic {
hook_arena_size: usize,
node_arena_size: usize,
}
// a slab-like arena with stable references even when new scopes are allocated
// uses a bump arena as a backing
//
// has an internal heuristics engine to pre-allocate arenas to the right size
pub(crate) struct ScopeArena {
bump: Bump,
scopes: Vec<*mut ScopeState>,
free_scopes: Vec<ScopeId>,
pub(crate) sender: UnboundedSender<SchedulerMsg>,
}
impl ScopeArena {
pub fn new(sender: UnboundedSender<SchedulerMsg>) -> Self {
Self {
bump: Bump::new(),
scopes: Vec::new(),
free_scopes: Vec::new(),
sender,
}
}
pub fn get_scope(&self, id: &ScopeId) -> Option<&ScopeState> {
unsafe { Some(&*self.scopes[id.0]) }
}
pub fn new_with_key(
&mut self,
fc_ptr: *const (),
vcomp: &VComponent,
parent_scope: Option<*mut ScopeState>,
height: u32,
subtree: u32,
sender: UnboundedSender<SchedulerMsg>,
) -> ScopeId {
if let Some(id) = self.free_scopes.pop() {
// have already called drop on it - the slot is still chillin tho
let scope = unsafe { &mut *self.scopes[id.0 as usize] };
todo!("override the scope contents");
id
} else {
let id = ScopeId(self.scopes.len());
let vcomp = unsafe { std::mem::transmute(vcomp as *const VComponent) };
let new_scope = ScopeState {
sender,
parent_scope,
our_arena_idx: id,
height,
subtree: Cell::new(subtree),
is_subtree_root: Cell::new(false),
frames: ActiveFrame::new(),
vcomp,
hooks: Default::default(),
shared_contexts: Default::default(),
items: RefCell::new(SelfReferentialItems {
listeners: Default::default(),
borrowed_props: Default::default(),
suspended_nodes: Default::default(),
tasks: Default::default(),
pending_effects: Default::default(),
cached_nodes: Default::default(),
generation: Default::default(),
}),
};
let stable = self.bump.alloc(new_scope);
self.scopes.push(stable);
id
}
}
pub fn try_remove(&self, id: &ScopeId) -> Option<ScopeState> {
todo!()
}
pub fn reserve_node(&self, node: &VNode) -> ElementId {
todo!()
// self.node_reservations.insert(id);
}
pub fn collect_garbage(&self, id: ElementId) {
todo!()
}
// scopes never get dropepd
}