diff --git a/src/app/events/event_types/event/handlers/main.rs b/src/app/events/event_types/event/handlers/main.rs index 880339a..01d3097 100644 --- a/src/app/events/event_types/event/handlers/main.rs +++ b/src/app/events/event_types/event/handlers/main.rs @@ -2,7 +2,11 @@ use anyhow::Result; use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers}; use crate::{ - app::{command, command::Command, events::event_types::EventStatus, App}, + app::{ + command_interface::Command, + events::event_types::{Event, EventStatus}, + App, + }, ui::central, }; @@ -11,25 +15,33 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result { - command::execute(app.channel_tx(), Command::Exit).await?; + app.transmitter + .send(Event::CommandEvent(Command::Exit)) + .await?; } CrosstermEvent::Key(KeyEvent { code: KeyCode::Tab, .. }) => { - command::execute(app.channel_tx(), Command::CyclePlanes).await?; + app.transmitter + .send(Event::CommandEvent(Command::CyclePlanes)) + .await?; } CrosstermEvent::Key(KeyEvent { code: KeyCode::BackTab, .. }) => { - command::execute(app.channel_tx(), Command::CyclePlanesRev).await?; + app.transmitter + .send(Event::CommandEvent(Command::CyclePlanesRev)) + .await?; } CrosstermEvent::Key(KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, .. }) => { - command::execute(app.channel_tx(), Command::CommandLineShow).await?; + app.transmitter + .send(Event::CommandEvent(Command::CommandLineShow)) + .await?; } input => match app.ui.input_position() { central::InputPosition::MessageCompose => { @@ -39,11 +51,11 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result { - command::execute( - app.channel_tx(), - Command::RoomMessageSend(app.ui.message_compose.lines().join("\n")), - ) - .await?; + app.transmitter + .send(Event::CommandEvent(Command::RoomMessageSend( + app.ui.message_compose.lines().join("\n"), + ))) + .await?; app.ui.message_compose_clear(); } _ => { diff --git a/src/app/mod.rs b/src/app/mod.rs index 3b21e9d..d4fc374 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,29 +1,31 @@ pub mod command_interface; pub mod events; pub mod status; +pub mod transmitter; use std::{path::Path, sync::mpsc::Sender as StdSender}; -use accounts::{Account, AccountsManager}; use anyhow::{Context, Error, Result}; use cli_log::info; use matrix_sdk::Client; use rlua::Lua; use status::{State, Status}; -use tokio::sync::mpsc; use tokio_util::sync::CancellationToken; -use crate::{accounts, app::command_interface::generate_ci_functions, ui::{central, setup}}; +use crate::{ + accounts::{Account, AccountsManager}, + app::{command_interface::generate_ci_functions, events::event_types::Event}, + ui::{central, setup}, +}; -use self::events::event_types::{self, Event}; +use self::{events::event_types, transmitter::Transmitter}; pub struct App<'ui> { ui: central::UI<'ui>, - accounts_manager: accounts::AccountsManager, + accounts_manager: AccountsManager, status: Status, - channel_tx: mpsc::Sender, - channel_rx: mpsc::Receiver, + transmitter: Transmitter, input_listener_killer: CancellationToken, matrix_listener_killer: CancellationToken, @@ -49,19 +51,17 @@ impl App<'_> { None }; - let (channel_tx, channel_rx) = mpsc::channel(256); - + let transmitter = Transmitter::new(); Ok(Self { ui: central::UI::new()?, accounts_manager: AccountsManager::new(config)?, status: Status::new(None), - channel_tx, - channel_rx, + transmitter, input_listener_killer: CancellationToken::new(), matrix_listener_killer: CancellationToken::new(), - lua: set_up_lua(channel_tx), + lua: set_up_lua(transmitter.std_tx()), }) } @@ -83,7 +83,7 @@ impl App<'_> { pub async fn run(&mut self) -> Result<()> { // Spawn input event listener tokio::task::spawn(events::poll_input_events( - self.channel_tx.clone(), + self.transmitter.tx(), self.input_listener_killer.clone(), )); @@ -99,10 +99,11 @@ impl App<'_> { self.status.set_state(State::Main); self.ui.update(&self.status).await?; - let event: event_types::Event = match self.channel_rx.recv().await { - Some(e) => e, - None => return Err(Error::msg("Event channel has no senders")), - }; + let event = self + .transmitter + .recv() + .await + .context("Failed to get next event")?; match event.handle(self).await? { event_types::EventStatus::Ok => (), @@ -122,10 +123,11 @@ impl App<'_> { self.status.set_state(State::Setup); self.ui.update_setup().await?; - let event: event_types::Event = match self.channel_rx.recv().await { - Some(e) => e, - None => return Err(Error::msg("Event channel has no senders")), - }; + let event = self + .transmitter + .recv() + .await + .context("Failed to get next event")?; match event.handle(self).await? { event_types::EventStatus::Ok => (), @@ -149,7 +151,7 @@ impl App<'_> { // Spawn Matrix Event Listener tokio::task::spawn(events::poll_matrix_events( - self.channel_tx.clone(), + self.transmitter.tx(), self.matrix_listener_killer.clone(), client.clone(), )); @@ -203,8 +205,4 @@ impl App<'_> { pub fn client(&self) -> Option<&Client> { self.accounts_manager.client() } - - pub fn channel_tx(&self) -> &mpsc::Sender { - &self.channel_tx - } } diff --git a/src/app/transmitter.rs b/src/app/transmitter.rs new file mode 100644 index 0000000..c887459 --- /dev/null +++ b/src/app/transmitter.rs @@ -0,0 +1,43 @@ +use std::sync::mpsc as StdMpsc; + +use anyhow::{bail, Context, Result}; +use tokio::sync::mpsc; + +use super::events::event_types::Event; + +pub struct Transmitter { + tx: mpsc::Sender, + rx: mpsc::Receiver, + std_tx: StdMpsc::Sender, + std_rx: StdMpsc::Receiver, +} + +impl Transmitter { + pub fn new() -> Transmitter { + let (std_tx, std_rx) = StdMpsc::channel(); + let (tx, rx) = mpsc::channel(256); + Transmitter { + tx, + rx, + std_tx, + std_rx, + } + } + pub fn tx(&self) -> mpsc::Sender { + self.tx.to_owned() + } + + pub fn std_tx(&self) -> StdMpsc::Sender { + self.std_tx.to_owned() + } + + pub async fn recv(&mut self) -> Result { + match self.rx.recv().await { + Some(event) => Ok(event), + None => bail!("Event channel has no senders"), + } + } + pub async fn send(&mut self, event: Event) -> Result<()> { + self.tx.send(event).await.context("Failed to send event") + } +}