chore: rename ctx to cx

This commit is contained in:
Jonathan Kelley committed 2021-06-25 21:15:33 -04:00
1 parent 23c14078bb
commit 81382e7044
99 files changed
+789 -664

No files matched your search

+4 -4
View File
@@ -3,7 +3,7 @@
//!
//! Note - using the builder pattern does not required the Properties trait to be implemented - the only thing that matters is
//! if the type suppports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
//! that ensures compile-time required and optional fields on ctx.
//! that ensures compile-time required and optional fields on cx.
use crate::innerlude::FC;
@@ -50,9 +50,9 @@ pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
/// Fragments are incredibly useful when necessary, but *do* add cost in the diffing phase.
/// Try to avoid nesting fragments if you can. Infinitely nested Fragments *will* cause diffing to crash.
#[allow(non_upper_case_globals)]
pub const Fragment: FC<()> = |ctx| {
pub const Fragment: FC<()> = |cx| {
use crate::prelude::*;
ctx.render(LazyNodes::new(move |c| {
crate::nodebuilder::vfragment(c, None, ctx.children())
cx.render(LazyNodes::new(move |c| {
crate::nodebuilder::vfragment(c, None, cx.children())
}))
};
+3 -3
View File
@@ -86,7 +86,7 @@ impl DebugVNodeSource {
}
fn render_nodes(&self) -> VNode {
// let ctx = NodeCtx
// let cx = NodeCtx
todo!()
}
}
@@ -97,9 +97,9 @@ mod tests {
#[test]
fn ensure_creation() -> Result<(), ()> {
// static Example: FC<()> = |ctx| {
// static Example: FC<()> = |cx| {
// //
// ctx.render(html! { <div> "hello world" </div> })
// cx.render(html! { <div> "hello world" </div> })
// };
// let mut dom = VirtualDom::new(Example);
+3
View File
@@ -44,6 +44,9 @@ pub enum VirtualEvent {
MouseEvent(Rc<dyn on::MouseEvent>),
PointerEvent(Rc<dyn on::PointerEvent>),
// Whenever a task is ready (complete) Dioxus produces this "FiberEvent"
FiberEvent { task_id: u16 },
// image event has conflicting method types
// ImageEvent(event_data::ImageEvent),
OtherEvent,
+20 -20
View File
@@ -28,8 +28,8 @@ mod use_state_def {
///
/// Usage:
/// ```ignore
/// static Example: FC<()> = |ctx| {
/// let (counter, set_counter) = use_state(&ctx, || 0);
/// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0);
/// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1);
///
@@ -43,7 +43,7 @@ mod use_state_def {
/// }
/// ```
pub fn use_state<'a, 'c, T: 'static, F: FnOnce() -> T>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: F,
) -> (&'a T, &'a Rc<dyn Fn(T)>) {
struct UseState<T: 'static> {
@@ -52,7 +52,7 @@ mod use_state_def {
caller: Rc<dyn Fn(T) + 'static>,
}
ctx.use_hook(
cx.use_hook(
move || UseState {
new_val: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -61,7 +61,7 @@ mod use_state_def {
move |hook| {
log::debug!("Use_state set called");
let inner = hook.new_val.clone();
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// get ownership of the new val and replace the current with the new
// -> as_ref -> borrow_mut -> deref_mut -> take
@@ -155,8 +155,8 @@ mod new_use_state_def {
///
/// Usage:
/// ```ignore
/// static Example: FC<()> = |ctx| {
/// let (counter, set_counter) = use_state(&ctx, || 0);
/// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0);
/// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1);
///
@@ -170,10 +170,10 @@ mod new_use_state_def {
/// }
/// ```
pub fn use_state_new<'a, 'c, T: 'static, F: FnOnce() -> T>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: F,
) -> &'a UseState<T> {
ctx.use_hook(
cx.use_hook(
move || UseState {
modifier: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -182,7 +182,7 @@ mod new_use_state_def {
},
move |hook| {
log::debug!("addr of hook: {:#?}", hook as *const _);
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// log::debug!("Checking if new value {:#?}", &hook.current_val);
// get ownership of the new val and replace the current with the new
@@ -247,10 +247,10 @@ mod use_ref_def {
/// Modifications to this value do not cause updates to the component
/// Attach to inner context reference, so context can be consumed
pub fn use_ref<'a, T: 'static>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: impl FnOnce() -> T + 'static,
) -> &'a RefCell<T> {
ctx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
cx.use_hook(|| RefCell::new(initial_state_fn()), |state| &*state, |_| {})
}
}
@@ -271,11 +271,11 @@ mod use_reducer_def {
/// This is behaves almost exactly the same way as React's "use_state".
///
pub fn use_reducer<'a, 'c, State: 'static, Action: 'static>(
ctx: &impl Scoped<'a>,
cx: &impl Scoped<'a>,
initial_state_fn: impl FnOnce() -> State,
_reducer: impl Fn(&mut State, Action),
) -> (&'a State, &'a Box<dyn Fn(Action)>) {
ctx.use_hook(
cx.use_hook(
move || UseReducer {
new_val: Rc::new(RefCell::new(None)),
current_val: initial_state_fn(),
@@ -283,7 +283,7 @@ mod use_reducer_def {
},
move |hook| {
let _inner = hook.new_val.clone();
let scheduled_update = ctx.schedule_update();
let scheduled_update = cx.schedule_update();
// get ownership of the new val and replace the current with the new
// -> as_ref -> borrow_mut -> deref_mut -> take
@@ -320,9 +320,9 @@ mod use_reducer_def {
}
// #[allow(unused)]
// static Example: FC<()> = |ctx| {
// static Example: FC<()> = |cx| {
// let (count, reduce) = use_reducer(
// &ctx,
// &cx,
// || 0,
// |count, action| match action {
// Actions::Incr => *count += 1,
@@ -330,7 +330,7 @@ mod use_reducer_def {
// },
// );
// ctx.render(rsx! {
// cx.render(rsx! {
// div {
// h1 {"Count: {count}"}
// button {
@@ -347,8 +347,8 @@ mod use_reducer_def {
}
}
pub fn use_is_initialized<P>(ctx: Context<P>) -> bool {
let val = use_ref(&ctx, || false);
pub fn use_is_initialized<P>(cx: Context<P>) -> bool {
let val = use_ref(&cx, || false);
match *val.borrow() {
true => true,
false => {
+39 -38
View File
@@ -29,13 +29,14 @@ where
Attributes: 'a + AsRef<[Attribute<'a>]>,
Children: 'a + AsRef<[VNode<'a>]>,
{
ctx: &'b NodeCtx<'a>,
cx: &'b NodeCtx<'a>,
key: NodeKey<'a>,
tag_name: &'a str,
tag_name: &'static str,
// tag_name: &'a str,
listeners: Listeners,
attributes: Attributes,
children: Children,
namespace: Option<&'a str>,
namespace: Option<&'static str>,
}
impl<'a, 'b>
@@ -70,10 +71,10 @@ impl<'a, 'b>
/// let my_element_builder = ElementBuilder::new(&b, tag_name);
/// # fn flip_coin() -> bool { true }
/// ```
pub fn new(ctx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
let bump = ctx.bump();
pub fn new(cx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
let bump = cx.bump();
ElementBuilder {
ctx,
cx,
key: NodeKey::NONE,
tag_name,
listeners: bumpalo::collections::Vec::new_in(bump),
@@ -124,7 +125,7 @@ where
L: 'a + AsRef<[Listener<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners,
@@ -163,7 +164,7 @@ where
A: 'a + AsRef<[Attribute<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -202,7 +203,7 @@ where
C: 'a + AsRef<[VNode<'a>]>,
{
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -227,9 +228,9 @@ where
/// .finish();
/// ```
#[inline]
pub fn namespace(self, namespace: Option<&'a str>) -> Self {
pub fn namespace(self, namespace: Option<&'static str>) -> Self {
ElementBuilder {
ctx: self.ctx,
cx: self.cx,
key: self.key,
tag_name: self.tag_name,
listeners: self.listeners,
@@ -281,7 +282,7 @@ where
Some(static_str) => static_str,
None => {
use bumpalo::core_alloc::fmt::Write;
let mut s = bumpalo::collections::String::new_in(self.ctx.bump());
let mut s = bumpalo::collections::String::new_in(self.cx.bump());
s.write_fmt(args).unwrap();
s.into_bump_str()
}
@@ -307,7 +308,7 @@ where
/// ```
#[inline]
pub fn finish(self) -> VNode<'a> {
let bump = self.ctx.bump();
let bump = self.cx.bump();
let children: &'a Children = bump.alloc(self.children);
let children: &'a [VNode<'a>] = children.as_ref();
@@ -357,11 +358,11 @@ where
/// .finish();
/// ```
pub fn on(self, event: &'static str, callback: impl Fn(VirtualEvent) + 'a) -> Self {
let bump = &self.ctx.bump();
let bump = &self.cx.bump();
let listener = Listener {
event,
callback: bump.alloc(callback),
scope: self.ctx.scope_ref.arena_idx,
scope: self.cx.scope_ref.arena_idx,
mounted_node: bump.alloc(Cell::new(RealDomNode::empty())),
};
self.add_listener(listener)
@@ -371,15 +372,15 @@ where
self.listeners.push(listener);
// bump the context id forward
let id = self.ctx.listener_id.get();
self.ctx.listener_id.set(id + 1);
let id = self.cx.listener_id.get();
self.cx.listener_id.set(id + 1);
// Add this listener to the context list
// This casts the listener to a self-referential pointer
// This is okay because the bump arena is stable
self.listeners.last().map(|g| {
let r = unsafe { std::mem::transmute::<&Listener<'a>, &Listener<'static>>(g) };
self.ctx
self.cx
.scope_ref
.listeners
.borrow_mut()
@@ -413,7 +414,7 @@ where
Some(static_str) => static_str,
None => {
use bumpalo::core_alloc::fmt::Write;
let mut s = bumpalo::collections::String::new_in(self.ctx.bump());
let mut s = bumpalo::collections::String::new_in(self.cx.bump());
s.write_fmt(args).unwrap();
s.into_bump_str()
}
@@ -501,7 +502,7 @@ where
pub fn iter_child(mut self, nodes: impl IntoIterator<Item = impl IntoVNode<'a>>) -> Self {
let len_before = self.children.len();
for item in nodes {
let child = item.into_vnode(&self.ctx);
let child = item.into_vnode(&self.cx);
self.children.push(child);
}
if cfg!(debug_assertions) {
@@ -531,20 +532,20 @@ impl<'a> IntoIterator for VNode<'a> {
}
}
impl<'a> IntoVNode<'a> for VNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
self
}
}
impl<'a> IntoVNode<'a> for &VNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
// cloning is cheap since vnodes are just references into bump arenas
self.clone()
}
}
pub trait IntoVNode<'a> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a>;
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a>;
}
pub trait VNodeBuilder<'a, G>: IntoIterator<Item = G>
@@ -590,8 +591,8 @@ impl<'a, G> IntoVNode<'a> for LazyNodes<'a, G>
where
G: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a,
{
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
(self.inner)(ctx)
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
(self.inner)(cx)
}
}
@@ -608,14 +609,14 @@ where
}
impl<'a> IntoVNode<'a> for () {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
}
}
impl<'a> IntoVNode<'a> for Option<()> {
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
}
@@ -679,7 +680,7 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> {
}
pub fn virtual_child<'a, T: Properties + 'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
f: FC<T>,
props: T,
key: Option<&'a str>, // key: NodeKey<'a>,
@@ -689,37 +690,37 @@ pub fn virtual_child<'a, T: Properties + 'a>(
// might override it with the props macro
// todo!()
VNode::Component(
ctx.bump()
.alloc(crate::nodes::VComponent::new(ctx, f, props, key, children)),
// ctx.bump()
cx.bump()
.alloc(crate::nodes::VComponent::new(cx, f, props, key, children)),
// cx.bump()
// .alloc(crate::nodes::VComponent::new(f, props, key)),
)
}
pub fn vfragment<'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
key: Option<&'a str>, // key: NodeKey<'a>,
children: &'a [VNode<'a>],
) -> VNode<'a> {
VNode::Fragment(ctx.bump().alloc(VFragment::new(key, children)))
VNode::Fragment(cx.bump().alloc(VFragment::new(key, children)))
}
pub struct ChildrenList<'a, 'b> {
ctx: &'b NodeCtx<'a>,
cx: &'b NodeCtx<'a>,
children: bumpalo::collections::Vec<'a, VNode<'a>>,
}
impl<'a, 'b> ChildrenList<'a, 'b> {
pub fn new(ctx: &'b NodeCtx<'a>) -> Self {
pub fn new(cx: &'b NodeCtx<'a>) -> Self {
Self {
ctx,
children: bumpalo::collections::Vec::new_in(ctx.bump()),
cx,
children: bumpalo::collections::Vec::new_in(cx.bump()),
}
}
pub fn add_child(mut self, nodes: impl IntoIterator<Item = impl IntoVNode<'a>>) -> Self {
for item in nodes {
let child = item.into_vnode(&self.ctx);
let child = item.into_vnode(&self.cx);
self.children.push(child);
}
self
+48 -11
View File
@@ -11,10 +11,8 @@ use crate::{
};
use bumpalo::Bump;
use std::{
any::Any,
cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter},
marker::PhantomData,
rc::Rc,
};
@@ -56,6 +54,43 @@ impl<'a> Clone for VNode<'a> {
}
}
impl<'old, 'new> VNode<'old> {
// performs a somewhat costly clone of this vnode into another bump
// this is used when you want to drag nodes from an old frame into a new frame
// There is no way to safely drag listeners over (no way to clone a closure)
//
// This method will only be called if a component was once a real node and then becomes suspended
fn deep_clone_to_new_bump(&self, new: &'new Bump) -> VNode<'new> {
match self {
VNode::Element(el) => {
let new_el: VElement<'new> = VElement {
key: NodeKey::NONE,
// key: el.key.clone(),
tag_name: el.tag_name,
// wipe listeners on deep clone, there's no way to know what other bump material they might be referencing (nodes, etc)
listeners: &[],
attributes: {
let attr_vec = bumpalo::collections::Vec::new_in(new);
attr_vec.into_bump_slice()
},
children: {
let attr_vec = bumpalo::collections::Vec::new_in(new);
attr_vec.into_bump_slice()
},
namespace: el.namespace.clone(),
dom_id: el.dom_id.clone(),
};
VNode::Element(new.alloc_with(move || new_el))
}
VNode::Text(_) => todo!(),
VNode::Fragment(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Component(_) => todo!(),
}
}
}
impl<'a> VNode<'a> {
/// Low-level constructor for making a new `Node` of type element with given
/// parts.
@@ -67,11 +102,11 @@ impl<'a> VNode<'a> {
pub fn element(
bump: &'a Bump,
key: NodeKey<'a>,
tag_name: &'a str,
tag_name: &'static str,
listeners: &'a [Listener<'a>],
attributes: &'a [Attribute<'a>],
children: &'a [VNode<'a>],
namespace: Option<&'a str>,
namespace: Option<&'static str>,
) -> VNode<'a> {
let element = bump.alloc_with(|| VElement {
key,
@@ -157,14 +192,16 @@ pub struct VText<'src> {
// ========================================================
// VElement (div, h1, etc), attrs, keys, listener handle
// ========================================================
#[derive(Clone)]
pub struct VElement<'a> {
/// Elements have a tag name, zero or more attributes, and zero or more
pub key: NodeKey<'a>,
pub tag_name: &'a str,
pub tag_name: &'static str,
pub listeners: &'a [Listener<'a>],
pub attributes: &'a [Attribute<'a>],
pub children: &'a [VNode<'a>],
pub namespace: Option<&'a str>,
pub namespace: Option<&'static str>,
pub dom_id: Cell<RealDomNode>,
}
@@ -298,13 +335,13 @@ impl<'a> VComponent<'a> {
///
/// If the CanMemo is `false`, then the macro will call the backup method which always defaults to "false"
pub fn new<P: Properties + 'a>(
ctx: &NodeCtx<'a>,
cx: &NodeCtx<'a>,
component: FC<P>,
props: P,
key: Option<&'a str>,
children: &'a [VNode<'a>],
) -> Self {
let bump = ctx.bump();
let bump = cx.bump();
let user_fc = component as *const ();
let props = bump.alloc(props);
@@ -370,13 +407,13 @@ fn create_closure<'a, P: 'a>(
let g: Captured = Rc::new(move |scp: &Scope| -> VNode {
// cast back into the right lifetime
let safe_props: &'_ P = unsafe { &*(raw_props as *const P) };
// let ctx: Context<P2> = todo!();
let ctx: Context<P> = Context {
// let cx: Context<P2> = todo!();
let cx: Context<P> = Context {
props: safe_props,
scope: scp,
};
let g = component(ctx);
let g = component(cx);
let g2 = unsafe { std::mem::transmute(g) };
g2
});
+60 -26
View File
@@ -21,6 +21,7 @@
use crate::{arena::ScopeArena, innerlude::*};
use bumpalo::Bump;
use futures::FutureExt;
use generational_arena::Arena;
use std::{
any::{Any, TypeId},
@@ -55,7 +56,7 @@ pub struct VirtualDom {
#[doc(hidden)]
_root_caller: Rc<OpaqueComponent>,
// _root_caller: Rc<OpaqueComponent<'static>>,
/// Type of the original ctx. This is stored as TypeId so VirtualDom does not need to be generic.
/// Type of the original cx. This is stored as TypeId so VirtualDom does not need to be generic.
///
/// Whenver props need to be updated, an Error will be thrown if the new props do not
/// match the props used to create the VirtualDom.
@@ -90,12 +91,12 @@ impl VirtualDom {
/// ```ignore
/// // Directly from a closure
///
/// let dom = VirtualDom::new(|ctx| ctx.render(rsx!{ div {"hello world"} }));
/// let dom = VirtualDom::new(|cx| cx.render(rsx!{ div {"hello world"} }));
///
/// // or pass in...
///
/// let root = |ctx| {
/// ctx.render(rsx!{
/// let root = |cx| {
/// cx.render(rsx!{
/// div {"hello world"}
/// })
/// }
@@ -103,8 +104,8 @@ impl VirtualDom {
///
/// // or directly from a fn
///
/// fn Example(ctx: Context<()>) -> VNode {
/// ctx.render(rsx!{ div{"hello world"} })
/// fn Example(cx: Context<()>) -> VNode {
/// cx.render(rsx!{ div{"hello world"} })
/// }
///
/// let dom = VirtualDom::new(Example);
@@ -113,7 +114,7 @@ impl VirtualDom {
Self::new_with_props(root, ())
}
/// Start a new VirtualDom instance with a dependent ctx.
/// Start a new VirtualDom instance with a dependent cx.
/// Later, the props can be updated by calling "update" with a new set of props, causing a set of re-renders.
///
/// This is useful when a component tree can be driven by external state (IE SSR) but it would be too expensive
@@ -122,12 +123,12 @@ impl VirtualDom {
/// ```ignore
/// // Directly from a closure
///
/// let dom = VirtualDom::new(|ctx| ctx.render(rsx!{ div {"hello world"} }));
/// let dom = VirtualDom::new(|cx| cx.render(rsx!{ div {"hello world"} }));
///
/// // or pass in...
///
/// let root = |ctx| {
/// ctx.render(rsx!{
/// let root = |cx| {
/// cx.render(rsx!{
/// div {"hello world"}
/// })
/// }
@@ -135,8 +136,8 @@ impl VirtualDom {
///
/// // or directly from a fn
///
/// fn Example(ctx: Context, props: &SomeProps) -> VNode {
/// ctx.render(rsx!{ div{"hello world"} })
/// fn Example(cx: Context, props: &SomeProps) -> VNode {
/// cx.render(rsx!{ div{"hello world"} })
/// }
///
/// let dom = VirtualDom::new(Example);
@@ -395,11 +396,13 @@ pub struct Scope {
// Stores references into the listeners attached to the vnodes
// NEEDS TO BE PRIVATE
pub(crate) listeners: RefCell<Vec<(*const Cell<RealDomNode>, *const dyn Fn(VirtualEvent))>>,
pub(crate) suspended_tasks: Vec<Box<dyn Future<Output = VNode<'static>>>>,
// pub(crate) listeners: RefCell<nohash_hasher::IntMap<u32, *const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// NoHashMap<RealDomNode, <*const dyn Fn(VirtualEvent)>
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>,
// pub(crate) listeners: RefCell<Vec<*const dyn Fn(VirtualEvent)>>
}
// We need to pin the hook so it doesn't move as we initialize the list of hooks
@@ -465,6 +468,7 @@ impl Scope {
listeners: Default::default(),
hookidx: Default::default(),
descendents: Default::default(),
suspended_tasks: Default::default(),
}
}
@@ -588,9 +592,9 @@ impl Scope {
///
/// }
///
/// fn example(ctx: Context, props: &Props -> VNode {
/// fn example(cx: Context, props: &Props -> VNode {
/// html! {
/// <div> "Hello, {ctx.ctx.name}" </div>
/// <div> "Hello, {cx.cx.name}" </div>
/// }
/// }
/// ```
@@ -645,6 +649,14 @@ pub trait Scoped<'src>: Sized {
self.get_scope().event_channel.clone()
}
fn schedule_effect(&self) -> Rc<dyn Fn() + 'static> {
todo!()
}
fn schedule_layout_effect(&self) {
todo!()
}
/// 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.
@@ -652,12 +664,12 @@ pub trait Scoped<'src>: Sized {
/// ## Example
///
/// ```ignore
/// fn Component(ctx: Context<()>) -> VNode {
/// 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
/// ctx.render(lazy_tree)
/// cx.render(lazy_tree)
/// }
///```
fn render<'a, F: for<'b> FnOnce(&'b NodeCtx<'src>) -> VNode<'src> + 'src + 'a>(
@@ -750,7 +762,7 @@ Any function prefixed with "use" should not be called conditionally.
///
fn use_create_context<T: 'static>(&self, init: impl Fn() -> T) {
let scope = self.get_scope();
let mut ctxs = scope.shared_contexts.borrow_mut();
let mut cxs = scope.shared_contexts.borrow_mut();
let ty = TypeId::of::<T>();
let is_initialized = self.use_hook(
@@ -763,14 +775,14 @@ Any function prefixed with "use" should not be called conditionally.
|_| {},
);
match (is_initialized, ctxs.contains_key(&ty)) {
match (is_initialized, cxs.contains_key(&ty)) {
// Do nothing, already initialized and already exists
(true, true) => {}
// Needs to be initialized
(false, false) => {
log::debug!("Initializing context...");
ctxs.insert(ty, Rc::new(init()));
cxs.insert(ty, Rc::new(init()));
}
_ => debug_assert!(false, "Cannot initialize two contexts of the same type"),
@@ -810,9 +822,9 @@ Any function prefixed with "use" should not be called conditionally.
log::debug!("Searching {:#?} for valid shared_context", inner.arena_idx);
let shared_contexts = inner.shared_contexts.borrow();
if let Some(shared_ctx) = shared_contexts.get(&ty) {
log::debug!("found matching ctx");
let rc = shared_ctx
if let Some(shared_cx) = shared_contexts.get(&ty) {
log::debug!("found matching cx");
let rc = shared_cx
.clone()
.downcast::<T>()
.expect("Should not fail, already validated the type from the hashmap");
@@ -841,10 +853,32 @@ Any function prefixed with "use" should not be called conditionally.
)
}
fn suspend<O>(
fn suspend<O: 'src>(
&self,
f: impl Future<Output = O>,
g: impl FnOnce(O) -> VNode<'src> + 'src,
f: &'src mut Pin<Box<dyn Future<Output = O> + Send + 'static>>,
g: impl FnOnce(SuspendedContext, O) -> VNode<'src> + 'src,
) -> VNode<'src> {
match f.now_or_never() {
Some(o) => {
let suspended_cx = SuspendedContext {};
let nodes = g(suspended_cx, o);
return nodes;
}
None => {
// we need to register this task
VNode::Suspended
}
}
}
}
#[derive(Clone)]
pub struct SuspendedContext {}
impl SuspendedContext {
pub fn render<'a, 'src, F: for<'b> FnOnce(&'b NodeCtx<'src>) -> VNode<'src> + 'src + 'a>(
self,
lazy_nodes: LazyNodes<'src, F>,
) -> VNode<'src> {
todo!()
}