|
| 1 | +use crate::proxy::memo::{FnMemo, Memo, MemoState}; |
| 2 | +use crate::proxy::node::{NodeId, ReactiveNode, ReactiveNodeType}; |
| 3 | +use crate::proxy::reference::Reference; |
| 4 | +use slotmap::{SecondaryMap, SlotMap}; |
| 5 | +use std::cell::RefCell; |
| 6 | +use std::collections::HashSet; |
| 7 | +use std::rc::Rc; |
| 8 | + |
| 9 | +thread_local! { |
| 10 | + pub(crate) static RUNTIME: Runtime = Runtime::new(); |
| 11 | +} |
| 12 | + |
| 13 | +pub struct Runtime { |
| 14 | + nodes: RefCell<SlotMap<NodeId, ReactiveNode>>, |
| 15 | + node_subscribers: RefCell<SecondaryMap<NodeId, RefCell<HashSet<NodeId>>>>, |
| 16 | +} |
| 17 | + |
| 18 | +impl Runtime { |
| 19 | + pub(crate) fn new() -> Self { |
| 20 | + Self { |
| 21 | + nodes: RefCell::new(SlotMap::default()), |
| 22 | + node_subscribers: RefCell::new(SecondaryMap::default()), |
| 23 | + } |
| 24 | + } |
| 25 | +} |
| 26 | + |
| 27 | +pub(crate) fn with_runtime<T, F>(f: F) -> T |
| 28 | +where |
| 29 | + F: FnOnce(&Runtime) -> T, |
| 30 | +{ |
| 31 | + RUNTIME.with(|runtime| f(runtime)) |
| 32 | +} |
| 33 | + |
| 34 | +pub(crate) struct RuntimeContext; |
| 35 | + |
| 36 | +impl RuntimeContext { |
| 37 | + pub(crate) fn create_ref<T>(self, value: T) -> Reference<T> { |
| 38 | + let id = with_runtime(|runtime| { |
| 39 | + runtime.nodes.borrow_mut().insert(ReactiveNode { |
| 40 | + value: Some(value), |
| 41 | + node_type: ReactiveNodeType::Ref, |
| 42 | + }) |
| 43 | + }); |
| 44 | + Reference::new(id) |
| 45 | + } |
| 46 | + |
| 47 | + pub(crate) fn create_memo<T>(self, f: FnMemo<T>) -> Memo<T> { |
| 48 | + let state = Rc::new(MemoState::new(f)); |
| 49 | + let id = with_runtime(|runtime| { |
| 50 | + runtime.nodes.borrow_mut().insert(ReactiveNode { |
| 51 | + value: Some(Rc::new(RefCell::new(None::<T>))), |
| 52 | + node_type: ReactiveNodeType::Memo { f: state }, |
| 53 | + }) |
| 54 | + }); |
| 55 | + Memo::new(id) |
| 56 | + } |
| 57 | +} |
0 commit comments