Refactor(app): Add a transmitter
This commit is contained in:
parent
ba225e29df
commit
49818e0bfe
|
@ -2,7 +2,11 @@ use anyhow::Result;
|
||||||
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers};
|
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{command, command::Command, events::event_types::EventStatus, App},
|
app::{
|
||||||
|
command_interface::Command,
|
||||||
|
events::event_types::{Event, EventStatus},
|
||||||
|
App,
|
||||||
|
},
|
||||||
ui::central,
|
ui::central,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,25 +15,33 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Esc, ..
|
code: KeyCode::Esc, ..
|
||||||
}) => {
|
}) => {
|
||||||
command::execute(app.channel_tx(), Command::Exit).await?;
|
app.transmitter
|
||||||
|
.send(Event::CommandEvent(Command::Exit))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Tab, ..
|
code: KeyCode::Tab, ..
|
||||||
}) => {
|
}) => {
|
||||||
command::execute(app.channel_tx(), Command::CyclePlanes).await?;
|
app.transmitter
|
||||||
|
.send(Event::CommandEvent(Command::CyclePlanes))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::BackTab,
|
code: KeyCode::BackTab,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
command::execute(app.channel_tx(), Command::CyclePlanesRev).await?;
|
app.transmitter
|
||||||
|
.send(Event::CommandEvent(Command::CyclePlanesRev))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Char('c'),
|
code: KeyCode::Char('c'),
|
||||||
modifiers: KeyModifiers::CONTROL,
|
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() {
|
input => match app.ui.input_position() {
|
||||||
central::InputPosition::MessageCompose => {
|
central::InputPosition::MessageCompose => {
|
||||||
|
@ -39,10 +51,10 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
modifiers: KeyModifiers::ALT,
|
modifiers: KeyModifiers::ALT,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
command::execute(
|
app.transmitter
|
||||||
app.channel_tx(),
|
.send(Event::CommandEvent(Command::RoomMessageSend(
|
||||||
Command::RoomMessageSend(app.ui.message_compose.lines().join("\n")),
|
app.ui.message_compose.lines().join("\n"),
|
||||||
)
|
)))
|
||||||
.await?;
|
.await?;
|
||||||
app.ui.message_compose_clear();
|
app.ui.message_compose_clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
pub mod command_interface;
|
pub mod command_interface;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
pub mod transmitter;
|
||||||
|
|
||||||
use std::{path::Path, sync::mpsc::Sender as StdSender};
|
use std::{path::Path, sync::mpsc::Sender as StdSender};
|
||||||
|
|
||||||
use accounts::{Account, AccountsManager};
|
|
||||||
use anyhow::{Context, Error, Result};
|
use anyhow::{Context, Error, Result};
|
||||||
use cli_log::info;
|
use cli_log::info;
|
||||||
use matrix_sdk::Client;
|
use matrix_sdk::Client;
|
||||||
use rlua::Lua;
|
use rlua::Lua;
|
||||||
use status::{State, Status};
|
use status::{State, Status};
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use tokio_util::sync::CancellationToken;
|
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> {
|
pub struct App<'ui> {
|
||||||
ui: central::UI<'ui>,
|
ui: central::UI<'ui>,
|
||||||
accounts_manager: accounts::AccountsManager,
|
accounts_manager: AccountsManager,
|
||||||
status: Status,
|
status: Status,
|
||||||
|
|
||||||
channel_tx: mpsc::Sender<event_types::Event>,
|
transmitter: Transmitter,
|
||||||
channel_rx: mpsc::Receiver<event_types::Event>,
|
|
||||||
input_listener_killer: CancellationToken,
|
input_listener_killer: CancellationToken,
|
||||||
matrix_listener_killer: CancellationToken,
|
matrix_listener_killer: CancellationToken,
|
||||||
|
|
||||||
|
@ -49,19 +51,17 @@ impl App<'_> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let (channel_tx, channel_rx) = mpsc::channel(256);
|
let transmitter = Transmitter::new();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ui: central::UI::new()?,
|
ui: central::UI::new()?,
|
||||||
accounts_manager: AccountsManager::new(config)?,
|
accounts_manager: AccountsManager::new(config)?,
|
||||||
status: Status::new(None),
|
status: Status::new(None),
|
||||||
|
|
||||||
channel_tx,
|
transmitter,
|
||||||
channel_rx,
|
|
||||||
input_listener_killer: CancellationToken::new(),
|
input_listener_killer: CancellationToken::new(),
|
||||||
matrix_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<()> {
|
pub async fn run(&mut self) -> Result<()> {
|
||||||
// Spawn input event listener
|
// Spawn input event listener
|
||||||
tokio::task::spawn(events::poll_input_events(
|
tokio::task::spawn(events::poll_input_events(
|
||||||
self.channel_tx.clone(),
|
self.transmitter.tx(),
|
||||||
self.input_listener_killer.clone(),
|
self.input_listener_killer.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -99,10 +99,11 @@ impl App<'_> {
|
||||||
self.status.set_state(State::Main);
|
self.status.set_state(State::Main);
|
||||||
self.ui.update(&self.status).await?;
|
self.ui.update(&self.status).await?;
|
||||||
|
|
||||||
let event: event_types::Event = match self.channel_rx.recv().await {
|
let event = self
|
||||||
Some(e) => e,
|
.transmitter
|
||||||
None => return Err(Error::msg("Event channel has no senders")),
|
.recv()
|
||||||
};
|
.await
|
||||||
|
.context("Failed to get next event")?;
|
||||||
|
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
event_types::EventStatus::Ok => (),
|
||||||
|
@ -122,10 +123,11 @@ impl App<'_> {
|
||||||
self.status.set_state(State::Setup);
|
self.status.set_state(State::Setup);
|
||||||
self.ui.update_setup().await?;
|
self.ui.update_setup().await?;
|
||||||
|
|
||||||
let event: event_types::Event = match self.channel_rx.recv().await {
|
let event = self
|
||||||
Some(e) => e,
|
.transmitter
|
||||||
None => return Err(Error::msg("Event channel has no senders")),
|
.recv()
|
||||||
};
|
.await
|
||||||
|
.context("Failed to get next event")?;
|
||||||
|
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
event_types::EventStatus::Ok => (),
|
||||||
|
@ -149,7 +151,7 @@ impl App<'_> {
|
||||||
|
|
||||||
// Spawn Matrix Event Listener
|
// Spawn Matrix Event Listener
|
||||||
tokio::task::spawn(events::poll_matrix_events(
|
tokio::task::spawn(events::poll_matrix_events(
|
||||||
self.channel_tx.clone(),
|
self.transmitter.tx(),
|
||||||
self.matrix_listener_killer.clone(),
|
self.matrix_listener_killer.clone(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
));
|
));
|
||||||
|
@ -203,8 +205,4 @@ impl App<'_> {
|
||||||
pub fn client(&self) -> Option<&Client> {
|
pub fn client(&self) -> Option<&Client> {
|
||||||
self.accounts_manager.client()
|
self.accounts_manager.client()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn channel_tx(&self) -> &mpsc::Sender<Event> {
|
|
||||||
&self.channel_tx
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<Event>,
|
||||||
|
rx: mpsc::Receiver<Event>,
|
||||||
|
std_tx: StdMpsc::Sender<Event>,
|
||||||
|
std_rx: StdMpsc::Receiver<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Event> {
|
||||||
|
self.tx.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn std_tx(&self) -> StdMpsc::Sender<Event> {
|
||||||
|
self.std_tx.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn recv(&mut self) -> Result<Event> {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue