Skip to content

Commit

Permalink
perf(core): ⚡️ pipe lazy calc
Browse files Browse the repository at this point in the history
  • Loading branch information
M-Adoo committed Sep 25, 2023
1 parent fb9e68f commit fa4b663
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 366 deletions.
23 changes: 13 additions & 10 deletions core/src/builtin_widgets/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ define_widget_context!(LifecycleEvent);

pub type LifecycleSubject = MutRefItemSubject<'static, AllLifecycle, Infallible>;

#[derive(Declare2, Default)]
#[derive(Default)]
pub struct LifecycleListener {
#[declare(skip)]
lifecycle: LifecycleSubject,
}

Expand Down Expand Up @@ -42,7 +41,17 @@ macro_rules! match_closure {
};
}

impl LifecycleListenerDeclarer2 {
impl Declare2 for LifecycleListener {
type Builder = Self;
fn declare2_builder() -> Self::Builder { Self::default() }
}

impl DeclareBuilder for LifecycleListener {
type Target = State<Self>;
fn build_declare(self, _: &BuildCtx) -> Self::Target { State::value(self) }
}

impl LifecycleListener {
pub fn on_mounted(mut self, handler: impl FnMut(&mut LifecycleEvent) + 'static) -> Self {
let _ = self
.subject()
Expand Down Expand Up @@ -72,13 +81,7 @@ impl LifecycleListenerDeclarer2 {
self
}

fn subject(&mut self) -> LifecycleSubject {
self
.lifecycle
.get_or_insert_with(DeclareInit::default)
.value()
.clone()
}
fn subject(&mut self) -> LifecycleSubject { self.lifecycle.clone() }
}

impl_query_self_only!(LifecycleListener);
Expand Down
27 changes: 8 additions & 19 deletions core/src/declare.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{context::BuildCtx, prelude::Pipe, state::ModifyScope};
use crate::{context::BuildCtx, pipe::Pipe, state::ModifyScope};
use rxrust::ops::box_it::BoxOp;
use std::convert::Infallible;

Expand All @@ -21,7 +21,7 @@ pub trait DeclareBuilder {
/// The type use to store the init value of the field when declare a object.
pub enum DeclareInit<V> {
Value(V),
Pipe(Pipe<V>),
Pipe(Box<dyn Pipe<Value = V>>),
}

type ValueStream<V> = BoxOp<'static, (ModifyScope, V), Infallible>;
Expand All @@ -31,25 +31,11 @@ impl<V: 'static> DeclareInit<V> {
match self {
Self::Value(v) => (v, None),
Self::Pipe(v) => {
let (v, pipe) = v.unzip();
let (v, pipe) = v.box_unzip();
(v, Some(pipe))
}
}
}

pub fn value(&self) -> &V {
match self {
Self::Value(v) => v,
Self::Pipe(v) => v.value(),
}
}

pub fn value_mut(&mut self) -> &mut V {
match self {
Self::Value(v) => v,
Self::Pipe(v) => v.value_mut(),
}
}
}

impl<T: Default> Default for DeclareInit<T> {
Expand All @@ -66,9 +52,12 @@ impl<V, U: From<V>> DeclareFrom<V, ()> for DeclareInit<U> {
fn declare_from(value: V) -> Self { Self::Value(value.into()) }
}

impl<V: 'static, U: From<V> + 'static> DeclareFrom<Pipe<V>, Pipe<()>> for DeclareInit<U> {
impl<P: Pipe + 'static, V> DeclareFrom<P, &dyn Pipe<Value = ()>> for DeclareInit<V>
where
V: From<P::Value> + 'static,
{
#[inline]
fn declare_from(value: Pipe<V>) -> Self { Self::Pipe(value.map(U::from)) }
fn declare_from(value: P) -> Self { Self::Pipe(Box::new(Pipe::map(value, |v| v.into()))) }
}

/// struct help the generate code have better type hint.
Expand Down
22 changes: 15 additions & 7 deletions core/src/events/listener_impl_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,30 @@ macro_rules! impl_listener {
($doc: literal, $name: ident, $event_ty: ident) => {
paste::paste! {
#[doc= $doc]
#[derive(Declare2)]
pub struct [<$name Listener>]{
#[declare(skip)]
pub struct [<$name Listener>]{
[<$name:snake _subject>]: [<$name Subject>]
}

impl [<$name ListenerDeclarer2>] {
impl [<$name Listener>] {
fn subject(&mut self) -> [<$name Subject>] {
self
.[<$name:snake _subject>]
.get_or_insert_with(DeclareInit::default)
.value()
.clone()
}
}

impl Declare2 for [<$name Listener>] {
type Builder = Self;
fn declare2_builder() -> Self::Builder {
Self { [<$name:snake _subject>]: Default::default()}
}
}

impl DeclareBuilder for [<$name Listener>] {
type Target = State<Self>;
fn build_declare(self, _ctx: &BuildCtx) -> Self::Target { State::value(self) }
}

impl [<$name Listener>] {
/// Convert a observable stream of this event.
pub fn [<$name:snake _stream>](&self) -> [<$name Subject>] {
Expand Down Expand Up @@ -89,7 +97,7 @@ macro_rules! impl_multi_event_listener {
impl_all_event!($name, $($on_doc, $event_ty),+);
impl_listener!($doc, $name, [<All $name>]);

impl [<$name ListenerDeclarer2>] {
impl [<$name Listener>] {
$(
#[doc = "Sets up a function that will be called whenever the `" $event_ty "` is delivered"]
pub fn [<on_ $event_ty:snake>](
Expand Down
44 changes: 1 addition & 43 deletions core/src/events/pointers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ fn x_times_tap_map_filter(
}
}

impl PointerListenerDeclarer2 {
impl PointerListener {
pub fn on_double_tap(self, handler: impl FnMut(&mut PointerEvent) + 'static) -> Self {
self.on_x_times_tap((2, handler))
}
Expand Down Expand Up @@ -207,48 +207,6 @@ impl PointerListenerDeclarer2 {
}
}

impl PointerListener {
pub fn on_double_tap(self, handler: impl FnMut(&mut PointerEvent) + 'static) {
self.on_x_times_tap((2, handler))
}

pub fn on_double_tap_capture(self, handler: impl FnMut(&mut PointerEvent) + 'static) {
self.on_x_times_tap_capture((2, handler))
}

pub fn on_triple_tap(self, handler: impl FnMut(&mut PointerEvent) + 'static) {
self.on_x_times_tap((3, handler))
}

pub fn on_triple_tap_capture(self, handler: impl FnMut(&mut PointerEvent) + 'static) {
self.on_x_times_tap_capture((3, handler))
}

pub fn on_x_times_tap(self, (times, handler): (usize, impl FnMut(&mut PointerEvent) + 'static)) {
self.on_x_times_tap_impl(times, MULTI_TAP_DURATION, false, handler);
}

pub fn on_x_times_tap_capture(
self,
(times, handler): (usize, impl FnMut(&mut PointerEvent) + 'static),
) {
self.on_x_times_tap_impl(times, MULTI_TAP_DURATION, true, handler);
}

fn on_x_times_tap_impl(
&self,
x: usize,
dur: Duration,
capture: bool,
handler: impl FnMut(&mut PointerEvent) + 'static,
) {
self
.pointer_stream()
.filter_map(x_times_tap_map_filter(x, dur, capture))
.subscribe(handler);
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub mod prelude {
#[doc(no_inline)]
pub use crate::events::*;
#[doc(no_inline)]
pub use crate::pipe::Pipe;
pub use crate::pipe::{FinalChain, MapPipe, ModifiesPipe, Pipe};
#[doc(no_inline)]
pub use crate::state::*;
#[doc(no_inline)]
Expand Down
Loading

0 comments on commit fa4b663

Please sign in to comment.