Fix problems with child scopes causing RefCell errors by wrapping in an Rc and immediately cloning when we try to access a ScopeState, dropping the Ref (and allowing us to access the contents of one scope immutably while adding another scope, etc.)

This commit is contained in:
Greg Johnston 2022-08-11 07:16:26 -04:00
parent fbe665494e
commit c2af386565
2 changed files with 11 additions and 7 deletions

View file

@ -5,11 +5,12 @@ use crate::{
use slotmap::SlotMap;
use std::cell::RefCell;
use std::fmt::Debug;
use std::rc::Rc;
#[derive(Default, Debug)]
pub(crate) struct Runtime {
pub(crate) stack: RefCell<Vec<Subscriber>>,
pub(crate) scopes: RefCell<SlotMap<ScopeId, ScopeState>>,
pub(crate) scopes: RefCell<SlotMap<ScopeId, Rc<ScopeState>>>,
}
impl Runtime {
@ -18,8 +19,9 @@ impl Runtime {
}
pub fn scope<T>(&self, id: ScopeId, f: impl FnOnce(&ScopeState) -> T) -> T {
if let Some(scope) = self.scopes.borrow().get(id) {
(f)(scope)
let scope = { self.scopes.borrow().get(id).cloned() };
if let Some(scope) = scope {
(f)(&scope)
} else {
panic!("couldn't locate {id:?}");
}
@ -104,7 +106,11 @@ impl Runtime {
f: impl FnOnce(Scope),
parent: Option<Scope>,
) -> ScopeDisposer {
let id = { self.scopes.borrow_mut().insert(ScopeState::new(parent)) };
let id = {
self.scopes
.borrow_mut()
.insert(Rc::new(ScopeState::new(parent)))
};
let scope = Scope { runtime: self, id };
f(scope);

View file

@ -24,9 +24,7 @@ pub struct Scope {
impl Scope {
pub fn child_scope(self, f: impl FnOnce(Scope)) -> ScopeDisposer {
//self.runtime.create_scope(f, Some(self))
f(self);
ScopeDisposer(Box::new(move || {}))
self.runtime.create_scope(f, Some(self))
}
pub fn untrack<T>(&self, f: impl FnOnce() -> T) -> T {