feat(sdk): SlidingSyncView.state, .rooms_list and .rooms_count are now private.

Before this patch, `SlidingSyncView` has the following fields that were public:
`state`, `rooms_list` and `rooms_count`. Since they are `Mutable`, they can be
changed from the outside, and then will break the internal state of the view.
This problem is mentioned in https://github.com/matrix-org/matrix-rust-sdk/
issues/1474.

This patch solves this by making them prviate. Phew. That was simple!

But wait, we have a problem now. `matrix-sdk-ffi` was relying on them. So
this patch adds “helpers” methods on `SlidingSyncView`, like `state_stream`,
`rooms_list`, `rooms_list_stream`, `rooms_count` and `rooms_count_stream`.
Let's add new ones when it's necessary.
This commit is contained in:
Ivan Enderlin
2023-02-20 14:07:24 +01:00
parent 03c3f66c9a
commit d49ceddfd5
2 changed files with 44 additions and 13 deletions

View File

@@ -504,10 +504,11 @@ impl SlidingSyncView {
&self,
observer: Box<dyn SlidingSyncViewStateObserver>,
) -> Arc<StoppableSpawn> {
let mut signal = self.inner.state.signal_cloned().to_stream();
let mut state_stream = self.inner.state_stream();
Arc::new(StoppableSpawn::with_handle(RUNTIME.spawn(async move {
loop {
if let Some(new_state) = signal.next().await {
if let Some(new_state) = state_stream.next().await {
observer.did_receive_update(new_state);
}
}
@@ -518,10 +519,11 @@ impl SlidingSyncView {
&self,
observer: Box<dyn SlidingSyncViewRoomListObserver>,
) -> Arc<StoppableSpawn> {
let mut room_list = self.inner.rooms_list.signal_vec_cloned().to_stream();
let mut rooms_list_stream = self.inner.rooms_list_stream();
Arc::new(StoppableSpawn::with_handle(RUNTIME.spawn(async move {
loop {
if let Some(diff) = room_list.next().await {
if let Some(diff) = rooms_list_stream.next().await {
observer.did_receive_update(diff.into());
}
}
@@ -546,10 +548,11 @@ impl SlidingSyncView {
&self,
observer: Box<dyn SlidingSyncViewRoomsCountObserver>,
) -> Arc<StoppableSpawn> {
let mut rooms_count = self.inner.rooms_count.signal_cloned().to_stream();
let mut rooms_count_stream = self.inner.rooms_count_stream();
Arc::new(StoppableSpawn::with_handle(RUNTIME.spawn(async move {
loop {
if let Some(Some(new)) = rooms_count.next().await {
if let Some(Some(new)) = rooms_count_stream.next().await {
observer.did_receive_update(new);
}
}
@@ -561,7 +564,7 @@ impl SlidingSyncView {
impl SlidingSyncView {
/// Get the current list of rooms
pub fn current_rooms_list(&self) -> Vec<RoomListEntry> {
self.inner.rooms_list.lock_ref().as_slice().iter().map(|e| e.into()).collect()
self.inner.rooms_list()
}
/// Reset the ranges to a particular set
@@ -587,7 +590,7 @@ impl SlidingSyncView {
/// Total of rooms matching the filter
pub fn current_room_count(&self) -> Option<u32> {
self.inner.rooms_count.get_cloned()
self.inner.rooms_count()
}
/// The current timeline limit

View File

@@ -9,8 +9,8 @@ use std::{
use derive_builder::Builder;
use futures_signals::{
signal::Mutable,
signal_vec::{MutableVec, MutableVecLockMut},
signal::{Mutable, MutableSignalCloned, SignalExt, SignalStream},
signal_vec::{MutableSignalVec, MutableVec, MutableVecLockMut, SignalVecExt, SignalVecStream},
};
use ruma::{
api::client::sync::sync_events::v4, assign, events::StateEventType, OwnedRoomId, RoomId, UInt,
@@ -83,15 +83,15 @@ pub struct SlidingSyncView {
/// The state this view is in
#[builder(private, default)]
pub state: Mutable<SlidingSyncState>,
state: Mutable<SlidingSyncState>,
/// The total known number of rooms,
#[builder(private, default)]
pub rooms_count: Mutable<Option<u32>>,
rooms_count: Mutable<Option<u32>>,
/// The rooms in order
#[builder(private, default)]
pub rooms_list: Arc<MutableVec<RoomListEntry>>,
rooms_list: Arc<MutableVec<RoomListEntry>>,
/// The ranges windows of the view
#[builder(setter(name = "ranges_raw"), default)]
@@ -212,6 +212,34 @@ impl SlidingSyncView {
self
}
/// Get a stream of state.
pub fn state_stream(&self) -> SignalStream<MutableSignalCloned<SlidingSyncState>> {
self.state.signal_cloned().to_stream()
}
/// Get the current rooms list.
pub fn rooms_list<R>(&self) -> Vec<R>
where
R: for<'a> From<&'a RoomListEntry>,
{
self.rooms_list.lock_ref().iter().map(|e| R::from(e)).collect()
}
/// Get a stream of rooms list.
pub fn rooms_list_stream(&self) -> SignalVecStream<MutableSignalVec<RoomListEntry>> {
self.rooms_list.signal_vec_cloned().to_stream()
}
/// Get the current rooms count.
pub fn rooms_count(&self) -> Option<u32> {
self.rooms_count.get_cloned()
}
/// Get a stream of rooms count.
pub fn rooms_count_stream(&self) -> SignalStream<MutableSignalCloned<Option<u32>>> {
self.rooms_count.signal_cloned().to_stream()
}
/// Find the current valid position of the room in the view room_list.
///
/// Only matches against the current ranges and only against filled items.