wip: move things into a "shared" object
This commit is contained in:
1 parent
22f894e6b9
commit
f644d7c441
19 files changed
+542
-698
No files matched your search
+111
-37
@@ -1,55 +1,99 @@
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::{cell::UnsafeCell, rc::Rc};
|
||||
|
||||
use crate::heuristics::*;
|
||||
use crate::innerlude::*;
|
||||
use futures_util::stream::FuturesUnordered;
|
||||
use slotmap::SlotMap;
|
||||
|
||||
slotmap::new_key_type! {
|
||||
// A dedicated key type for the all the scopes
|
||||
pub struct ScopeId;
|
||||
}
|
||||
|
||||
slotmap::new_key_type! {
|
||||
// A dedicated key type for every real element that the virtualdom creates.
|
||||
//
|
||||
// This is a slotmap key because we expect the "mirror" realdom to also maintain a slotmap mapping
|
||||
// of virtual element to real element.
|
||||
pub struct ElementId;
|
||||
}
|
||||
|
||||
impl ElementId {
|
||||
pub fn as_u64(self) -> u64 {
|
||||
self.0.as_ffi()
|
||||
}
|
||||
}
|
||||
|
||||
type Shared<T> = Rc<RefCell<T>>;
|
||||
|
||||
/// These are resources shared among all the components and the virtualdom itself
|
||||
#[derive(Clone)]
|
||||
pub struct SharedArena {
|
||||
pub components: Rc<UnsafeCell<ScopeMap>>,
|
||||
}
|
||||
pub type ScopeMap = SlotMap<ScopeId, Scope>;
|
||||
pub struct SharedResources {
|
||||
pub components: Rc<UnsafeCell<SlotMap<ScopeId, Scope>>>,
|
||||
|
||||
enum MutStatus {
|
||||
Immut,
|
||||
Mut,
|
||||
pub event_queue: Shared<Vec<HeightMarker>>,
|
||||
|
||||
pub events: Shared<Vec<EventTrigger>>,
|
||||
|
||||
pub(crate) heuristics: Shared<HeuristicsEngine>,
|
||||
|
||||
pub(crate) tasks: Shared<FuturesUnordered<FiberTask>>,
|
||||
|
||||
/// We use a SlotSet to keep track of the keys that are currently being used.
|
||||
/// However, we don't store any specific data since the "mirror"
|
||||
pub raw_elements: Shared<SlotMap<ElementId, ()>>,
|
||||
|
||||
pub task_setter: Rc<dyn Fn(ScopeId)>,
|
||||
}
|
||||
|
||||
impl SharedArena {
|
||||
pub fn new(arena: ScopeMap) -> Self {
|
||||
let components = Rc::new(UnsafeCell::new(arena));
|
||||
SharedArena { components }
|
||||
impl SharedResources {
|
||||
pub fn new() -> Self {
|
||||
// preallocate 1000 elements and 20 scopes to avoid dynamic allocation
|
||||
let components = Rc::new(UnsafeCell::new(
|
||||
SlotMap::<ScopeId, Scope>::with_capacity_and_key(20),
|
||||
));
|
||||
let raw_elements = SlotMap::<ElementId, ()>::with_capacity_and_key(1000);
|
||||
|
||||
let event_queue = Rc::new(RefCell::new(Vec::new()));
|
||||
let tasks = Vec::new();
|
||||
let heuristics = HeuristicsEngine::new();
|
||||
|
||||
let queue = event_queue.clone();
|
||||
let _components = components.clone();
|
||||
let task_setter = Rc::new(move |idx| {
|
||||
let comps = unsafe { &*_components.get() };
|
||||
if let Some(scope) = comps.get(idx) {
|
||||
queue.borrow_mut().push(HeightMarker {
|
||||
height: scope.height,
|
||||
idx,
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
event_queue,
|
||||
components,
|
||||
tasks: Rc::new(RefCell::new(FuturesUnordered::new())),
|
||||
events: Rc::new(RefCell::new(tasks)),
|
||||
heuristics: Rc::new(RefCell::new(heuristics)),
|
||||
raw_elements: Rc::new(RefCell::new(raw_elements)),
|
||||
task_setter,
|
||||
}
|
||||
}
|
||||
|
||||
/// THIS METHOD IS CURRENTLY UNSAFE
|
||||
/// THERE ARE NO CHECKS TO VERIFY THAT WE ARE ALLOWED TO DO THIS
|
||||
pub fn get(&self, idx: ScopeId) -> Option<&Scope> {
|
||||
let inner = unsafe { &*self.components.get() };
|
||||
/// this is unsafe because the caller needs to track which other scopes it's already using
|
||||
pub unsafe fn get_scope(&self, idx: ScopeId) -> Option<&Scope> {
|
||||
let inner = &*self.components.get();
|
||||
inner.get(idx)
|
||||
}
|
||||
|
||||
/// THIS METHOD IS CURRENTLY UNSAFE
|
||||
/// THERE ARE NO CHECKS TO VERIFY THAT WE ARE ALLOWED TO DO THIS
|
||||
pub fn get_mut(&self, idx: ScopeId) -> Option<&mut Scope> {
|
||||
let inner = unsafe { &mut *self.components.get() };
|
||||
/// this is unsafe because the caller needs to track which other scopes it's already using
|
||||
pub unsafe fn get_sope_mut(&self, idx: ScopeId) -> Option<&mut Scope> {
|
||||
let inner = &mut *self.components.get();
|
||||
inner.get_mut(idx)
|
||||
}
|
||||
|
||||
fn inner(&self) -> &ScopeMap {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn inner_mut(&mut self) -> &mut ScopeMap {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// THIS METHOD IS CURRENTLY UNSAFE
|
||||
/// THERE ARE NO CHECKS TO VERIFY THAT WE ARE ALLOWED TO DO THIS
|
||||
pub fn with<T>(&self, f: impl FnOnce(&mut ScopeMap) -> T) -> Result<T> {
|
||||
let inner = unsafe { &mut *self.components.get() };
|
||||
Ok(f(inner))
|
||||
// todo!()
|
||||
}
|
||||
|
||||
pub fn with_scope<'b, O: 'static>(
|
||||
&'b self,
|
||||
_id: ScopeId,
|
||||
@@ -75,7 +119,37 @@ impl SharedArena {
|
||||
.ok_or_else(|| Error::FatalInternal("Scope not found"))
|
||||
}
|
||||
|
||||
unsafe fn inner_unchecked<'s>() -> &'s mut ScopeMap {
|
||||
todo!()
|
||||
pub fn reserve_node(&self) -> ElementId {
|
||||
self.raw_elements.borrow_mut().insert(())
|
||||
}
|
||||
|
||||
/// return the id, freeing the space of the original node
|
||||
pub fn collect_garbage(&self, id: ElementId) {}
|
||||
|
||||
pub fn borrow_queue(&self) -> RefMut<Vec<HeightMarker>> {
|
||||
self.event_queue.borrow_mut()
|
||||
}
|
||||
|
||||
pub fn insert_scope_with_key(&self, f: impl FnOnce(ScopeId) -> Scope) -> ScopeId {
|
||||
let g = unsafe { &mut *self.components.get() };
|
||||
g.insert_with_key(f)
|
||||
}
|
||||
|
||||
pub fn schedule_update(&self) -> Rc<dyn Fn(ScopeId)> {
|
||||
self.task_setter.clone()
|
||||
}
|
||||
|
||||
pub fn submit_task(&self, task: FiberTask) -> TaskHandle {
|
||||
self.tasks.borrow_mut().push(task);
|
||||
TaskHandle {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TaskHandle {}
|
||||
|
||||
impl TaskHandle {
|
||||
pub fn toggle(&self) {}
|
||||
pub fn start(&self) {}
|
||||
pub fn stop(&self) {}
|
||||
pub fn restart(&self) {}
|
||||
}
|
||||
Reference in new issue
Block a user