docs: update local examples and docs to support new syntaxes
This commit is contained in:
1 parent
e495b09bf1
commit
4de16c4779
118 files changed
+520
-1154
No files matched your search
@@ -58,7 +58,7 @@ impl<'a, const A: bool> FragmentBuilder<'a, A> {
|
||||
/// cx.render(rsx!{
|
||||
/// div {
|
||||
/// h1 {"Title card"}
|
||||
/// {props.children}
|
||||
/// {cx.props.children}
|
||||
/// }
|
||||
/// })
|
||||
/// }
|
||||
|
||||
@@ -440,7 +440,7 @@ impl<'bump> DiffState<'bump> {
|
||||
let height = parent_scope.height + 1;
|
||||
let subtree = parent_scope.subtree.get();
|
||||
|
||||
let parent_scope = unsafe { self.scopes.get_scope_raw(parent_idx) };
|
||||
let parent_scope = self.scopes.get_scope_raw(parent_idx);
|
||||
let caller = unsafe { std::mem::transmute(vcomponent.caller as *const _) };
|
||||
let fc_ptr = vcomponent.user_fc;
|
||||
|
||||
@@ -716,13 +716,12 @@ impl<'bump> DiffState<'bump> {
|
||||
new.associated_scope.set(Some(scope_addr));
|
||||
|
||||
// make sure the component's caller function is up to date
|
||||
let scope = unsafe {
|
||||
self.scopes
|
||||
.get_scope_mut(scope_addr)
|
||||
.unwrap_or_else(|| panic!("could not find {:?}", scope_addr))
|
||||
};
|
||||
let scope = self
|
||||
.scopes
|
||||
.get_scope(scope_addr)
|
||||
.unwrap_or_else(|| panic!("could not find {:?}", scope_addr));
|
||||
|
||||
scope.caller = unsafe { std::mem::transmute(new.caller) };
|
||||
scope.caller.set(unsafe { std::mem::transmute(new.caller) });
|
||||
|
||||
// React doesn't automatically memoize, but we do.
|
||||
let props_are_the_same = old.comparator.unwrap();
|
||||
|
||||
@@ -520,8 +520,8 @@ impl<'a> NodeFactory<'a> {
|
||||
move |other: &VComponent| {
|
||||
if user_fc == other.user_fc {
|
||||
// Safety
|
||||
// - We guarantee that FC<P> is the same by function pointer
|
||||
// - Because FC<P> is the same, then P must be the same (even with generics)
|
||||
// - We guarantee that Component<P> is the same by function pointer
|
||||
// - Because Component<P> is the same, then P must be the same (even with generics)
|
||||
// - Non-static P are autoderived to memoize as false
|
||||
// - This comparator is only called on a corresponding set of bumpframes
|
||||
//
|
||||
|
||||
@@ -28,7 +28,7 @@ use bumpalo::{boxed::Box as BumpBox, Bump};
|
||||
/// }
|
||||
///
|
||||
/// fn Example(cx: Context, props: &ExampleProps) -> Element {
|
||||
/// cx.render(rsx!{ div {"Hello, {props.name}"} })
|
||||
/// cx.render(rsx!{ div {"Hello, {cx.props.name}"} })
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Scope<'a, P> {
|
||||
@@ -88,7 +88,7 @@ pub struct ScopeState {
|
||||
|
||||
pub(crate) frames: [BumpFrame; 2],
|
||||
|
||||
pub(crate) caller: *const dyn Fn(&ScopeState) -> Element,
|
||||
pub(crate) caller: Cell<*const dyn Fn(&ScopeState) -> Element>,
|
||||
|
||||
pub(crate) items: RefCell<SelfReferentialItems<'static>>,
|
||||
|
||||
@@ -269,12 +269,12 @@ impl ScopeState {
|
||||
/// ```rust, ignore
|
||||
/// struct SharedState(&'static str);
|
||||
///
|
||||
/// static App: FC<()> = |cx, props|{
|
||||
/// static App: Component<()> = |cx, props|{
|
||||
/// cx.use_hook(|_| cx.provide_state(SharedState("world")), |_| {}, |_| {});
|
||||
/// rsx!(cx, Child {})
|
||||
/// }
|
||||
///
|
||||
/// static Child: FC<()> = |cx, props| {
|
||||
/// static Child: Component<()> = |cx| {
|
||||
/// let state = cx.consume_state::<SharedState>();
|
||||
/// rsx!(cx, div { "hello {state.0}" })
|
||||
/// }
|
||||
@@ -344,7 +344,7 @@ impl ScopeState {
|
||||
/// ## Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// fn Component(cx: Scope, props: &Props) -> Element {
|
||||
/// fn Component(cx: Scope<Props>) -> Element {
|
||||
/// // Lazy assemble the VNode tree
|
||||
/// let lazy_nodes = rsx!("hello world");
|
||||
///
|
||||
|
||||
@@ -72,14 +72,10 @@ impl ScopeArena {
|
||||
unsafe { self.scopes.borrow().get(&id).map(|f| &**f) }
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn get_scope_raw(&self, id: ScopeId) -> Option<*mut ScopeState> {
|
||||
pub(crate) fn get_scope_raw(&self, id: ScopeId) -> Option<*mut ScopeState> {
|
||||
self.scopes.borrow().get(&id).copied()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn get_scope_mut(&self, id: ScopeId) -> Option<&mut ScopeState> {
|
||||
self.scopes.borrow().get(&id).map(|s| &mut **s)
|
||||
}
|
||||
|
||||
pub(crate) fn new_with_key(
|
||||
&self,
|
||||
fc_ptr: *const (),
|
||||
@@ -95,35 +91,13 @@ impl ScopeArena {
|
||||
if let Some(old_scope) = self.free_scopes.borrow_mut().pop() {
|
||||
let scope = unsafe { &mut *old_scope };
|
||||
|
||||
scope.caller = caller;
|
||||
scope.caller.set(caller);
|
||||
scope.parent_scope = parent_scope;
|
||||
scope.height = height;
|
||||
scope.subtree = Cell::new(subtree);
|
||||
scope.our_arena_idx = new_scope_id;
|
||||
scope.container = container;
|
||||
|
||||
// scope.frames[0].nodes.get_mut().push({
|
||||
// let vnode = scope.frames[0]
|
||||
// .bump
|
||||
// .alloc(VNode::Text(scope.frames[0].bump.alloc(VText {
|
||||
// dom_id: Default::default(),
|
||||
// is_static: false,
|
||||
// text: "",
|
||||
// })));
|
||||
// unsafe { std::mem::transmute(vnode as *mut VNode) }
|
||||
// });
|
||||
|
||||
// scope.frames[1].nodes.get_mut().push({
|
||||
// let vnode = scope.frames[1]
|
||||
// .bump
|
||||
// .alloc(VNode::Text(scope.frames[1].bump.alloc(VText {
|
||||
// dom_id: Default::default(),
|
||||
// is_static: false,
|
||||
// text: "",
|
||||
// })));
|
||||
// unsafe { std::mem::transmute(vnode as *mut VNode) }
|
||||
// });
|
||||
|
||||
let any_item = self.scopes.borrow_mut().insert(new_scope_id, scope);
|
||||
debug_assert!(any_item.is_none());
|
||||
} else {
|
||||
@@ -148,7 +122,7 @@ impl ScopeArena {
|
||||
subtree: Cell::new(subtree),
|
||||
is_subtree_root: Cell::new(false),
|
||||
|
||||
caller,
|
||||
caller: Cell::new(caller),
|
||||
generation: 0.into(),
|
||||
|
||||
shared_contexts: Default::default(),
|
||||
@@ -277,18 +251,20 @@ impl ScopeArena {
|
||||
// Remove all the outdated listeners
|
||||
self.ensure_drop_safety(id);
|
||||
|
||||
let scope = unsafe { &mut *self.get_scope_mut(id).expect("could not find scope") };
|
||||
// todo: we *know* that this is aliased by the contents of the scope itself
|
||||
let scope = unsafe { &mut *self.get_scope_raw(id).expect("could not find scope") };
|
||||
|
||||
// Safety:
|
||||
// - We dropped the listeners, so no more &mut T can be used while these are held
|
||||
// - All children nodes that rely on &mut T are replaced with a new reference
|
||||
scope.hook_idx.set(0);
|
||||
|
||||
// Safety:
|
||||
// - We've dropped all references to the wip bump frame with "ensure_drop_safety"
|
||||
unsafe { scope.reset_wip_frame() };
|
||||
|
||||
// book keeping to ensure safety around the borrowed data
|
||||
{
|
||||
// Safety:
|
||||
// - We've dropped all references to the wip bump frame with "ensure_drop_safety"
|
||||
unsafe { scope.reset_wip_frame() };
|
||||
|
||||
let mut items = scope.items.borrow_mut();
|
||||
|
||||
// just forget about our suspended nodes while we're at it
|
||||
@@ -298,12 +274,9 @@ impl ScopeArena {
|
||||
debug_assert!(items.listeners.is_empty());
|
||||
debug_assert!(items.borrowed_props.is_empty());
|
||||
debug_assert!(items.tasks.is_empty());
|
||||
|
||||
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
||||
// scope.wip_frame().nodes
|
||||
}
|
||||
|
||||
let render: &dyn Fn(&ScopeState) -> Element = unsafe { &*scope.caller };
|
||||
let render: &dyn Fn(&ScopeState) -> Element = unsafe { &*scope.caller.get() };
|
||||
|
||||
if let Some(node) = render(scope) {
|
||||
if !scope.items.borrow().tasks.is_empty() {
|
||||
@@ -319,6 +292,10 @@ impl ScopeArena {
|
||||
scope.cycle_frame();
|
||||
true
|
||||
} else {
|
||||
// the component bailed out early
|
||||
// this leaves the wip frame and all descendents in a state where
|
||||
// their WIP frames are invalid
|
||||
// todo: descendents should not cause the app to crash
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ use std::{any::Any, collections::VecDeque, pin::Pin, sync::Arc, task::Poll};
|
||||
///
|
||||
/// fn App(cx: Context, props: &AppProps) -> Element {
|
||||
/// cx.render(rsx!(
|
||||
/// div {"hello, {props.title}"}
|
||||
/// div {"hello, {cx.props.title}"}
|
||||
/// ))
|
||||
/// }
|
||||
/// ```
|
||||
@@ -36,7 +36,7 @@ use std::{any::Any, collections::VecDeque, pin::Pin, sync::Arc, task::Poll};
|
||||
/// fn App(cx: Context, props: &AppProps) -> Element {
|
||||
/// cx.render(rsx!(
|
||||
/// NavBar { routes: ROUTES }
|
||||
/// Title { "{props.title}" }
|
||||
/// Title { "{cx.props.title}" }
|
||||
/// Footer {}
|
||||
/// ))
|
||||
/// }
|
||||
@@ -459,7 +459,7 @@ impl VirtualDom {
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust, ignore
|
||||
/// static App: FC<()> = |cx, props| cx.render(rsx!{ "hello world" });
|
||||
/// static App: Component<()> = |cx, props| cx.render(rsx!{ "hello world" });
|
||||
/// let mut dom = VirtualDom::new();
|
||||
/// let edits = dom.rebuild();
|
||||
///
|
||||
@@ -497,7 +497,7 @@ impl VirtualDom {
|
||||
/// value: Shared<&'static str>,
|
||||
/// }
|
||||
///
|
||||
/// static App: FC<AppProps> = |cx, props|{
|
||||
/// static App: Component<AppProps> = |cx, props|{
|
||||
/// let val = cx.value.borrow();
|
||||
/// cx.render(rsx! { div { "{val}" } })
|
||||
/// };
|
||||
|
||||
Reference in new issue
Block a user