From db0217d093ad4ce5afcfebb5c5589dd5fdd4b3b5 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 1 Jun 2023 15:33:58 +0200 Subject: [PATCH 1/3] Box internally --- crates/matrix-sdk-ui/src/room_list/mod.rs | 4 ++-- crates/matrix-sdk-ui/tests/integration/room_list.rs | 4 ++-- crates/matrix-sdk/src/sliding_sync/list/mod.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/matrix-sdk-ui/src/room_list/mod.rs b/crates/matrix-sdk-ui/src/room_list/mod.rs index 2843b0b5a..8e1a5e6f9 100644 --- a/crates/matrix-sdk-ui/src/room_list/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list/mod.rs @@ -54,7 +54,7 @@ impl RoomList { move |list| { *entries.lock().unwrap() = - Some(list.room_list_filtered_stream(Box::new(|_| true))); + Some(list.room_list_filtered_stream(|_| true)); list } @@ -135,7 +135,7 @@ impl RoomList { pub async fn update_entries_stream_filter( &self, - filter: Box bool + Sync + Send>, + filter: impl Fn(&RoomListEntry) -> bool + Sync + Send + 'static, ) -> Result<(), Error> { let mut entries_stream = self.entries_stream.try_write().map_err(|_| Error::CannotUpdateEntriesFilter)?; diff --git a/crates/matrix-sdk-ui/tests/integration/room_list.rs b/crates/matrix-sdk-ui/tests/integration/room_list.rs index 88b2dd294..5347f4392 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list.rs @@ -646,12 +646,12 @@ async fn test_entries_stream_with_updated_filter() -> Result<(), Error> { // Second, update the filter. room_list - .update_entries_stream_filter(Box::new(|room_list_entry| { + .update_entries_stream_filter(|room_list_entry| { matches!( room_list_entry.as_room_id(), Some(room_id) if room_id.server_name() == "bar.org" ) - })) + }) .await?; // Third, let's get a new entries stream. diff --git a/crates/matrix-sdk/src/sliding_sync/list/mod.rs b/crates/matrix-sdk/src/sliding_sync/list/mod.rs index 48399429d..9a8efa764 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/mod.rs @@ -135,7 +135,7 @@ impl SlidingSyncList { /// by `filter`. pub fn room_list_filtered_stream( &self, - filter: Box bool + Sync + Send>, + filter: impl Fn(&RoomListEntry) -> bool + Sync + Send + 'static, ) -> FilteredVectorSubscriber bool + Sync + Send>> { let (_, stream) = From 58e8c0a7ace017374acb78d0601b405daced3e70 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 1 Jun 2023 15:34:13 +0200 Subject: [PATCH 2/3] Fix warning --- crates/matrix-sdk-ui/src/room_list/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk-ui/src/room_list/mod.rs b/crates/matrix-sdk-ui/src/room_list/mod.rs index 8e1a5e6f9..70941a3df 100644 --- a/crates/matrix-sdk-ui/src/room_list/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list/mod.rs @@ -129,7 +129,7 @@ impl RoomList { pub fn entries_stream( &self, - ) -> RwLockWriteGuard>> { + ) -> RwLockWriteGuard<'_, impl Stream>> { self.entries_stream.write().unwrap() } From 51062559113b1ffa56731be249cdd22771c38ede Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 1 Jun 2023 15:40:39 +0200 Subject: [PATCH 3/3] On-demand stream creation --- crates/matrix-sdk-ui/src/room_list/mod.rs | 69 +++++-------------- .../matrix-sdk/src/sliding_sync/list/mod.rs | 22 ++++-- 2 files changed, 31 insertions(+), 60 deletions(-) diff --git a/crates/matrix-sdk-ui/src/room_list/mod.rs b/crates/matrix-sdk-ui/src/room_list/mod.rs index 70941a3df..40a94e003 100644 --- a/crates/matrix-sdk-ui/src/room_list/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list/mod.rs @@ -1,17 +1,13 @@ //! `RoomList` API. -use std::{ - fmt, - future::ready, - sync::{Arc, Mutex, RwLock, RwLockWriteGuard}, -}; +use std::future::ready; use async_stream::stream; use async_trait::async_trait; use eyeball::shared::Observable; use eyeball_im::VectorDiff; -use eyeball_im_util::FilteredVectorSubscriber; use futures_util::{pin_mut, Stream, StreamExt}; +use imbl::Vector; pub use matrix_sdk::RoomListEntry; use matrix_sdk::{ Client, Error as SlidingSyncError, SlidingSync, SlidingSyncList, SlidingSyncMode, @@ -22,43 +18,20 @@ use thiserror::Error; pub const ALL_ROOMS_LIST_NAME: &str = "all_rooms"; pub const VISIBLE_ROOMS_LIST_NAME: &str = "visible_rooms"; +#[derive(Debug)] pub struct RoomList { sliding_sync: SlidingSync, - entries_stream: RwLock< - FilteredVectorSubscriber bool + Sync + Send>>, - >, state: Observable, } -impl fmt::Debug for RoomList { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter - .debug_struct("RoomList") - .field("sliding_sync", &self.sliding_sync) - .field("state", &self.state) - .finish_non_exhaustive() - } -} - impl RoomList { pub async fn new(client: Client) -> Result { - let entries = Arc::new(Mutex::new(None)); let sliding_sync = client .sliding_sync() .storage_key(Some("matrix-sdk-ui-roomlist".to_string())) .add_cached_list( SlidingSyncList::builder(ALL_ROOMS_LIST_NAME) - .sync_mode(SlidingSyncMode::new_selective().add_range(0..=19)) - .once_built({ - let entries = entries.clone(); - - move |list| { - *entries.lock().unwrap() = - Some(list.room_list_filtered_stream(|_| true)); - - list - } - }), + .sync_mode(SlidingSyncMode::new_selective().add_range(0..=19)), ) .await .map_err(Error::SlidingSync)? @@ -66,14 +39,7 @@ impl RoomList { .await .map_err(Error::SlidingSync)?; - let entries = - Arc::try_unwrap(entries).map_err(|_| Error::Entries)?.into_inner().unwrap().unwrap(); - - Ok(Self { - sliding_sync, - entries_stream: RwLock::new(entries), - state: Observable::new(State::Init), - }) + Ok(Self { sliding_sync, state: Observable::new(State::Init) }) } pub fn sync(&self) -> impl Stream> + '_ { @@ -127,26 +93,23 @@ impl RoomList { Observable::subscribe(&self.state) } - pub fn entries_stream( + pub async fn entries( &self, - ) -> RwLockWriteGuard<'_, impl Stream>> { - self.entries_stream.write().unwrap() + ) -> Result<(Vector, impl Stream>), Error> { + self.sliding_sync + .on_list(ALL_ROOMS_LIST_NAME, |list| ready(list.room_list_stream())) + .await + .ok_or_else(|| Error::UnknownList(ALL_ROOMS_LIST_NAME.to_string())) } - pub async fn update_entries_stream_filter( + pub async fn entries_filtered( &self, - filter: impl Fn(&RoomListEntry) -> bool + Sync + Send + 'static, - ) -> Result<(), Error> { - let mut entries_stream = - self.entries_stream.try_write().map_err(|_| Error::CannotUpdateEntriesFilter)?; - - *entries_stream = self - .sliding_sync + filter: impl Fn(&RoomListEntry) -> bool + Send + Sync + 'static, + ) -> Result<(Vector, impl Stream>), Error> { + self.sliding_sync .on_list(ALL_ROOMS_LIST_NAME, |list| ready(list.room_list_filtered_stream(filter))) .await - .ok_or_else(|| Error::UnknownList(ALL_ROOMS_LIST_NAME.to_string()))?; - - Ok(()) + .ok_or_else(|| Error::UnknownList(ALL_ROOMS_LIST_NAME.to_string())) } #[cfg(any(test, feature = "testing"))] diff --git a/crates/matrix-sdk/src/sliding_sync/list/mod.rs b/crates/matrix-sdk/src/sliding_sync/list/mod.rs index 9a8efa764..4d99277f7 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/mod.rs @@ -17,6 +17,7 @@ use eyeball_im::{ObservableVector, VectorDiff}; use eyeball_im_util::{FilteredVectorSubscriber, VectorExt}; pub(super) use frozen::FrozenSlidingSyncList; use futures_core::Stream; +use imbl::Vector; pub(super) use request_generator::*; pub use room_list_entry::RoomListEntry; use ruma::{api::client::sync::sync_events::v4, assign, events::StateEventType, OwnedRoomId}; @@ -49,6 +50,8 @@ pub struct SlidingSyncList { inner: Arc, } +type BoxedRoomListEntryFilter = Box bool + Sync + Send>; + impl SlidingSyncList { /// Create a new [`SlidingSyncListBuilder`] with the given name. pub fn builder(name: impl Into) -> SlidingSyncListBuilder { @@ -125,8 +128,13 @@ impl SlidingSyncList { /// /// There's no guarantee of ordering between items emitted by this stream /// and those emitted by other streams exposed on this structure. - pub fn room_list_stream(&self) -> impl Stream> { - ObservableVector::subscribe(&self.inner.room_list.read().unwrap()) + pub fn room_list_stream( + &self, + ) -> (Vector, impl Stream>) { + let read_lock = self.inner.room_list.read().unwrap(); + let values = (*read_lock).clone(); + let subscriber = ObservableVector::subscribe(&read_lock); + (values, subscriber) } /// Get a stream of room list, but filtered. @@ -136,12 +144,12 @@ impl SlidingSyncList { pub fn room_list_filtered_stream( &self, filter: impl Fn(&RoomListEntry) -> bool + Sync + Send + 'static, - ) -> FilteredVectorSubscriber bool + Sync + Send>> + ) -> (Vector, FilteredVectorSubscriber) { - let (_, stream) = - ObservableVector::subscribe_filtered(&self.inner.room_list.read().unwrap(), filter); - - stream + ObservableVector::subscribe_filtered( + &self.inner.room_list.read().unwrap(), + Box::new(filter), + ) } /// Get the maximum number of rooms. See [`Self::maximum_number_of_rooms`]