|
@@ -7,6 +7,51 @@ 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
|
|
|
+/// #[derive(Props)]
|
|
|
+/// struct ComponentProps {
|
|
|
+/// runtime: std::rc::Rc<Runtime>,
|
|
|
+/// }
|
|
|
+///
|
|
|
+/// impl PartialEq for ComponentProps {
|
|
|
+/// fn eq(&self, _other: &Self) -> bool {
|
|
|
+/// true
|
|
|
+/// }
|
|
|
+/// }
|
|
|
+///
|
|
|
+/// fn Component(cx: Scope<ComponentProps>) -> Element {
|
|
|
+/// cx.use_hook(|| override_runtime(cx.props.runtime.clone()));
|
|
|
+///
|
|
|
+/// render! { div {} }
|
|
|
+/// }
|
|
|
+/// ```
|
|
|
+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 +86,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 +109,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,14 +128,14 @@ 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())
|
|
|
})
|