fix scope context

This commit is contained in:
Evan Almloff committed 2023-08-04 14:12:59 -07:00
1 parent 04cdb14e5b
commit cb4c46154d
7 files changed
+83 -45

No files matched your search

+38 -26
View File
@@ -1,20 +1,14 @@
use std::cell::RefCell;
use std::cell::{Ref, RefCell};
use crate::{
innerlude::{DirtyScope, Scheduler, SchedulerMsg},
scope_context::ScopeContext,
scopes::{ScopeId, ScopeState},
};
use rustc_hash::FxHashSet;
use slab::Slab;
use std::{collections::BTreeSet, rc::Rc};
use crate::{innerlude::Scheduler, scope_context::ScopeContext, scopes::ScopeId};
use std::rc::Rc;
thread_local! {
static RUNTIMES: RefCell<Vec<Runtime>> = RefCell::new(vec![]);
static RUNTIMES: RefCell<Vec<Rc<Runtime>>> = RefCell::new(vec![]);
}
/// Pushes a new scope onto the stack
pub(crate) fn push_runtime(runtime: Runtime) {
pub(crate) fn push_runtime(runtime: Rc<Runtime>) {
RUNTIMES.with(|stack| stack.borrow_mut().push(runtime));
}
@@ -30,7 +24,7 @@ where
{
RUNTIMES.with(|stack| {
let stack = stack.borrow();
stack.last().map(f)
stack.last().map(|r| f(&**r))
})
}
@@ -42,28 +36,50 @@ where
with_runtime(|runtime| {
runtime
.current_scope_id()
.and_then(|scope| runtime.get_context(scope).map(f))
.and_then(|scope| runtime.get_context(scope).map(|sc| f(&*sc)))
})
.flatten()
}
pub struct Runtime {
pub(crate) scope_contexts: Slab<ScopeContext>,
pub(crate) scope_contexts: RefCell<Vec<Option<ScopeContext>>>,
pub(crate) scheduler: Rc<Scheduler>,
// While diffing we need some sort of way of breaking off a stream of suspended mutations.
pub(crate) scope_stack: RefCell<Vec<ScopeId>>,
}
impl Drop for Runtime {
fn drop(&mut self) {
// todo: do this better
pop_runtime();
}
}
impl Runtime {
pub(crate) fn new(scheduler: Rc<Scheduler>) -> Rc<Self> {
Rc::new(Self {
let runtime = Rc::new(Self {
scheduler,
scope_contexts: Default::default(),
scope_stack: Default::default(),
})
});
push_runtime(runtime.clone());
runtime
}
/// Create a scope context. This slab is synchronized with the scope slab.
pub(crate) fn create_context_at(&self, id: ScopeId, context: ScopeContext) {
let mut contexts = self.scope_contexts.borrow_mut();
if contexts.len() <= id.0 {
contexts.resize_with(id.0 + 1, Default::default);
}
contexts[id.0] = Some(context);
}
pub(crate) fn remove_context(&self, id: ScopeId) {
self.scope_contexts.borrow_mut()[id.0] = None;
}
/// Get the current scope id
@@ -71,17 +87,13 @@ impl Runtime {
self.scope_stack.borrow().last().copied()
}
/// Get the state for any scope given its ID
/// Get the context for any scope given its ID
///
/// This is useful for inserting or removing contexts from a scope, or rendering out its root node
pub fn get_context(&self, id: ScopeId) -> Option<&ScopeContext> {
self.scope_contexts.get(id.0).map(|f| &*f)
}
/// Get the single scope at the top of the Runtime tree that will always be around
///
/// This scope has a ScopeId of 0 and is the root of the tree
pub fn base_context(&self) -> &ScopeContext {
self.get_context(ScopeId(0)).unwrap()
pub fn get_context(&self, id: ScopeId) -> Option<Ref<'_, ScopeContext>> {
Ref::filter_map(self.scope_contexts.borrow(), |contexts| {
contexts.get(id.0).and_then(|f| f.as_ref())
})
.ok()
}
}