wip: remove the scoped trait
This commit is contained in:
1 parent
36542b482f
commit
cca7c5fc3a
4 files changed
+85
-159
No files matched your search
+14
-14
@@ -32,7 +32,7 @@ mod traits {
|
|||||||
// Atoms, selectors, and their family variants are readable
|
// Atoms, selectors, and their family variants are readable
|
||||||
pub trait Readable<T: AtomValue>: Sized + Copy {
|
pub trait Readable<T: AtomValue>: Sized + Copy {
|
||||||
fn use_read<'a, P: 'static>(self, cx: Context<'a, P>) -> &'a T {
|
fn use_read<'a, P: 'static>(self, cx: Context<'a, P>) -> &'a T {
|
||||||
hooks::use_read(&cx, self)
|
hooks::use_read(cx, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This returns a future of the value
|
// This returns a future of the value
|
||||||
@@ -95,9 +95,9 @@ mod atoms {
|
|||||||
const EXAMPLE_ATOM: Atom<i32> = |_| 10;
|
const EXAMPLE_ATOM: Atom<i32> = |_| 10;
|
||||||
|
|
||||||
// ensure that atoms are both read and write
|
// ensure that atoms are both read and write
|
||||||
let _ = use_read(&cx, &EXAMPLE_ATOM);
|
let _ = use_read(cx, &EXAMPLE_ATOM);
|
||||||
let _ = use_read_write(&cx, &EXAMPLE_ATOM);
|
let _ = use_read_write(cx, &EXAMPLE_ATOM);
|
||||||
let _ = use_write(&cx, &EXAMPLE_ATOM);
|
let _ = use_write(cx, &EXAMPLE_ATOM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ mod atomfamily {
|
|||||||
|
|
||||||
fn test(cx: Context<()>) {
|
fn test(cx: Context<()>) {
|
||||||
let title = Titles.select(&10).use_read(cx);
|
let title = Titles.select(&10).use_read(cx);
|
||||||
let t2 = use_read(&cx, &Titles.select(&10));
|
let t2 = use_read(cx, &Titles.select(&10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +368,7 @@ mod root {
|
|||||||
|
|
||||||
mod hooks {
|
mod hooks {
|
||||||
use super::*;
|
use super::*;
|
||||||
use dioxus_core::{hooks::use_ref, prelude::Context, virtual_dom::Scoped};
|
use dioxus_core::{hooks::use_ref, prelude::Context};
|
||||||
|
|
||||||
pub fn use_init_recoil_root<P>(cx: Context<P>, cfg: impl Fn(())) {
|
pub fn use_init_recoil_root<P>(cx: Context<P>, cfg: impl Fn(())) {
|
||||||
cx.use_create_context(move || RefCell::new(RecoilRoot::new()))
|
cx.use_create_context(move || RefCell::new(RecoilRoot::new()))
|
||||||
@@ -381,12 +381,12 @@ mod hooks {
|
|||||||
///
|
///
|
||||||
/// You can use this method to create controllers that perform much more complex actions than set/get
|
/// You can use this method to create controllers that perform much more complex actions than set/get
|
||||||
/// However, be aware that "getting" values through this hook will not subscribe the component to any updates.
|
/// However, be aware that "getting" values through this hook will not subscribe the component to any updates.
|
||||||
pub fn use_recoil_api<'a>(cx: &impl Scoped<'a>) -> &'a Rc<RecoilContext> {
|
pub fn use_recoil_api<'a, P>(cx: Context<'a, P>) -> &'a Rc<RecoilContext> {
|
||||||
cx.use_context::<RecoilContext>()
|
cx.use_context::<RecoilContext>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_write<'a, T: AtomValue>(
|
pub fn use_write<'a, P, T: AtomValue>(
|
||||||
cx: &impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
// todo: this shouldn't need to be static
|
// todo: this shouldn't need to be static
|
||||||
writable: impl Writable<T>,
|
writable: impl Writable<T>,
|
||||||
) -> &'a Rc<dyn Fn(T)> {
|
) -> &'a Rc<dyn Fn(T)> {
|
||||||
@@ -412,8 +412,8 @@ mod hooks {
|
|||||||
/// Read the atom and get the Rc directly to the Atom's slot
|
/// Read the atom and get the Rc directly to the Atom's slot
|
||||||
/// This is useful if you need the memoized Atom value. However, Rc<T> is not as easy to
|
/// This is useful if you need the memoized Atom value. However, Rc<T> is not as easy to
|
||||||
/// work with as
|
/// work with as
|
||||||
pub fn use_read_raw<'a, T: AtomValue>(
|
pub fn use_read_raw<'a, P, T: AtomValue>(
|
||||||
cx: &impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
readable: impl Readable<T>,
|
readable: impl Readable<T>,
|
||||||
) -> &'a Rc<T> {
|
) -> &'a Rc<T> {
|
||||||
struct ReadHook<T> {
|
struct ReadHook<T> {
|
||||||
@@ -449,7 +449,7 @@ mod hooks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
pub fn use_read<'a, T: AtomValue>(cx: &impl Scoped<'a>, readable: impl Readable<T>) -> &'a T {
|
pub fn use_read<'a, P, T: AtomValue>(cx: Context<'a, P>, readable: impl Readable<T>) -> &'a T {
|
||||||
use_read_raw(cx, readable).as_ref()
|
use_read_raw(cx, readable).as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,8 +468,8 @@ mod hooks {
|
|||||||
/// // equivalent to:
|
/// // equivalent to:
|
||||||
/// let (title, set_title) = (use_read(cx, &Title), use_write(cx, &Title));
|
/// let (title, set_title) = (use_read(cx, &Title), use_write(cx, &Title));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn use_read_write<'a, T: AtomValue + 'static>(
|
pub fn use_read_write<'a, P, T: AtomValue + 'static>(
|
||||||
cx: &impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
writable: impl Writable<T>,
|
writable: impl Writable<T>,
|
||||||
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
|
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
|
||||||
(use_read(cx, writable), use_write(cx, writable))
|
(use_read(cx, writable), use_write(cx, writable))
|
||||||
|
|||||||
+11
-11
@@ -36,8 +36,8 @@ use std::{
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn use_state_classic<'a, 'c, T: 'static, F: FnOnce() -> T>(
|
pub fn use_state_classic<'a, 'c, T: 'static, F: FnOnce() -> T, P>(
|
||||||
cx: impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
initial_state_fn: F,
|
initial_state_fn: F,
|
||||||
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
|
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
|
||||||
struct UseState<T: 'static> {
|
struct UseState<T: 'static> {
|
||||||
@@ -158,8 +158,8 @@ impl<'a, T: 'static + Display> std::fmt::Display for UseState<T> {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn use_state<'a, 'c, T: 'static, F: FnOnce() -> T>(
|
pub fn use_state<'a, 'c, T: 'static, F: FnOnce() -> T, P>(
|
||||||
cx: impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
initial_state_fn: F,
|
initial_state_fn: F,
|
||||||
) -> &'a UseState<T> {
|
) -> &'a UseState<T> {
|
||||||
cx.use_hook(
|
cx.use_hook(
|
||||||
@@ -230,8 +230,8 @@ pub fn use_state<'a, 'c, T: 'static, F: FnOnce() -> T>(
|
|||||||
/// To change it, use modify.
|
/// To change it, use modify.
|
||||||
/// Modifications to this value do not cause updates to the component
|
/// Modifications to this value do not cause updates to the component
|
||||||
/// Attach to inner context reference, so context can be consumed
|
/// Attach to inner context reference, so context can be consumed
|
||||||
pub fn use_ref<'a, T: 'static>(
|
pub fn use_ref<'a, T: 'static, P>(
|
||||||
cx: impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
initial_state_fn: impl FnOnce() -> T + 'static,
|
initial_state_fn: impl FnOnce() -> T + 'static,
|
||||||
) -> &'a RefCell<T> {
|
) -> &'a RefCell<T> {
|
||||||
cx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
|
cx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
|
||||||
@@ -249,8 +249,8 @@ struct UseReducer<T: 'static, R: 'static> {
|
|||||||
///
|
///
|
||||||
/// This is behaves almost exactly the same way as React's "use_state".
|
/// This is behaves almost exactly the same way as React's "use_state".
|
||||||
///
|
///
|
||||||
pub fn use_reducer<'a, 'c, State: 'static, Action: 'static>(
|
pub fn use_reducer<'a, 'c, State: 'static, Action: 'static, P>(
|
||||||
cx: impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
initial_state_fn: impl FnOnce() -> State,
|
initial_state_fn: impl FnOnce() -> State,
|
||||||
_reducer: impl Fn(&mut State, Action),
|
_reducer: impl Fn(&mut State, Action),
|
||||||
) -> (&'a State, &'a Box<dyn Fn(Action)>) {
|
) -> (&'a State, &'a Box<dyn Fn(Action)>) {
|
||||||
@@ -291,8 +291,8 @@ pub fn use_reducer<'a, 'c, State: 'static, Action: 'static>(
|
|||||||
/// Use model makes it easy to use "models" as state for components. To modify the model, call "modify" and a clone of the
|
/// Use model makes it easy to use "models" as state for components. To modify the model, call "modify" and a clone of the
|
||||||
/// current model will be made, with a RefMut lock on it. Dioxus will never run your components multithreaded, so you can
|
/// current model will be made, with a RefMut lock on it. Dioxus will never run your components multithreaded, so you can
|
||||||
/// be relatively sure that this won't fail in practice
|
/// be relatively sure that this won't fail in practice
|
||||||
pub fn use_model<'a, T: ToOwned<Owned = T> + 'static>(
|
pub fn use_model<'a, T: ToOwned<Owned = T> + 'static, P>(
|
||||||
cx: impl Scoped<'a>,
|
cx: Context<'a, P>,
|
||||||
f: impl FnOnce() -> T,
|
f: impl FnOnce() -> T,
|
||||||
) -> &'a UseModel<T> {
|
) -> &'a UseModel<T> {
|
||||||
cx.use_hook(
|
cx.use_hook(
|
||||||
@@ -381,7 +381,7 @@ mod tests {
|
|||||||
// };
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_is_initialized<P>(cx: Context<P>) -> bool {
|
pub fn use_is_initialized<'a, P>(cx: Context<'a, P>) -> bool {
|
||||||
let val = use_ref(cx, || false);
|
let val = use_ref(cx, || false);
|
||||||
match *val.borrow() {
|
match *val.borrow() {
|
||||||
true => true,
|
true => true,
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ pub mod prelude {
|
|||||||
use crate::nodes;
|
use crate::nodes;
|
||||||
pub use crate::styles::{AsAttr, StyleBuilder};
|
pub use crate::styles::{AsAttr, StyleBuilder};
|
||||||
pub use crate::virtual_dom::Context;
|
pub use crate::virtual_dom::Context;
|
||||||
pub use crate::virtual_dom::Scoped;
|
|
||||||
pub use nodes::*;
|
pub use nodes::*;
|
||||||
|
|
||||||
pub use crate::nodebuilder::LazyNodes;
|
pub use crate::nodebuilder::LazyNodes;
|
||||||
|
|||||||
@@ -586,13 +586,58 @@ impl Scope {
|
|||||||
pub(crate) fn root<'a>(&'a self) -> &'a VNode<'a> {
|
pub(crate) fn root<'a>(&'a self) -> &'a VNode<'a> {
|
||||||
&self.frames.cur_frame().head_node
|
&self.frames.cur_frame().head_node
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Components in Dioxus use the "Context" object to interact with their lifecycle.
|
||||||
|
/// This lets components schedule updates, integrate hooks, and expose their context via the context api.
|
||||||
|
///
|
||||||
|
/// Properties passed down from the parent component are also directly accessible via the exposed "props" field.
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// #[derive(Properties)]
|
||||||
|
/// struct Props {
|
||||||
|
/// name: String
|
||||||
|
///
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn example(cx: Context<Props>) -> VNode {
|
||||||
|
/// html! {
|
||||||
|
/// <div> "Hello, {cx.name}" </div>
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
// todo: force lifetime of source into T as a valid lifetime too
|
||||||
|
// it's definitely possible, just needs some more messing around
|
||||||
|
pub struct Context<'src, T> {
|
||||||
|
pub props: &'src T,
|
||||||
|
pub scope: &'src Scope,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'src, T> Copy for Context<'src, T> {}
|
||||||
|
impl<'src, T> Clone for Context<'src, T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
props: self.props,
|
||||||
|
scope: self.scope,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Deref for Context<'a, T> {
|
||||||
|
type Target = &'a T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.props
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'src, P> Context<'src, P> {
|
||||||
/// Access the children elements passed into the component
|
/// Access the children elements passed into the component
|
||||||
pub fn children(&self) -> &[VNode] {
|
pub fn children(&self) -> &'src [VNode<'src>] {
|
||||||
// We're re-casting the nodes back out
|
// We're re-casting the nodes back out
|
||||||
// They don't really have a static lifetime
|
// They don't really have a static lifetime
|
||||||
unsafe {
|
unsafe {
|
||||||
let scope = self;
|
let scope = self.scope;
|
||||||
let nodes = scope.child_nodes;
|
let nodes = scope.child_nodes;
|
||||||
nodes
|
nodes
|
||||||
}
|
}
|
||||||
@@ -600,7 +645,7 @@ impl Scope {
|
|||||||
|
|
||||||
/// Create a subscription that schedules a future render for the reference component
|
/// Create a subscription that schedules a future render for the reference component
|
||||||
pub fn schedule_update(&self) -> Rc<dyn Fn() + 'static> {
|
pub fn schedule_update(&self) -> Rc<dyn Fn() + 'static> {
|
||||||
self.event_channel.clone()
|
self.scope.event_channel.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schedule_effect(&self) -> Rc<dyn Fn() + 'static> {
|
pub fn schedule_effect(&self) -> Rc<dyn Fn() + 'static> {
|
||||||
@@ -626,11 +671,11 @@ impl Scope {
|
|||||||
/// cx.render(lazy_tree)
|
/// cx.render(lazy_tree)
|
||||||
/// }
|
/// }
|
||||||
///```
|
///```
|
||||||
pub fn render<'src, F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
|
pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
|
||||||
&'src self,
|
self,
|
||||||
lazy_nodes: LazyNodes<'src, F>,
|
lazy_nodes: LazyNodes<'src, F>,
|
||||||
) -> VNode<'src> {
|
) -> VNode<'src> {
|
||||||
let scope_ref = self;
|
let scope_ref = self.scope;
|
||||||
let listener_id = &scope_ref.listener_idx;
|
let listener_id = &scope_ref.listener_idx;
|
||||||
lazy_nodes.into_vnode(NodeFactory {
|
lazy_nodes.into_vnode(NodeFactory {
|
||||||
scope_ref,
|
scope_ref,
|
||||||
@@ -654,8 +699,8 @@ impl Scope {
|
|||||||
/// )
|
/// )
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn use_hook<'src, InternalHookState: 'static, Output: 'src>(
|
pub fn use_hook<InternalHookState: 'static, Output: 'src>(
|
||||||
&'src self,
|
self,
|
||||||
|
|
||||||
// The closure that builds the hook state
|
// The closure that builds the hook state
|
||||||
initializer: impl FnOnce() -> InternalHookState,
|
initializer: impl FnOnce() -> InternalHookState,
|
||||||
@@ -667,7 +712,7 @@ impl Scope {
|
|||||||
// TODO: add this to the "clean up" group for when the component is dropped
|
// TODO: add this to the "clean up" group for when the component is dropped
|
||||||
_cleanup: impl FnOnce(InternalHookState),
|
_cleanup: impl FnOnce(InternalHookState),
|
||||||
) -> Output {
|
) -> Output {
|
||||||
let scope = self;
|
let scope = self.scope;
|
||||||
|
|
||||||
let idx = scope.hookidx.get();
|
let idx = scope.hookidx.get();
|
||||||
|
|
||||||
@@ -715,8 +760,8 @@ Any function prefixed with "use" should not be called conditionally.
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
fn use_create_context<T: 'static>(&self, init: impl Fn() -> T) {
|
pub fn use_create_context<T: 'static>(&self, init: impl Fn() -> T) {
|
||||||
let scope = self;
|
let mut scope = self.scope;
|
||||||
let mut cxs = scope.shared_contexts.borrow_mut();
|
let mut cxs = scope.shared_contexts.borrow_mut();
|
||||||
let ty = TypeId::of::<T>();
|
let ty = TypeId::of::<T>();
|
||||||
|
|
||||||
@@ -745,12 +790,12 @@ Any function prefixed with "use" should not be called conditionally.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// There are hooks going on here!
|
/// There are hooks going on here!
|
||||||
pub fn use_context<'src, T: 'static>(&'src self) -> &'src Rc<T> {
|
pub fn use_context<T: 'static>(self) -> &'src Rc<T> {
|
||||||
self.try_use_context().unwrap()
|
self.try_use_context().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uses a context, storing the cached value around
|
/// Uses a context, storing the cached value around
|
||||||
pub fn try_use_context<'src, T: 'static>(&'src self) -> Result<&'src Rc<T>> {
|
pub fn try_use_context<T: 'static>(self) -> Result<&'src Rc<T>> {
|
||||||
struct UseContextHook<C> {
|
struct UseContextHook<C> {
|
||||||
par: Option<Rc<C>>,
|
par: Option<Rc<C>>,
|
||||||
we: Option<Weak<C>>,
|
we: Option<Weak<C>>,
|
||||||
@@ -762,7 +807,7 @@ Any function prefixed with "use" should not be called conditionally.
|
|||||||
we: None as Option<Weak<T>>,
|
we: None as Option<Weak<T>>,
|
||||||
},
|
},
|
||||||
move |hook| {
|
move |hook| {
|
||||||
let mut scope = Some(self);
|
let mut scope = Some(self.scope);
|
||||||
|
|
||||||
if let Some(we) = &hook.we {
|
if let Some(we) = &hook.we {
|
||||||
if let Some(re) = we.upgrade() {
|
if let Some(re) = we.upgrade() {
|
||||||
@@ -807,11 +852,7 @@ Any function prefixed with "use" should not be called conditionally.
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suspend<
|
pub fn suspend<Output: 'src, Fut: FnOnce(SuspendedContext, Output) -> VNode<'src> + 'src>(
|
||||||
'src,
|
|
||||||
Output: 'src,
|
|
||||||
Fut: FnOnce(SuspendedContext, Output) -> VNode<'src> + 'src,
|
|
||||||
>(
|
|
||||||
&'src self,
|
&'src self,
|
||||||
fut: &'src mut Pin<Box<dyn Future<Output = Output> + 'static>>,
|
fut: &'src mut Pin<Box<dyn Future<Output = Output> + 'static>>,
|
||||||
callback: Fut,
|
callback: Fut,
|
||||||
@@ -832,120 +873,6 @@ Any function prefixed with "use" should not be called conditionally.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Components in Dioxus use the "Context" object to interact with their lifecycle.
|
|
||||||
/// This lets components schedule updates, integrate hooks, and expose their context via the context api.
|
|
||||||
///
|
|
||||||
/// Properties passed down from the parent component are also directly accessible via the exposed "props" field.
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// #[derive(Properties)]
|
|
||||||
/// struct Props {
|
|
||||||
/// name: String
|
|
||||||
///
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn example(cx: Context<Props>) -> VNode {
|
|
||||||
/// html! {
|
|
||||||
/// <div> "Hello, {cx.name}" </div>
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
// todo: force lifetime of source into T as a valid lifetime too
|
|
||||||
// it's definitely possible, just needs some more messing around
|
|
||||||
pub struct Context<'src, T> {
|
|
||||||
pub props: &'src T,
|
|
||||||
pub scope: &'src Scope,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'src, T> Copy for Context<'src, T> {}
|
|
||||||
impl<'src, T> Clone for Context<'src, T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
props: self.props,
|
|
||||||
scope: self.scope,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for Context<'a, T> {
|
|
||||||
type Target = &'a T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// The `Scoped` trait makes it slightly less cumbersome for hooks to use the underlying `Scope` without having to make
|
|
||||||
/// their hooks generic over the [`Props`] type that [`Context`] is
|
|
||||||
///
|
|
||||||
/// ## Example:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// fn use_raw<T>(cx: impl Scoped) -> &mut T {
|
|
||||||
///
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
pub trait Scoped<'src>: Sized + Clone + Copy {
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
fn get_scope(self) -> &'src Scope;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn children(self) -> &'src [VNode<'src>] {
|
|
||||||
self.get_scope().children()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn schedule_update(self) -> Rc<dyn Fn() + 'static> {
|
|
||||||
self.get_scope().schedule_update()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn use_hook<InternalHookState: 'static, Output: 'src>(
|
|
||||||
self,
|
|
||||||
initializer: impl FnOnce() -> InternalHookState,
|
|
||||||
runner: impl FnOnce(&'src mut InternalHookState) -> Output,
|
|
||||||
_cleanup: impl FnOnce(InternalHookState),
|
|
||||||
) -> Output {
|
|
||||||
self.get_scope().use_hook(initializer, runner, _cleanup)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Take a lazy VNode structure and actually build it with the context of the VDom's efficient VNode allocator.
|
|
||||||
///
|
|
||||||
/// This function consumes the context and absorb the lifetime, so these VNodes *must* be returned.
|
|
||||||
///
|
|
||||||
/// ## Example
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// fn Component(cx: Context<()>) -> VNode {
|
|
||||||
/// // Lazy assemble the VNode tree
|
|
||||||
/// let lazy_tree = html! {<div> "Hello World" </div>};
|
|
||||||
///
|
|
||||||
/// // Actually build the tree and allocate it
|
|
||||||
/// cx.render(lazy_tree)
|
|
||||||
/// }
|
|
||||||
///```
|
|
||||||
#[inline]
|
|
||||||
fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
|
|
||||||
self,
|
|
||||||
lazy_nodes: LazyNodes<'src, F>,
|
|
||||||
) -> VNode<'src> {
|
|
||||||
self.get_scope().render(lazy_nodes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'src, T> Scoped<'src> for Context<'src, T> {
|
|
||||||
#[inline]
|
|
||||||
fn get_scope(self) -> &'src Scope {
|
|
||||||
self.scope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SuspendedContext {}
|
pub struct SuspendedContext {}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user