Feat: rename recoil to atoms
This commit is contained in:
1 parent
47e896038e
commit
36ea39ae30
29 files changed
+398
-249
No files matched your search
@@ -33,3 +33,31 @@ impl EmptyBuilder {
|
||||
pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
|
||||
T::builder()
|
||||
}
|
||||
|
||||
mod eliminate_bounds {
|
||||
|
||||
struct BNode<'a> {
|
||||
_p: &'a (),
|
||||
}
|
||||
|
||||
trait Broper {}
|
||||
impl Broper for () {}
|
||||
|
||||
struct Bontext<'a, P: Broper + 'a> {
|
||||
inner: &'a (),
|
||||
props: P,
|
||||
}
|
||||
|
||||
fn Bexample(c: Bontext<()>) -> BNode {
|
||||
todo!()
|
||||
}
|
||||
|
||||
struct MyBrops<'a> {
|
||||
_i: &'a (),
|
||||
}
|
||||
impl<'a> Broper for MyBrops<'a> {}
|
||||
|
||||
fn Bexample2<'a>(c: Bontext<'a, MyBrops<'a>>) -> BNode {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
+26
-25
@@ -1,3 +1,14 @@
|
||||
//! This module contains the stateful DiffMachine and all methods to diff VNodes, their properties, and their children.
|
||||
//!
|
||||
//! Notice:
|
||||
//! ------
|
||||
//!
|
||||
//! The inspiration and code for this module was originally taken from Dodrio (@fitzgen) and modified to support Components,
|
||||
//! Fragments, Suspense, and additional batching operations.
|
||||
//!
|
||||
//! Implementation Details:
|
||||
//! -----------------------
|
||||
//!
|
||||
//! Diff the `old` node with the `new` node. Emits instructions to modify a
|
||||
//! physical DOM node that reflects `old` into something that reflects `new`.
|
||||
//!
|
||||
@@ -8,39 +19,18 @@
|
||||
//!
|
||||
//! The change list stack is in the same state when this function exits.
|
||||
//!
|
||||
//! ----
|
||||
//! Further Reading and Thoughts
|
||||
//! ----------------------------
|
||||
//!
|
||||
//! There are more ways of increasing diff performance here that are currently not implemented.
|
||||
//! Additionally, the caching mechanism has also been tweaked.
|
||||
//!
|
||||
//! Instead of having "cached" nodes, each component is, by default, a cached node. This leads to increased
|
||||
//! memory overhead for large numbers of small components, but we can optimize this by tracking alloc size over time
|
||||
//! and shrinking bumps down if possible.
|
||||
//!
|
||||
//! Additionally, clean up of these components is not done at diff time (though it should), but rather, the diffing
|
||||
//! proprogates removal lifecycle events for affected components into the event queue. It's not imperative that these
|
||||
//! are ran immediately, but it should be noted that cleanup of components might be able to emit changes.
|
||||
//!
|
||||
//! This diffing only ever occurs on a component-by-component basis (not entire trees at once).
|
||||
//!
|
||||
//! Currently, the listener situation is a bit broken.
|
||||
//! We aren't removing listeners (choosing to leak them instead) :(
|
||||
//! Eventually, we'll set things up so add/remove listener is an instruction again
|
||||
//!
|
||||
//! A major assumption of this diff algorithm when combined with the ChangeList is that the Changelist will be
|
||||
//! fresh and the event queue is clean. This lets us continue to batch edits together under the same ChangeList
|
||||
//!
|
||||
//! More info on how to improve this diffing algorithm:
|
||||
//! - https://hacks.mozilla.org/2019/03/fast-bump-allocated-virtual-doms-with-rust-and-wasm/
|
||||
|
||||
use crate::{arena::ScopeArena, innerlude::*};
|
||||
use bumpalo::Bump;
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
use generational_arena::Arena;
|
||||
|
||||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
cmp::Ordering,
|
||||
collections::VecDeque,
|
||||
rc::{Rc, Weak},
|
||||
sync::atomic::AtomicU32,
|
||||
};
|
||||
@@ -207,7 +197,18 @@ impl<'a> DiffMachine<'a> {
|
||||
todo!("Fragments not currently supported in diffing")
|
||||
}
|
||||
|
||||
(_, VNode::Fragment(_)) => {
|
||||
(VNode::Fragment(_), VNode::Fragment(_)) => {
|
||||
todo!("Fragments not currently supported in diffing")
|
||||
}
|
||||
|
||||
(old_n, VNode::Fragment(_)) => {
|
||||
match old_n {
|
||||
VNode::Element(_) => todo!(),
|
||||
VNode::Text(_) => todo!(),
|
||||
VNode::Fragment(_) => todo!(),
|
||||
VNode::Suspended => todo!(),
|
||||
VNode::Component(_) => todo!(),
|
||||
}
|
||||
todo!("Fragments not currently supported in diffing")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,11 @@
|
||||
//! <div align="center">
|
||||
//! <h1>🌗🚀 📦 Dioxus</h1>
|
||||
//! <p>
|
||||
//! <strong>A concurrent, functional, virtual DOM for Rust</strong>
|
||||
//! </p>
|
||||
//! </div>
|
||||
//! Dioxus: a concurrent, functional, reactive virtual dom for any renderer in Rust.
|
||||
//! Dioxus Core
|
||||
//! ----------
|
||||
//!
|
||||
//! This crate aims to maintain a hook-based, renderer-agnostic framework for cross-platform UI development.
|
||||
//!
|
||||
//! ## Components
|
||||
//! The base unit of Dioxus is the `component`. Components can be easily created from just a function - no traits required:
|
||||
//! ```
|
||||
//! use dioxus_core::prelude::*;
|
||||
//!
|
||||
//! #[derive(Properties)]
|
||||
//! struct Props { name: String }
|
||||
//!
|
||||
//! fn Example(ctx: Context, props: &Props) -> VNode {
|
||||
//! html! { <div> "Hello {ctx.name}!" </div> }
|
||||
//! }
|
||||
//! ```
|
||||
//! Components need to take a "Context" parameter which is generic over some properties. This defines how the component can be used
|
||||
//! and what properties can be used to specify it in the VNode output. Component state in Dioxus is managed by hooks - if you're new
|
||||
//! to hooks, check out the hook guide in the official guide.
|
||||
//!
|
||||
//! Components can also be crafted as static closures, enabling type inference without all the type signature noise:
|
||||
//! ```
|
||||
//! use dioxus_core::prelude::*;
|
||||
//!
|
||||
//! #[derive(Properties)]
|
||||
//! struct Props { name: String }
|
||||
//!
|
||||
//! static Example: FC<Props> = |ctx| {
|
||||
//! html! { <div> "Hello {ctx.name}!" </div> }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! If the properties struct is too noisy for you, we also provide a macro that converts variadic functions into components automatically.
|
||||
//! Many people don't like the magic of proc macros, so this is entirely optional. Under-the-hood, we simply transplant the
|
||||
//! function arguments into a struct, so there's very little actual magic happening.
|
||||
//!
|
||||
//! ```
|
||||
//! use dioxus_core::prelude::*;
|
||||
//!
|
||||
//! #[derive_props]
|
||||
//! static Example: FC = |ctx, name: &String| {
|
||||
//! html! { <div> "Hello {name}!" </div> }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Hooks
|
||||
//! Dioxus uses hooks for state management. Hooks are a form of state persisted between calls of the function component. Instead of
|
||||
//! using a single struct to store data, hooks use the "use_hook" building block which allows the persistence of data between
|
||||
//! function component renders. Each hook stores some data in a "memory cell" and needs to be called in a consistent order.
|
||||
//! This means hooks "anything with `use_x`" may not be called conditionally.
|
||||
//!
|
||||
//! This allows functions to reuse stateful logic between components, simplify large complex components, and adopt more clear context
|
||||
//! subscription patterns to make components easier to read.
|
||||
//!
|
||||
//! ## Supported Renderers
|
||||
//! Instead of being tightly coupled to a platform, browser, or toolkit, Dioxus implements a VirtualDOM object which
|
||||
//! can be consumed to draw the UI. The Dioxus VDOM is reactive and easily consumable by 3rd-party renderers via
|
||||
//! the `Patch` object. See [Implementing a Renderer](docs/8-custom-renderer.md) and the `StringRenderer` classes for information
|
||||
//! on how to implement your own custom renderer. We provide 1st-class support for these renderers:
|
||||
//! - dioxus-desktop (via WebView)
|
||||
//! - dioxus-web (via WebSys)
|
||||
//! - dioxus-ssr (via StringRenderer)
|
||||
//! - dioxus-liveview (SSR + StringRenderer)
|
||||
//!
|
||||
|
||||
pub mod arena;
|
||||
@@ -104,7 +43,6 @@ pub(crate) mod innerlude {
|
||||
pub type FC<P> = fn(Context<P>) -> VNode;
|
||||
|
||||
// Re-export the FC macro
|
||||
pub use crate as dioxus;
|
||||
pub use crate::nodebuilder as builder;
|
||||
pub use dioxus_core_macro::{html, rsx};
|
||||
}
|
||||
@@ -131,7 +69,6 @@ pub mod prelude {
|
||||
pub use bumpalo::Bump;
|
||||
|
||||
// Re-export the FC macro
|
||||
pub use crate as dioxus;
|
||||
pub use crate::nodebuilder as builder;
|
||||
// pub use dioxus_core_macro::fc;
|
||||
|
||||
|
||||
@@ -251,87 +251,61 @@ impl<'a> EditMachine<'a> {
|
||||
|
||||
pub fn push_temporary(&mut self, temp: u32) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: push_temporary({})", temp);
|
||||
|
||||
self.emitter.push(Edit::PushTemporary { temp });
|
||||
// self.emitter.push_temporary(temp);
|
||||
}
|
||||
|
||||
pub fn remove_child(&mut self, child: usize) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: remove_child({})", child);
|
||||
// self.emitter.remove_child(child as u32);
|
||||
|
||||
self.emitter.push(Edit::RemoveChild { n: child as u32 })
|
||||
}
|
||||
|
||||
pub fn insert_before(&mut self) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: insert_before()");
|
||||
// self.emitter.insert_before();
|
||||
|
||||
self.emitter.push(Edit::InsertBefore {})
|
||||
}
|
||||
|
||||
pub fn set_text(&mut self, text: &'a str) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: set_text({:?})", text);
|
||||
// self.emitter.set_text(text);
|
||||
self.emitter.push(Edit::SetText { text });
|
||||
// .set_text(text.as_ptr() as u32, text.len() as u32);
|
||||
}
|
||||
|
||||
pub fn remove_self_and_next_siblings(&mut self) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: remove_self_and_next_siblings()");
|
||||
self.emitter.push(Edit::RemoveSelfAndNextSiblings {});
|
||||
// self.emitter.remove_self_and_next_siblings();
|
||||
}
|
||||
|
||||
pub fn replace_with(&mut self) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: replace_with()");
|
||||
self.emitter.push(Edit::ReplaceWith {});
|
||||
// if let Some(id) = self.current_known {
|
||||
// // update mapping
|
||||
// self.emitter.push(Edit::MakeKnown{node: id});
|
||||
// self.current_known = None;
|
||||
// }
|
||||
// self.emitter.replace_with();
|
||||
self.emitter.push(Edit::ReplaceWith {});
|
||||
}
|
||||
|
||||
pub fn set_attribute(&mut self, name: &'a str, value: &'a str, is_namespaced: bool) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// todo!()
|
||||
|
||||
if name == "class" && !is_namespaced {
|
||||
// let class_id = self.ensure_string(value);
|
||||
// let class_id = self.ensure_string(value);
|
||||
// debug!("emit: set_class({:?})", value);
|
||||
// self.emitter.set_class(class_id.into());
|
||||
self.emitter.push(Edit::SetClass { class_name: value });
|
||||
} else {
|
||||
self.emitter.push(Edit::SetAttribute { name, value });
|
||||
// let name_id = self.ensure_string(name);
|
||||
// let value_id = self.ensure_string(value);
|
||||
// debug!("emit: set_attribute({:?}, {:?})", name, value);
|
||||
// self.state
|
||||
// .emitter
|
||||
// .set_attribute(name_id.into(), value_id.into());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_attribute(&mut self, name: &'a str) {
|
||||
// todo!("figure out how to get this working with ensure string");
|
||||
self.emitter.push(Edit::RemoveAttribute { name });
|
||||
// self.emitter.remove_attribute(name);
|
||||
// debug_assert!(self.traversal_is_committed());
|
||||
// // debug!("emit: remove_attribute({:?})", name);
|
||||
// let name_id = self.ensure_string(name);
|
||||
// self.emitter.remove_attribute(name_id.into());
|
||||
}
|
||||
|
||||
pub fn append_child(&mut self) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// debug!("emit: append_child()");
|
||||
self.emitter.push(Edit::AppendChild {});
|
||||
// self.emitter.append_child();
|
||||
}
|
||||
|
||||
pub fn create_text_node(&mut self, text: &'a str) {
|
||||
@@ -378,7 +352,6 @@ impl<'a> EditMachine<'a> {
|
||||
pub fn remove_event_listener(&mut self, event: &'a str) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
self.emitter.push(Edit::RemoveListener { event });
|
||||
// debug!("emit: remove_event_listener({:?})", event);
|
||||
}
|
||||
|
||||
pub fn save_known_root(&mut self, id: u32) {
|
||||
@@ -388,7 +361,6 @@ impl<'a> EditMachine<'a> {
|
||||
|
||||
pub fn load_known_root(&mut self, id: u32) {
|
||||
log::debug!("emit: TraverseToKnown({:?})", id);
|
||||
// self.current_known = Some(id);
|
||||
self.emitter.push(Edit::TraverseToKnown { node: id })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user