From 5cbdc571e3abe54391aec8f296d7389410b373b6 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 31 Aug 2021 12:28:44 -0400 Subject: [PATCH] more cleanup --- packages/core/src/bumpframe.rs | 4 +- packages/core/src/childiter.rs | 15 +---- packages/core/src/context.rs | 1 - packages/core/src/events.rs | 16 +++--- packages/core/src/hooks.rs | 2 +- packages/core/src/lib.rs | 102 ++++++++++++++++----------------- packages/core/src/scheduler.rs | 83 +++++++++++---------------- packages/core/src/scope.rs | 8 +-- packages/core/src/util.rs | 53 +++++++++++++++++ packages/core/src/yield_now.rs | 56 ------------------ 10 files changed, 148 insertions(+), 192 deletions(-) delete mode 100644 packages/core/src/yield_now.rs diff --git a/packages/core/src/bumpframe.rs b/packages/core/src/bumpframe.rs index 59a6252a5..8696d4e8e 100644 --- a/packages/core/src/bumpframe.rs +++ b/packages/core/src/bumpframe.rs @@ -2,7 +2,7 @@ use crate::innerlude::*; use bumpalo::Bump; use std::cell::Cell; -pub struct ActiveFrame { +pub(crate) struct ActiveFrame { // We use a "generation" for users of contents in the bump frames to ensure their data isn't broken pub generation: Cell, @@ -10,7 +10,7 @@ pub struct ActiveFrame { pub frames: [BumpFrame; 2], } -pub struct BumpFrame { +pub(crate) struct BumpFrame { pub bump: Bump, pub(crate) head_node: VNode<'static>, diff --git a/packages/core/src/childiter.rs b/packages/core/src/childiter.rs index 2f5ffde96..5436f9355 100644 --- a/packages/core/src/childiter.rs +++ b/packages/core/src/childiter.rs @@ -4,7 +4,7 @@ use crate::innerlude::*; /// /// This iterator is useful when it's important to load the next real root onto the top of the stack for operations like /// "InsertBefore". -pub struct RealChildIterator<'a> { +pub(crate) struct RealChildIterator<'a> { scopes: &'a ResourcePool, // Heuristcally we should never bleed into 4 completely nested fragments/components @@ -20,19 +20,6 @@ impl<'a> RealChildIterator<'a> { stack: smallvec::smallvec![(0, starter)], } } - - pub fn new_from_slice(nodes: &'a [VNode<'a>], scopes: &'a ResourcePool) -> Self { - let mut stack = smallvec::smallvec![]; - for node in nodes { - stack.push((0, node)); - } - Self { scopes, stack } - } - // keep the memory around - pub fn reset_with(&mut self, node: &'a VNode<'a>) { - self.stack.clear(); - self.stack.push((0, node)); - } } impl<'a> Iterator for RealChildIterator<'a> { diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs index 2c53384ab..903e53249 100644 --- a/packages/core/src/context.rs +++ b/packages/core/src/context.rs @@ -112,7 +112,6 @@ impl<'src, P> Context<'src, P> { } /// Get's this component's unique identifier. - /// pub fn get_scope_id(&self) -> ScopeId { self.scope.our_arena_idx.clone() } diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index a52c24f53..7360d87e4 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -6,13 +6,15 @@ use crate::innerlude::{ElementId, ScopeId}; #[derive(Debug)] -pub struct EventTrigger { +pub struct UiEvent { /// The originator of the event trigger pub scope: ScopeId, /// The optional real node associated with the trigger pub mounted_dom_id: Option, + pub listener_type: &'static str, + /// The type of event pub event: SyntheticEvent, } @@ -26,7 +28,6 @@ pub enum SyntheticEvent { FocusEvent(on::FocusEvent), FormEvent(on::FormEvent), SelectionEvent(on::SelectionEvent), - UIEvent(on::UIEvent), WheelEvent(on::WheelEvent), MediaEvent(on::MediaEvent), AnimationEvent(on::AnimationEvent), @@ -46,7 +47,6 @@ impl std::fmt::Debug for SyntheticEvent { SyntheticEvent::FormEvent(_) => "FormEvent", SyntheticEvent::SelectionEvent(_) => "SelectionEvent", SyntheticEvent::TouchEvent(_) => "TouchEvent", - SyntheticEvent::UIEvent(_) => "UIEvent", SyntheticEvent::WheelEvent(_) => "WheelEvent", SyntheticEvent::MediaEvent(_) => "MediaEvent", SyntheticEvent::AnimationEvent(_) => "AnimationEvent", @@ -284,6 +284,9 @@ pub mod on { /// onmouseout onmouseout + /// + onscroll + /// onmouseover /// /// Triggered when the users's mouse hovers over an element. @@ -331,14 +334,9 @@ pub mod on { ontouchstart ]; - UIEventInner(UIEvent): [ - /// - scroll - ]; - WheelEventInner(WheelEvent): [ /// - wheel + onwheel ]; MediaEventInner(MediaEvent): [ diff --git a/packages/core/src/hooks.rs b/packages/core/src/hooks.rs index b8808993e..86f7b4b4f 100644 --- a/packages/core/src/hooks.rs +++ b/packages/core/src/hooks.rs @@ -13,7 +13,7 @@ use crate::innerlude::*; use futures_util::FutureExt; use std::{ any::{Any, TypeId}, - cell::{Cell, RefCell}, + cell::RefCell, future::Future, rc::Rc, }; diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index 6b8a2909d..aa604f0ab 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -1,65 +1,16 @@ #![allow(non_snake_case)] #![doc = include_str!("../README.md")] -pub use crate::innerlude::{ - format_args_f, html, rsx, Context, DiffInstruction, DioxusElement, DomEdit, DomTree, ElementId, - EventPriority, EventTrigger, LazyNodes, MountType, Mutations, NodeFactory, Properties, ScopeId, - SuspendedContext, SyntheticEvent, VNode, VirtualDom, FC, -}; - -pub mod prelude { - pub use crate::component::{fc_to_builder, Fragment, Properties}; - pub use crate::context::Context; - pub use crate::hooks::*; - pub use crate::innerlude::{DioxusElement, DomTree, LazyNodes, Mutations, NodeFactory, FC}; - pub use crate::nodes::VNode; - pub use crate::VirtualDom; - pub use dioxus_core_macro::{format_args_f, html, rsx, Props}; -} - -pub(crate) mod innerlude { - pub use crate::bumpframe::*; - pub use crate::childiter::*; - pub use crate::component::*; - pub use crate::context::*; - pub use crate::diff::*; - pub use crate::diff_stack::*; - pub use crate::events::*; - pub use crate::heuristics::*; - pub use crate::hooklist::*; - pub use crate::hooks::*; - pub use crate::mutations::*; - pub use crate::nodes::*; - pub use crate::scheduler::*; - pub use crate::scope::*; - pub use crate::util::*; - pub use crate::virtual_dom::*; - pub use crate::yield_now::*; - - pub type DomTree<'a> = Option>; - pub type FC

= fn(Context

) -> DomTree; - - pub use dioxus_core_macro::{format_args_f, html, rsx}; -} - -pub mod exports { - //! Important dependencies that are used by the rest of the library - // the foundation of this library - pub use bumpalo; -} - /* Navigating this crate: - virtual_dom: the primary entrypoint for the crate - scheduler: the core interior logic called by virtual_dom - nodes: the definition of VNodes, listeners, etc. -- - +- diff: the stackmachine-based diffing algorithm +- hooks: foundational hooks that require crate-private APIs +- mutations: DomEdits/NodeRefs and internal API to create them Some utilities - - - */ pub mod bumpframe; pub mod childiter; @@ -78,4 +29,49 @@ pub mod scope; pub mod signals; pub mod util; pub mod virtual_dom; -pub mod yield_now; + +pub(crate) mod innerlude { + pub(crate) use crate::bumpframe::*; + pub(crate) use crate::childiter::*; + pub use crate::component::*; + pub use crate::context::*; + pub(crate) use crate::diff::*; + pub use crate::diff_stack::*; + pub use crate::events::*; + pub use crate::heuristics::*; + pub use crate::hooklist::*; + pub use crate::hooks::*; + pub use crate::mutations::*; + pub use crate::nodes::*; + pub use crate::scheduler::*; + pub use crate::scope::*; + pub use crate::util::*; + pub use crate::virtual_dom::*; + + pub type DomTree<'a> = Option>; + pub type FC

= fn(Context

) -> DomTree; + + pub use dioxus_core_macro::{format_args_f, html, rsx}; +} + +pub use crate::innerlude::{ + format_args_f, html, rsx, Context, DiffInstruction, DioxusElement, DomEdit, DomTree, ElementId, + EventPriority, LazyNodes, MountType, Mutations, NodeFactory, Properties, ScopeId, + SuspendedContext, SyntheticEvent, UiEvent, VNode, VirtualDom, FC, +}; + +pub mod prelude { + pub use crate::component::{fc_to_builder, Fragment, Properties}; + pub use crate::context::Context; + pub use crate::hooks::*; + pub use crate::innerlude::{DioxusElement, DomTree, LazyNodes, Mutations, NodeFactory, FC}; + pub use crate::nodes::VNode; + pub use crate::VirtualDom; + pub use dioxus_core_macro::{format_args_f, html, rsx, Props}; +} + +pub mod exports { + //! Important dependencies that are used by the rest of the library + // the foundation of this library + pub use bumpalo; +} diff --git a/packages/core/src/scheduler.rs b/packages/core/src/scheduler.rs index ba5ad4f10..a1a778a84 100644 --- a/packages/core/src/scheduler.rs +++ b/packages/core/src/scheduler.rs @@ -97,7 +97,7 @@ pub struct EventChannel { pub enum SchedulerMsg { Immediate(ScopeId), - UiEvent(EventTrigger), + UiEvent(UiEvent), SubmitTask(FiberTask, u64), ToggleTask(u64), PauseTask(u64), @@ -140,11 +140,11 @@ pub(crate) struct Scheduler { // scheduler stuff pub current_priority: EventPriority, - pub ui_events: VecDeque, + pub ui_events: VecDeque, pub pending_immediates: VecDeque, - pub pending_tasks: VecDeque, + pub pending_tasks: VecDeque, pub garbage_scopes: HashSet, @@ -248,39 +248,37 @@ impl Scheduler { // Converts UI events into dirty scopes with various priorities pub fn consume_pending_events(&mut self) { - // while let Some(trigger) = self.ui_events.pop_back() { - // match &trigger.event { - // SyntheticEvent::ClipboardEvent(_) - // | SyntheticEvent::CompositionEvent(_) - // | SyntheticEvent::KeyboardEvent(_) - // | SyntheticEvent::FocusEvent(_) - // | SyntheticEvent::FormEvent(_) - // | SyntheticEvent::SelectionEvent(_) - // | SyntheticEvent::TouchEvent(_) - // | SyntheticEvent::UIEvent(_) - // | SyntheticEvent::WheelEvent(_) - // | SyntheticEvent::MediaEvent(_) - // | SyntheticEvent::AnimationEvent(_) - // | SyntheticEvent::TransitionEvent(_) - // | SyntheticEvent::ToggleEvent(_) - // | SyntheticEvent::MouseEvent(_) - // | SyntheticEvent::PointerEvent(_) => { - // if let Some(scope) = self.get_scope_mut(trigger.scope) { - // if let Some(element) = trigger.mounted_dom_id { - // scope.call_listener(trigger.event, element)?; + while let Some(trigger) = self.ui_events.pop_back() { + if let Some(scope) = self.pool.get_scope_mut(trigger.scope) { + if let Some(element) = trigger.mounted_dom_id { + let priority = match &trigger.event { + SyntheticEvent::ClipboardEvent(_) => {} + SyntheticEvent::CompositionEvent(_) => {} + SyntheticEvent::KeyboardEvent(_) => {} + SyntheticEvent::FocusEvent(_) => {} + SyntheticEvent::FormEvent(_) => {} + SyntheticEvent::SelectionEvent(_) => {} + SyntheticEvent::TouchEvent(_) => {} + SyntheticEvent::WheelEvent(_) => {} + SyntheticEvent::MediaEvent(_) => {} + SyntheticEvent::AnimationEvent(_) => {} + SyntheticEvent::TransitionEvent(_) => {} + SyntheticEvent::ToggleEvent(_) => {} + SyntheticEvent::MouseEvent(_) => {} + SyntheticEvent::PointerEvent(_) => {} + }; - // // let receiver = self.immediate_receiver.clone(); - // // let mut receiver = receiver.borrow_mut(); + scope.call_listener(trigger.event, element); + // let receiver = self.immediate_receiver.clone(); + // let mut receiver = receiver.borrow_mut(); - // // // Drain the immediates into the dirty scopes, setting the appropiate priorities - // // while let Ok(Some(dirty_scope)) = receiver.try_next() { - // // self.add_dirty_scope(dirty_scope, trigger.priority) - // // } - // } - // } - // } - // } - // } + // // Drain the immediates into the dirty scopes, setting the appropiate priorities + // while let Ok(Some(dirty_scope)) = receiver.try_next() { + // self.add_dirty_scope(dirty_scope, trigger.priority) + // } + } + } + } } // nothing to do, no events on channels, no work @@ -293,26 +291,13 @@ impl Scheduler { } pub fn has_work(&self) -> bool { - todo!() - // self.high_priorty.has_work() - // || self.medium_priority.has_work() - // || self.low_priority.has_work() + self.lanes.iter().find(|f| f.has_work()).is_some() } pub fn has_pending_garbage(&self) -> bool { !self.garbage_scopes.is_empty() } - fn get_current_fiber<'a>(&'a mut self) -> &mut DiffMachine<'a> { - todo!() - // let fib = match self.current_priority { - // EventPriority::High => &mut self.high_priorty, - // EventPriority::Medium => &mut self.medium_priority, - // EventPriority::Low => &mut self.low_priority, - // }; - // unsafe { std::mem::transmute(fib) } - } - fn shift_priorities(&mut self) { self.current_priority = match ( self.lanes[0].has_work(), @@ -634,7 +619,7 @@ pub enum EventPriority { } #[derive(Clone)] -pub struct ResourcePool { +pub(crate) struct ResourcePool { /* This *has* to be an UnsafeCell. diff --git a/packages/core/src/scope.rs b/packages/core/src/scope.rs index c9350b6de..5dc02e790 100644 --- a/packages/core/src/scope.rs +++ b/packages/core/src/scope.rs @@ -195,11 +195,7 @@ impl Scope { // A safe wrapper around calling listeners // // - pub(crate) fn call_listener( - &mut self, - event: SyntheticEvent, - element: ElementId, - ) -> Option<()> { + pub(crate) fn call_listener(&mut self, event: SyntheticEvent, element: ElementId) { let listners = self.listeners.borrow_mut(); let raw_listener = listners.iter().find(|lis| { @@ -222,8 +218,6 @@ impl Scope { } else { log::warn!("An event was triggered but there was no listener to handle it"); } - - Some(()) } pub fn root(&self) -> &VNode { diff --git a/packages/core/src/util.rs b/packages/core/src/util.rs index fc406b0a2..d2df10eab 100644 --- a/packages/core/src/util.rs +++ b/packages/core/src/util.rs @@ -11,3 +11,56 @@ pub fn empty_cell() -> Cell> { pub fn type_name_of(_: T) -> &'static str { std::any::type_name::() } + +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +// use crate::task::{Context, Poll}; + +/// Cooperatively gives up a timeslice to the task scheduler. +/// +/// Calling this function will move the currently executing future to the back +/// of the execution queue, making room for other futures to execute. This is +/// especially useful after running CPU-intensive operations inside a future. +/// +/// See also [`task::spawn_blocking`]. +/// +/// [`task::spawn_blocking`]: fn.spawn_blocking.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// # async_std::task::block_on(async { +/// # +/// use async_std::task; +/// +/// task::yield_now().await; +/// # +/// # }) +/// ``` +#[inline] +pub async fn yield_now() { + YieldNow(false).await +} + +struct YieldNow(bool); + +impl Future for YieldNow { + type Output = (); + + // The futures executor is implemented as a FIFO queue, so all this future + // does is re-schedule the future back to the end of the queue, giving room + // for other futures to progress. + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if !self.0 { + self.0 = true; + cx.waker().wake_by_ref(); + Poll::Pending + } else { + Poll::Ready(()) + } + } +} diff --git a/packages/core/src/yield_now.rs b/packages/core/src/yield_now.rs deleted file mode 100644 index 8fef0848e..000000000 --- a/packages/core/src/yield_now.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Utility Code taken from async_std to immediately yield the current task to the executor. -//! -//! - -use std::future::Future; -use std::pin::Pin; -use std::task::{Context, Poll}; - -// use crate::task::{Context, Poll}; - -/// Cooperatively gives up a timeslice to the task scheduler. -/// -/// Calling this function will move the currently executing future to the back -/// of the execution queue, making room for other futures to execute. This is -/// especially useful after running CPU-intensive operations inside a future. -/// -/// See also [`task::spawn_blocking`]. -/// -/// [`task::spawn_blocking`]: fn.spawn_blocking.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// # async_std::task::block_on(async { -/// # -/// use async_std::task; -/// -/// task::yield_now().await; -/// # -/// # }) -/// ``` -#[inline] -pub async fn yield_now() { - YieldNow(false).await -} - -struct YieldNow(bool); - -impl Future for YieldNow { - type Output = (); - - // The futures executor is implemented as a FIFO queue, so all this future - // does is re-schedule the future back to the end of the queue, giving room - // for other futures to progress. - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - if !self.0 { - self.0 = true; - cx.waker().wake_by_ref(); - Poll::Pending - } else { - Poll::Ready(()) - } - } -}