create a way to hoist ownership to a different scope
This commit is contained in:
1 parent
49001c59d3
commit
dce418140a
4 files changed
+53
-6
No files matched your search
@@ -84,11 +84,11 @@ pub use crate::innerlude::{
|
|||||||
/// This includes types like [`Scope`], [`Element`], and [`Component`].
|
/// This includes types like [`Scope`], [`Element`], and [`Component`].
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
consume_context, current_scope_id, fc_to_builder, has_context, provide_context,
|
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
|
||||||
provide_root_context, schedule_update_any, suspend, throw, AnyValue, Component, Element,
|
provide_context, provide_context_to_scope, provide_root_context, schedule_update_any,
|
||||||
Event, EventHandler, Fragment, IntoAttributeValue, LazyNodes, Properties, Scope, ScopeId,
|
suspend, throw, AnyValue, Component, Element, Event, EventHandler, Fragment,
|
||||||
ScopeState, Scoped, TaskId, Template, TemplateAttribute, TemplateNode, Throw, VNode,
|
IntoAttributeValue, LazyNodes, Properties, Scope, ScopeId, ScopeState, Scoped, TaskId,
|
||||||
VirtualDom,
|
Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,15 @@ pub fn consume_context<T: 'static + Clone>() -> Option<T> {
|
|||||||
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume context from the current scope
|
||||||
|
pub fn consume_context_from_scope<T: 'static + Clone>(scope_id: ScopeId) -> Option<T> {
|
||||||
|
with_runtime(|rt| {
|
||||||
|
rt.get_context(scope_id)
|
||||||
|
.and_then(|cx| cx.consume_context::<T>())
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if the current scope has a context
|
/// Check if the current scope has a context
|
||||||
pub fn has_context<T: 'static + Clone>() -> Option<T> {
|
pub fn has_context<T: 'static + Clone>() -> Option<T> {
|
||||||
with_current_scope(|cx| cx.has_context::<T>()).flatten()
|
with_current_scope(|cx| cx.has_context::<T>()).flatten()
|
||||||
@@ -278,6 +287,11 @@ pub fn provide_context<T: 'static + Clone>(value: T) -> Option<T> {
|
|||||||
with_current_scope(|cx| cx.provide_context(value))
|
with_current_scope(|cx| cx.provide_context(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provide context to the the given scope
|
||||||
|
pub fn provide_context_to_scope<T: 'static + Clone>(scope_id: ScopeId, value: T) -> Option<T> {
|
||||||
|
with_runtime(|rt| rt.get_context(scope_id).map(|cx| cx.provide_context(value))).flatten()
|
||||||
|
}
|
||||||
|
|
||||||
/// Provide a context to the root scope
|
/// Provide a context to the root scope
|
||||||
pub fn provide_root_context<T: 'static + Clone>(value: T) -> Option<T> {
|
pub fn provide_root_context<T: 'static + Clone>(value: T) -> Option<T> {
|
||||||
with_current_scope(|cx| cx.provide_root_context(value))
|
with_current_scope(|cx| cx.provide_root_context(value))
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ impl<T: 'static> Signal<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn origin_scope(&self) -> ScopeId {
|
||||||
|
self.inner.origin_scope()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read(&self) -> Ref<T> {
|
pub fn read(&self) -> Ref<T> {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
if let Some(current_scope_id) = current_scope_id() {
|
if let Some(current_scope_id) = current_scope_id() {
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ use std::cell::{Ref, RefMut};
|
|||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use dioxus_core::prelude::{consume_context, provide_root_context};
|
use dioxus_core::prelude::{
|
||||||
|
consume_context, consume_context_from_scope, current_scope_id, provide_context_to_scope,
|
||||||
|
provide_root_context,
|
||||||
|
};
|
||||||
|
use dioxus_core::ScopeId;
|
||||||
|
|
||||||
use dioxus_copy::{CopyHandle, Owner, Store};
|
use dioxus_copy::{CopyHandle, Owner, Store};
|
||||||
|
|
||||||
@@ -26,8 +30,19 @@ fn current_owner() -> Rc<Owner> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn owner_in_scope(scope: ScopeId) -> Rc<Owner> {
|
||||||
|
match consume_context_from_scope(scope) {
|
||||||
|
Some(rt) => rt,
|
||||||
|
None => {
|
||||||
|
let owner = Rc::new(current_store().owner());
|
||||||
|
provide_context_to_scope(scope, owner).expect("in a virtual dom")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CopyValue<T: 'static> {
|
pub struct CopyValue<T: 'static> {
|
||||||
pub value: CopyHandle<T>,
|
pub value: CopyHandle<T>,
|
||||||
|
origin_scope: ScopeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> CopyValue<T> {
|
impl<T: 'static> CopyValue<T> {
|
||||||
@@ -36,9 +51,23 @@ impl<T: 'static> CopyValue<T> {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
value: owner.insert(value),
|
value: owner.insert(value),
|
||||||
|
origin_scope: current_scope_id().expect("in a virtual dom"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_in_scope(value: T, scope: ScopeId) -> Self {
|
||||||
|
let owner = owner_in_scope(scope);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
value: owner.insert(value),
|
||||||
|
origin_scope: scope,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn origin_scope(&self) -> ScopeId {
|
||||||
|
self.origin_scope
|
||||||
|
}
|
||||||
|
|
||||||
pub fn try_read(&self) -> Option<Ref<'_, T>> {
|
pub fn try_read(&self) -> Option<Ref<'_, T>> {
|
||||||
self.value.try_read()
|
self.value.try_read()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user