wip: more refactor for async
This commit is contained in:
1 parent
8cfc437bfe
commit
975fa566f9
18 files changed
+110
-122
No files matched your search
@@ -368,7 +368,7 @@ mod root {
|
||||
|
||||
mod hooks {
|
||||
use super::*;
|
||||
use dioxus_core::{hooks::use_ref, prelude::Context};
|
||||
use dioxus_core::prelude::Context;
|
||||
|
||||
pub fn use_init_recoil_root<P>(cx: Context<P>, cfg: impl Fn(())) {
|
||||
cx.use_create_context(move || RefCell::new(RecoilRoot::new()))
|
||||
|
||||
@@ -147,18 +147,18 @@ impl<'src, P> Context<'src, P> {
|
||||
cleanup: impl FnOnce(InternalHookState),
|
||||
) -> Output {
|
||||
// If the idx is the same as the hook length, then we need to add the current hook
|
||||
if self.scope.hooks.is_finished() {
|
||||
if self.scope.hooks.at_end() {
|
||||
let new_state = initializer();
|
||||
self.scope.hooks.push(Box::new(new_state));
|
||||
self.scope.hooks.push(new_state);
|
||||
}
|
||||
|
||||
let state = self.scope.hooks.next::<InternalHookState>().expect(
|
||||
r###"
|
||||
Unable to retrive the hook that was initialized in this index.
|
||||
Consult the `rules of hooks` to understand how to use hooks properly.
|
||||
|
||||
You likely used the hook in a conditional. Hooks rely on consistent ordering between renders.
|
||||
Any function prefixed with "use" should not be called conditionally.
|
||||
Unable to retrive the hook that was initialized in this index.
|
||||
Consult the `rules of hooks` to understand how to use hooks properly.
|
||||
|
||||
You likely used the hook in a conditional. Hooks rely on consistent ordering between renders.
|
||||
Any function prefixed with "use" should not be called conditionally.
|
||||
"###,
|
||||
);
|
||||
|
||||
@@ -299,16 +299,8 @@ Any function prefixed with "use" should not be called conditionally.
|
||||
///
|
||||
///
|
||||
///
|
||||
pub fn submit_task(
|
||||
&self,
|
||||
mut task: &'src mut DTask<'src>,
|
||||
// mut task: &'src mut Pin<Box<dyn Future<Output = ()> + 'static>>,
|
||||
) -> TaskHandle {
|
||||
pub fn submit_task(&self, mut task: &'src mut DTask<'src>) -> TaskHandle {
|
||||
self.tasks.push(task);
|
||||
// let mut g = self.task.borrow_mut();
|
||||
// *g = Some(task);
|
||||
// the pointer to the task is stable - we guarantee stability of all &'src references
|
||||
// let task_ptr = task as *mut _;
|
||||
|
||||
TaskHandle { _p: PhantomData {} }
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//! 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::SharedArena, innerlude::*};
|
||||
use crate::{arena::SharedArena, innerlude::*, tasks::TaskQueue};
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
|
||||
use std::{
|
||||
@@ -94,6 +94,7 @@ pub trait RealDom<'a> {
|
||||
pub struct DiffMachine<'real, 'bump, Dom: RealDom<'bump>> {
|
||||
pub dom: &'real mut Dom,
|
||||
pub components: &'bump SharedArena,
|
||||
pub task_queue: &'bump TaskQueue,
|
||||
pub cur_idx: ScopeIdx,
|
||||
pub diffed: FxHashSet<ScopeIdx>,
|
||||
pub event_queue: EventQueue,
|
||||
@@ -106,12 +107,14 @@ impl<'real, 'bump, Dom: RealDom<'bump>> DiffMachine<'real, 'bump, Dom> {
|
||||
components: &'bump SharedArena,
|
||||
cur_idx: ScopeIdx,
|
||||
event_queue: EventQueue,
|
||||
task_queue: &'bump TaskQueue,
|
||||
) -> Self {
|
||||
Self {
|
||||
components,
|
||||
dom,
|
||||
cur_idx,
|
||||
event_queue,
|
||||
task_queue,
|
||||
diffed: FxHashSet::default(),
|
||||
seen_nodes: FxHashSet::default(),
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ impl HookList {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_finished(&self) -> bool {
|
||||
self.idx.get() == self.vals.len()
|
||||
pub(crate) fn at_end(&self) -> bool {
|
||||
self.cur_idx() >= self.len()
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@ pub mod prelude {
|
||||
use crate::nodes;
|
||||
pub use crate::styles::{AsAttr, StyleBuilder};
|
||||
|
||||
pub use crate::util::RealDomNode;
|
||||
pub use nodes::*;
|
||||
|
||||
pub use crate::nodebuilder::LazyNodes;
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::{
|
||||
innerlude::{Context, Properties, RealDom, RealDomNode, Scope, ScopeIdx, FC},
|
||||
nodebuilder::{text3, NodeFactory},
|
||||
};
|
||||
use appendlist::AppendList;
|
||||
use bumpalo::Bump;
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
@@ -417,19 +418,25 @@ impl<'a> VComponent<'a> {
|
||||
type Captured<'a> = Rc<dyn for<'r> Fn(&'r Scope) -> VNode<'r> + 'a>;
|
||||
|
||||
fn create_closure<'a, P: 'a>(
|
||||
component: FC<P>,
|
||||
user_component: FC<P>,
|
||||
raw_props: *const (),
|
||||
) -> Rc<dyn for<'r> Fn(&'r Scope) -> VNode<'r>> {
|
||||
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 tasks = AppendList::new();
|
||||
let cx: Context<P> = Context {
|
||||
props: safe_props,
|
||||
scope: scp,
|
||||
tasks: todo!(),
|
||||
tasks: &tasks,
|
||||
};
|
||||
|
||||
let g = component(cx);
|
||||
let g = user_component(cx);
|
||||
|
||||
// collect the submitted tasks
|
||||
println!("tasks submittted: {:#?}", tasks.len());
|
||||
// log::debug!("tasks submittted: {:#?}", tasks.len());
|
||||
|
||||
let g2 = unsafe { std::mem::transmute(g) };
|
||||
g2
|
||||
});
|
||||
|
||||
@@ -39,15 +39,15 @@ impl TaskQueue {
|
||||
Self { slots, submitter }
|
||||
}
|
||||
|
||||
fn push_task(&mut self, task: DTask) -> TaskHandle {
|
||||
pub fn submit_task(&mut self, task: DTask) -> TaskHandle {
|
||||
let key = self.slots.write().unwrap().insert(task);
|
||||
TaskHandle {}
|
||||
TaskHandle { key }
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.slots.read().unwrap().is_empty()
|
||||
}
|
||||
fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.slots.read().unwrap().len()
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,9 @@ impl Stream for TaskQueue {
|
||||
}
|
||||
}
|
||||
|
||||
struct TaskHandle {}
|
||||
pub struct TaskHandle {
|
||||
key: DefaultKey,
|
||||
}
|
||||
|
||||
pub struct DTask {
|
||||
fut: *mut Pin<Box<dyn Future<Output = ()>>>,
|
||||
@@ -114,7 +116,7 @@ impl DTask {
|
||||
dead: Cell::new(false),
|
||||
}
|
||||
}
|
||||
fn debug_new(fut: &mut Pin<Box<dyn Future<Output = ()>>>) -> Self {
|
||||
pub fn debug_new(fut: &mut Pin<Box<dyn Future<Output = ()>>>) -> Self {
|
||||
let originator = ScopeIdx::default();
|
||||
Self {
|
||||
fut,
|
||||
@@ -154,9 +156,9 @@ mod tests {
|
||||
}) as RawTask);
|
||||
|
||||
let mut queue = TaskQueue::new();
|
||||
queue.push_task(DTask::debug_new(f1));
|
||||
queue.push_task(DTask::debug_new(f2));
|
||||
queue.push_task(DTask::debug_new(f3));
|
||||
queue.submit_task(DTask::debug_new(f1));
|
||||
queue.submit_task(DTask::debug_new(f2));
|
||||
queue.submit_task(DTask::debug_new(f3));
|
||||
|
||||
while !queue.is_empty() {
|
||||
let next = queue.next().await;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
use crate::tasks::TaskQueue;
|
||||
use crate::{arena::SharedArena, innerlude::*};
|
||||
use appendlist::AppendList;
|
||||
use slotmap::DefaultKey;
|
||||
use slotmap::SlotMap;
|
||||
use std::{any::TypeId, fmt::Debug, rc::Rc};
|
||||
@@ -130,16 +131,29 @@ impl VirtualDom {
|
||||
|
||||
// Normally, a component would be passed as a child in the RSX macro which automatically produces OpaqueComponents
|
||||
// Here, we need to make it manually, using an RC to force the Weak reference to stick around for the main scope.
|
||||
let _root_caller: Rc<WrappedCaller> = Rc::new(move |scope| {
|
||||
let _root_caller: Rc<WrappedCaller> = Rc::new(move |scope: &Scope| {
|
||||
// let _root_caller: Rc<OpaqueComponent<'static>> = Rc::new(move |scope| {
|
||||
// the lifetime of this closure is just as long as the lifetime on the scope reference
|
||||
// this closure moves root props (which is static) into this closure
|
||||
let props = unsafe { &*(&root_props as *const _) };
|
||||
root(Context {
|
||||
let tasks = AppendList::new();
|
||||
let t2 = &tasks;
|
||||
|
||||
let cx = Context {
|
||||
props,
|
||||
scope,
|
||||
tasks: todo!(),
|
||||
})
|
||||
tasks: t2,
|
||||
};
|
||||
let nodes = root(cx);
|
||||
|
||||
log::debug!("There were {:?} tasks submitted", tasks.len());
|
||||
// cast a weird lifetime to shake the appendlist thing
|
||||
// TODO: move all of this into the same logic that governs other components
|
||||
// we want to wrap everything in a dioxus root component
|
||||
unsafe { std::mem::transmute(nodes) }
|
||||
// std::mem::drop(tasks);
|
||||
//
|
||||
// nodes
|
||||
});
|
||||
|
||||
// Create a weak reference to the OpaqueComponent for the root scope to use as its render function
|
||||
@@ -185,6 +199,7 @@ impl VirtualDom {
|
||||
&self.components,
|
||||
self.base_scope,
|
||||
self.event_queue.clone(),
|
||||
&self.tasks,
|
||||
);
|
||||
|
||||
// Schedule an update and then immediately call it on the root component
|
||||
@@ -251,8 +266,13 @@ impl VirtualDom {
|
||||
|
||||
self.components.try_get_mut(id)?.call_listener(trigger)?;
|
||||
|
||||
let mut diff_machine =
|
||||
DiffMachine::new(realdom, &self.components, id, self.event_queue.clone());
|
||||
let mut diff_machine = DiffMachine::new(
|
||||
realdom,
|
||||
&self.components,
|
||||
id,
|
||||
self.event_queue.clone(),
|
||||
&self.tasks,
|
||||
);
|
||||
|
||||
self.progress_completely(&mut diff_machine)?;
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ struct UseStateInner<T: 'static> {
|
||||
update_scheuled: Cell<bool>,
|
||||
callback: Rc<dyn Fn()>,
|
||||
wip: RefCell<Option<T>>,
|
||||
updater:
|
||||
}
|
||||
|
||||
pub struct UseState<'a, T: 'static> {
|
||||
@@ -109,7 +108,7 @@ impl<'a, T: 'static> UseState<'a, T> {
|
||||
}
|
||||
|
||||
pub fn classic(self) -> (&'a T, &'a Rc<dyn Fn(T)>) {
|
||||
(&self.inner.current_val)
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
impl<'a, T: 'static + ToOwned<Owned = T>> UseState<'a, T> {
|
||||
|
||||
+5
-10
@@ -2,8 +2,7 @@ use std::{collections::HashMap, rc::Rc, sync::Arc};
|
||||
|
||||
use dioxus_core::{
|
||||
events::{EventTrigger, VirtualEvent},
|
||||
prelude::ScopeIdx,
|
||||
virtual_dom::RealDomNode,
|
||||
prelude::{RealDomNode, ScopeIdx},
|
||||
};
|
||||
use fxhash::FxHashMap;
|
||||
use slotmap::{DefaultKey, Key, KeyData};
|
||||
@@ -72,7 +71,7 @@ impl WebsysDom {
|
||||
}
|
||||
|
||||
impl<'a> dioxus_core::diff::RealDom<'a> for WebsysDom {
|
||||
fn push_root(&mut self, root: dioxus_core::virtual_dom::RealDomNode) {
|
||||
fn push_root(&mut self, root: RealDomNode) {
|
||||
log::debug!("Called [push_root] {:?}", root);
|
||||
let key: DefaultKey = KeyData::from_ffi(root.0).into();
|
||||
let domnode = self.nodes.get(key).expect("Failed to pop know root");
|
||||
@@ -150,7 +149,7 @@ impl<'a> dioxus_core::diff::RealDom<'a> for WebsysDom {
|
||||
fn create_placeholder(&mut self) -> RealDomNode {
|
||||
self.create_element("pre", None)
|
||||
}
|
||||
fn create_text_node(&mut self, text: &str) -> dioxus_core::virtual_dom::RealDomNode {
|
||||
fn create_text_node(&mut self, text: &str) -> RealDomNode {
|
||||
// let nid = self.node_counter.next();
|
||||
let textnode = self
|
||||
.document
|
||||
@@ -166,11 +165,7 @@ impl<'a> dioxus_core::diff::RealDom<'a> for WebsysDom {
|
||||
RealDomNode::new(nid)
|
||||
}
|
||||
|
||||
fn create_element(
|
||||
&mut self,
|
||||
tag: &str,
|
||||
ns: Option<&'static str>,
|
||||
) -> dioxus_core::virtual_dom::RealDomNode {
|
||||
fn create_element(&mut self, tag: &str, ns: Option<&'static str>) -> RealDomNode {
|
||||
let tag = wasm_bindgen::intern(tag);
|
||||
let el = match ns {
|
||||
Some(ns) => self
|
||||
@@ -587,7 +582,7 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<EventTrigger> {
|
||||
Ok(EventTrigger::new(
|
||||
virtual_event_from_websys_event(event),
|
||||
triggered_scope,
|
||||
real_id,
|
||||
Some(real_id),
|
||||
dioxus_core::events::EventPriority::High,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core::{
|
||||
diff::RealDom,
|
||||
serialize::DomEdit,
|
||||
virtual_dom::{RealDomNode, VirtualDom},
|
||||
};
|
||||
use dioxus_core::{diff::RealDom, serialize::DomEdit, virtual_dom::VirtualDom};
|
||||
use DomEdit::*;
|
||||
|
||||
pub struct WebviewRegistry {}
|
||||
@@ -37,7 +33,7 @@ impl WebviewDom<'_> {
|
||||
}
|
||||
}
|
||||
impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
|
||||
fn push_root(&mut self, root: dioxus_core::virtual_dom::RealDomNode) {
|
||||
fn push_root(&mut self, root: RealDomNode) {
|
||||
self.edits.push(PushRoot { root: root.0 });
|
||||
}
|
||||
|
||||
@@ -57,18 +53,14 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
|
||||
self.edits.push(RemoveAllChildren);
|
||||
}
|
||||
|
||||
fn create_text_node(&mut self, text: &'bump str) -> dioxus_core::virtual_dom::RealDomNode {
|
||||
fn create_text_node(&mut self, text: &'bump str) -> RealDomNode {
|
||||
self.node_counter += 1;
|
||||
let id = RealDomNode::new(self.node_counter);
|
||||
self.edits.push(CreateTextNode { text, id: id.0 });
|
||||
id
|
||||
}
|
||||
|
||||
fn create_element(
|
||||
&mut self,
|
||||
tag: &'bump str,
|
||||
ns: Option<&'bump str>,
|
||||
) -> dioxus_core::virtual_dom::RealDomNode {
|
||||
fn create_element(&mut self, tag: &'bump str, ns: Option<&'bump str>) -> RealDomNode {
|
||||
self.node_counter += 1;
|
||||
let id = RealDomNode::new(self.node_counter);
|
||||
match ns {
|
||||
@@ -78,7 +70,7 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
|
||||
id
|
||||
}
|
||||
|
||||
fn create_placeholder(&mut self) -> dioxus_core::virtual_dom::RealDomNode {
|
||||
fn create_placeholder(&mut self) -> RealDomNode {
|
||||
self.node_counter += 1;
|
||||
let id = RealDomNode::new(self.node_counter);
|
||||
self.edits.push(CreatePlaceholder { id: id.0 });
|
||||
@@ -90,7 +82,7 @@ impl<'bump> RealDom<'bump> for WebviewDom<'bump> {
|
||||
event: &'static str,
|
||||
scope: dioxus_core::prelude::ScopeIdx,
|
||||
element_id: usize,
|
||||
realnode: dioxus_core::virtual_dom::RealDomNode,
|
||||
realnode: RealDomNode,
|
||||
) {
|
||||
self.edits.push(NewEventListener {
|
||||
scope,
|
||||
|
||||
Reference in new issue
Block a user