@@ -18,10 +18,14 @@ use std::{
18
18
task:: { Context , Poll } ,
19
19
} ;
20
20
21
+ use eyeball:: Subscriber ;
22
+ use eyeball_im:: { VectorDiff , VectorSubscriberBatchedStream } ;
23
+ use eyeball_im_util:: vector:: { Skip , VectorObserverExt } ;
21
24
use futures_core:: Stream ;
25
+ use imbl:: Vector ;
22
26
use pin_project_lite:: pin_project;
23
27
24
- use super :: TimelineDropHandle ;
28
+ use super :: { controller :: ObservableItems , item :: TimelineItem , TimelineDropHandle } ;
25
29
26
30
pin_project ! {
27
31
/// A stream that wraps a [`TimelineDropHandle`] so that the `Timeline`
@@ -46,25 +50,77 @@ where
46
50
{
47
51
type Item = S :: Item ;
48
52
49
- fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
50
- self . project ( ) . inner . poll_next ( cx)
53
+ fn poll_next ( self : Pin < & mut Self > , context : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
54
+ self . project ( ) . inner . poll_next ( context)
55
+ }
56
+ }
57
+
58
+ pin_project ! {
59
+ /// A type that creates a proper `Timeline` subscriber.
60
+ ///
61
+ /// This type implements [`Stream`], so that it's entirely transparent for
62
+ /// all consumers expecting an `impl Stream`.
63
+ ///
64
+ /// This `Stream` pipes `VectorDiff`s from [`ObservableItems`] into a batched
65
+ /// stream ([`VectorSubscriberBatchedStream`]), and then apply a skip
66
+ /// higher-order stream ([`Skip`]).
67
+ ///
68
+ /// `Skip` works by skipping the first _n_ values, where _n_ is referred
69
+ /// as `count`. Here, this `count` value is defined by a `Stream<Item =
70
+ /// usize>` (see [`Skip::dynamic_skip_with_initial_count`]). Everytime
71
+ /// the `count` stream produces a value, `Skip` adjusts its output.
72
+ /// `count` is managed by [`SkipCount`][skip::SkipCount], and is hold in
73
+ /// `TimelineMetadata::subscriber_skip_count`.
74
+ pub ( super ) struct TimelineSubscriber {
75
+ #[ pin]
76
+ inner: Skip <VectorSubscriberBatchedStream <Arc <TimelineItem >>, Subscriber <usize >>,
77
+ }
78
+ }
79
+
80
+ impl TimelineSubscriber {
81
+ /// Creates a [`TimelineSubscriber`], in addition to the initial values of
82
+ /// the subscriber.
83
+ pub ( super ) fn new (
84
+ observable_items : & ObservableItems ,
85
+ observable_skip_count : & skip:: SkipCount ,
86
+ ) -> ( Vector < Arc < TimelineItem > > , Self ) {
87
+ let ( initial_values, stream) = observable_items
88
+ . subscribe ( )
89
+ . into_values_and_batched_stream ( )
90
+ . dynamic_skip_with_initial_count ( 0 , observable_skip_count. subscribe ( ) ) ;
91
+
92
+ ( initial_values, Self { inner : stream } )
93
+ }
94
+ }
95
+
96
+ impl Stream for TimelineSubscriber {
97
+ type Item = Vec < VectorDiff < Arc < TimelineItem > > > ;
98
+
99
+ fn poll_next ( self : Pin < & mut Self > , context : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
100
+ self . project ( ) . inner . poll_next ( context)
51
101
}
52
102
}
53
103
54
104
pub mod skip {
55
- use eyeball:: SharedObservable ;
56
- use futures_core:: Stream ;
105
+ use eyeball:: { SharedObservable , Subscriber } ;
57
106
58
107
use super :: super :: controller:: TimelineFocusKind ;
59
108
60
109
const MAXIMUM_NUMBER_OF_INITIAL_ITEMS : usize = 20 ;
61
110
111
+ /// `SkipCount` helps to manage the `count` value used by the [`Skip`]
112
+ /// higher-order stream used by the [`TimelineSubscriber`]. See its
113
+ /// documentation to learn more.
114
+ ///
115
+ /// [`Skip`]: eyeball_im_util::vector::Skip
116
+ /// [`TimelineSubscriber`]: super::TimelineSubscriber
62
117
#[ derive( Clone , Debug ) ]
63
118
pub struct SkipCount {
64
119
count : SharedObservable < usize > ,
65
120
}
66
121
67
122
impl SkipCount {
123
+ /// Create a [`SkipCount`] with a default `count` value set to 0.
68
124
pub fn new ( ) -> Self {
69
125
Self { count : SharedObservable :: new ( 0 ) }
70
126
}
@@ -176,7 +232,7 @@ pub mod skip {
176
232
}
177
233
178
234
/// Subscribe to update of the count value.
179
- pub fn subscribe ( & self ) -> impl Stream < Item = usize > {
235
+ pub fn subscribe ( & self ) -> Subscriber < usize > {
180
236
self . count . subscribe ( )
181
237
}
182
238
0 commit comments