expose public methods for manipulating the global runtime

This commit is contained in:
Evan Almloff committed 2023-09-08 10:05:58 -05:00
1 parent de87ba6548
commit 9496853fbc
3 files changed
+63 -9

No files matched your search

+52 -4
View File
@@ -7,6 +7,39 @@ thread_local! {
static RUNTIMES: RefCell<Vec<Rc<Runtime>>> = RefCell::new(vec![]);
}
/// Run some code within a runtime
pub fn in_runtime<R>(runtime: Rc<Runtime>, f: impl FnOnce() -> R) -> R {
let _guard = RuntimeGuard::new(runtime);
f()
}
/// Override the current runtime. This must be used to override the current runtime when importing components from a dynamic library that has it's own runtime.
///
/// ```rust
/// use dioxus::prelude::*;
///
/// fn main() {
/// let virtual_dom = VirtualDom::new(app);
/// }
///
/// fn app(cx: Scope) -> Element {
/// render!{ Component { runtime: Runtime::current().unwrap() } }
/// }
///
/// // In a dynamic library
/// #[inline_props]
/// fn Component(cx: Scope, runtime: Rc<Runtime>) -> Element {
/// cx.use_hook(|| override_runtime(runtime.clone()));
/// }
/// ```
pub fn override_runtime(runtime: Rc<Runtime>) {
RUNTIMES.with(|stack| {
let mut stack = stack.borrow_mut();
stack.pop();
stack.push(runtime);
});
}
/// Pushes a new scope onto the stack
pub(crate) fn push_runtime(runtime: Rc<Runtime>) {
RUNTIMES.with(|stack| stack.borrow_mut().push(runtime));
@@ -41,7 +74,8 @@ where
.flatten()
}
pub(crate) struct Runtime {
/// A global runtime that is shared across all scopes that provides the async runtime and context API
pub struct Runtime {
pub(crate) scope_contexts: RefCell<Vec<Option<ScopeContext>>>,
pub(crate) scheduler: Rc<Scheduler>,
@@ -63,6 +97,11 @@ impl Runtime {
})
}
/// Get the current runtime
pub fn current() -> Option<Rc<Self>> {
RUNTIMES.with(|stack| stack.borrow().last().cloned())
}
/// 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();
@@ -77,16 +116,25 @@ impl Runtime {
}
/// Get the current scope id
pub fn current_scope_id(&self) -> Option<ScopeId> {
pub(crate) fn current_scope_id(&self) -> Option<ScopeId> {
self.scope_stack.borrow().last().copied()
}
/// 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<Ref<'_, ScopeContext>> {
pub(crate) 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())
match contexts.get(id.0) {
Some(context) => context.as_ref(),
_ => {
tracing::error!(
"Attempted to get context for scope that doesn't exist (id: {})",
id.0
);
None
}
}
})
.ok()
}