Skip to content

Commit d8d136b

Browse files
daniel-abramovjplatte
authored andcommitted
widget: change signature of the ClientApi
Return `Self` and the channel to process incoming actions.
1 parent 5b92b0a commit d8d136b

File tree

2 files changed

+64
-58
lines changed

2 files changed

+64
-58
lines changed

crates/matrix-sdk/src/widget/client/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use ruma::{
2323
OwnedEventId,
2424
};
2525
use serde_json::Value as JsonValue;
26+
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
2627

2728
use super::Permissions;
2829

@@ -31,16 +32,18 @@ pub struct ClientApi;
3132

3233
impl ClientApi {
3334
/// Creates a new instance of a client widget API state machine.
34-
pub fn new() -> Self {
35-
Self
35+
/// Returns the client api handler as well as the channel to receive
36+
/// actions (commands) from the client.
37+
pub fn new() -> (Self, UnboundedReceiver<Action>) {
38+
let (_tx, rx) = unbounded_channel();
39+
(Self, rx)
3640
}
3741

3842
/// Processes an incoming event (an incoming raw message from a widget,
3943
/// or a data produced as a result of a previously sent `Action`).
4044
/// Produceses a list of actions that the client must perform.
41-
pub fn process(&mut self, _event: Event) -> Vec<Action> {
45+
pub fn process(&mut self, _event: Event) {
4246
// TODO: Process the event.
43-
Vec::new()
4447
}
4548
}
4649

crates/matrix-sdk/src/widget/mod.rs

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -119,75 +119,78 @@ impl WidgetDriver {
119119
room: Room,
120120
permissions_provider: impl PermissionsProvider,
121121
) -> Result<(), ()> {
122+
let (mut client_api, mut actions) = ClientApi::new();
123+
122124
// Create a channel so that we can conveniently send all events to it.
123125
let (events_tx, mut events_rx) = unbounded_channel();
124126

125-
// `from.map(|m| Ok(Event::MessageFromWidget(msg)).forward(events_tx)`,
126-
// but apparently `UnboundedSender<T>` does not implement `Sink<T>`.
127+
// Forward all of the incoming messages from the widget to the `events_tx`.
127128
let tx = events_tx.clone();
128129
tokio::spawn(async move {
129130
while let Ok(msg) = self.from_widget_rx.recv().await {
130131
let _ = tx.send(Event::MessageFromWidget(msg));
131132
}
132133
});
133134

134-
// Our "state" (everything we need to process events).
135-
let (mut client_api, matrix) = (ClientApi::new(), MatrixDriver::new(room));
136-
let mut event_forwarding_guard: Option<DropGuard> = None;
135+
// Forward all of the incoming events to the `ClientApi` implementation.
136+
tokio::spawn(async move {
137+
while let Some(event) = events_rx.recv().await {
138+
client_api.process(event);
139+
}
140+
});
137141

138-
// Process events by passing them to the `ClientApi` implementation.
139-
while let Some(event) = events_rx.recv().await {
140-
for action in client_api.process(event) {
141-
match action {
142-
Action::SendToWidget(msg) => {
143-
self.to_widget_tx.send(msg).await.map_err(|_| ())?
144-
}
145-
Action::AcquirePermissions(cmd) => {
146-
let obtained = permissions_provider.acquire_permissions(cmd.clone()).await;
147-
let event = Event::PermissionsAcquired(cmd.ok(obtained));
148-
events_tx.send(event).map_err(|_| ())?;
149-
}
150-
Action::GetOpenId(cmd) => {
151-
let result = cmd.result(matrix.get_open_id().await);
152-
events_tx.send(Event::OpenIdReceived(result)).map_err(|_| ())?;
153-
}
154-
Action::ReadMatrixEvent(cmd) => {
155-
let matrix_events = matrix.read(cmd.event_type.clone(), cmd.limit).await;
156-
let event = Event::MatrixEventRead(cmd.result(matrix_events));
157-
events_tx.send(event).map_err(|_| ())?;
158-
}
159-
Action::SendMatrixEvent(cmd) => {
160-
let SendEventCommand { event_type, state_key, content } = cmd.clone();
161-
let matrix_event_id = matrix.send(event_type, state_key, content).await;
162-
let event = Event::MatrixEventSent(cmd.result(matrix_event_id));
163-
events_tx.send(event).map_err(|_| ())?;
164-
}
165-
Action::Subscribe => {
166-
// Only subscribe if we are not already subscribed.
167-
if event_forwarding_guard.is_none() {
168-
let (stop_forwarding, guard) = {
169-
let token = CancellationToken::new();
170-
(token.child_token(), token.drop_guard())
171-
};
172-
173-
event_forwarding_guard = Some(guard);
174-
let (mut matrix, events_tx) = (matrix.events(), events_tx.clone());
175-
tokio::spawn(async move {
176-
loop {
177-
tokio::select! {
178-
_ = stop_forwarding.cancelled() => { return }
179-
Some(event) = matrix.recv() => {
180-
let _ = events_tx.send(Event::MatrixEventReceived(event));
181-
}
142+
// Process events that we receive **from** the client api implementation,
143+
// i.e. the commands (actions) that the client sends to us.
144+
let matrix = MatrixDriver::new(room);
145+
let mut event_forwarding_guard: Option<DropGuard> = None;
146+
while let Some(action) = actions.recv().await {
147+
match action {
148+
Action::SendToWidget(msg) => self.to_widget_tx.send(msg).await.map_err(|_| ())?,
149+
Action::AcquirePermissions(cmd) => {
150+
let obtained = permissions_provider.acquire_permissions(cmd.clone()).await;
151+
let event = Event::PermissionsAcquired(cmd.ok(obtained));
152+
events_tx.send(event).map_err(|_| ())?;
153+
}
154+
Action::GetOpenId(cmd) => {
155+
let result = cmd.result(matrix.get_open_id().await);
156+
events_tx.send(Event::OpenIdReceived(result)).map_err(|_| ())?;
157+
}
158+
Action::ReadMatrixEvent(cmd) => {
159+
let matrix_events = matrix.read(cmd.event_type.clone(), cmd.limit).await;
160+
let event = Event::MatrixEventRead(cmd.result(matrix_events));
161+
events_tx.send(event).map_err(|_| ())?;
162+
}
163+
Action::SendMatrixEvent(cmd) => {
164+
let SendEventCommand { event_type, state_key, content } = cmd.clone();
165+
let matrix_event_id = matrix.send(event_type, state_key, content).await;
166+
let event = Event::MatrixEventSent(cmd.result(matrix_event_id));
167+
events_tx.send(event).map_err(|_| ())?;
168+
}
169+
Action::Subscribe => {
170+
// Only subscribe if we are not already subscribed.
171+
if event_forwarding_guard.is_none() {
172+
let (stop_forwarding, guard) = {
173+
let token = CancellationToken::new();
174+
(token.child_token(), token.drop_guard())
175+
};
176+
177+
event_forwarding_guard = Some(guard);
178+
let (mut matrix, events_tx) = (matrix.events(), events_tx.clone());
179+
tokio::spawn(async move {
180+
loop {
181+
tokio::select! {
182+
_ = stop_forwarding.cancelled() => { return }
183+
Some(event) = matrix.recv() => {
184+
let _ = events_tx.send(Event::MatrixEventReceived(event));
182185
}
183186
}
184-
});
185-
}
186-
}
187-
Action::Unsubscribe => {
188-
event_forwarding_guard = None;
187+
}
188+
});
189189
}
190190
}
191+
Action::Unsubscribe => {
192+
event_forwarding_guard = None;
193+
}
191194
}
192195
}
193196

0 commit comments

Comments
 (0)