From a538877b5bbdea419afb0ea04ec4cdf3378b1985 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Thu, 19 Oct 2023 18:14:59 +0200 Subject: [PATCH] refactor: restructured event sources --- .../lua_command_manager/mod.rs | 2 +- src/app/config/lua/mod.rs | 2 +- src/app/events/event_types/event/mod.rs | 53 --------- src/app/events/event_types/event_status.rs | 6 - src/app/events/event_types/mod.rs | 4 - .../event => }/handlers/command.rs | 2 +- .../event => }/handlers/function.rs | 4 +- .../{event_types/event => }/handlers/input.rs | 2 +- .../event => }/handlers/lua_command.rs | 2 +- .../{event_types/event => }/handlers/main.rs | 0 .../event => }/handlers/matrix.rs | 2 +- .../{event_types/event => }/handlers/mod.rs | 0 .../{event_types/event => }/handlers/setup.rs | 2 +- src/app/events/listeners/input.rs | 21 ++++ src/app/events/listeners/matrix.rs | 41 +++++++ src/app/events/listeners/mod.rs | 2 + src/app/events/mod.rs | 110 +++++++++--------- src/app/mod.rs | 22 ++-- 18 files changed, 140 insertions(+), 137 deletions(-) delete mode 100644 src/app/events/event_types/event/mod.rs delete mode 100644 src/app/events/event_types/event_status.rs delete mode 100644 src/app/events/event_types/mod.rs rename src/app/events/{event_types/event => }/handlers/command.rs (99%) rename src/app/events/{event_types/event => }/handlers/function.rs (74%) rename src/app/events/{event_types/event => }/handlers/input.rs (98%) rename src/app/events/{event_types/event => }/handlers/lua_command.rs (88%) rename src/app/events/{event_types/event => }/handlers/main.rs (100%) rename src/app/events/{event_types/event => }/handlers/matrix.rs (91%) rename src/app/events/{event_types/event => }/handlers/mod.rs (100%) rename src/app/events/{event_types/event => }/handlers/setup.rs (98%) create mode 100644 src/app/events/listeners/input.rs create mode 100644 src/app/events/listeners/matrix.rs create mode 100644 src/app/events/listeners/mod.rs diff --git a/src/app/command_interface/lua_command_manager/mod.rs b/src/app/command_interface/lua_command_manager/mod.rs index f33d054..c87816f 100644 --- a/src/app/command_interface/lua_command_manager/mod.rs +++ b/src/app/command_interface/lua_command_manager/mod.rs @@ -19,7 +19,7 @@ use crate::app::{ Raw::{DisplayOutput, RaiseError}, Trinitrix::Api, }, - events::event_types::Event, + events::Event, }; use super::command_transfer_value::support_types::Function; diff --git a/src/app/config/lua/mod.rs b/src/app/config/lua/mod.rs index 7daa225..ac3a227 100644 --- a/src/app/config/lua/mod.rs +++ b/src/app/config/lua/mod.rs @@ -4,7 +4,7 @@ use anyhow::Result; use cli_log::info; use tokio::{fs, sync::mpsc::Sender}; -use crate::app::events::event_types::Event; +use crate::app::events::Event; pub async fn load(tx: Sender, path: PathBuf) -> Result<()> { let lua_config_code = fs::read_to_string(&path).await?; diff --git a/src/app/events/event_types/event/mod.rs b/src/app/events/event_types/event/mod.rs deleted file mode 100644 index d327e11..0000000 --- a/src/app/events/event_types/event/mod.rs +++ /dev/null @@ -1,53 +0,0 @@ -mod handlers; - -use anyhow::{Context, Result}; -use cli_log::trace; -use crossterm::event::Event as CrosstermEvent; -use tokio::sync::oneshot; - -use super::EventStatus; -use crate::app::{ - command_interface::{command_transfer_value::{CommandTransferValue, support_types::Function}, Command}, - status::State, - App, events::event_types::event::handlers::{input, matrix, command, lua_command, setup, function}, -}; - -#[derive(Debug)] -pub enum Event { - InputEvent(CrosstermEvent), - MatrixEvent(matrix_sdk::deserialized_responses::SyncResponse), - CommandEvent(Command, Option>), - LuaCommand(String), - Function(Function), -} - -impl Event { - pub async fn handle(self, app: &mut App<'_>) -> Result { - trace!("Recieved event to handle: `{:#?}`", &self); - match self { - Event::MatrixEvent(event) => matrix::handle(app, &event) - .await - .with_context(|| format!("Failed to handle matrix event: `{:#?}`", event)), - - Event::CommandEvent(event, callback_tx) => command::handle(app, &event, callback_tx) - .await - .with_context(|| format!("Failed to handle command event: `{:#?}`", event)), - - Event::LuaCommand(lua_code) => lua_command::handle(app, lua_code.to_owned()) - .await - .with_context(|| format!("Failed to handle lua code: `{}`", lua_code)), - Event::Function(function) => function::handle(app, function.to_owned()) - .await - .with_context(|| format!("Failed to handle function: `{}`", function)), - - Event::InputEvent(event) => match app.status.state() { - State::Setup => setup::handle(app, &event).await.with_context(|| { - format!("Failed to handle input (setup) event: `{:#?}`", event) - }), - _ => input::handle(app, &event).await.with_context(|| { - format!("Failed to handle input (non-setup) event: `{:#?}`", event) - }), - }, - } - } -} diff --git a/src/app/events/event_types/event_status.rs b/src/app/events/event_types/event_status.rs deleted file mode 100644 index d7642cb..0000000 --- a/src/app/events/event_types/event_status.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[derive(Debug)] -pub enum EventStatus { - Ok, - Finished, - Terminate, -} diff --git a/src/app/events/event_types/mod.rs b/src/app/events/event_types/mod.rs deleted file mode 100644 index b89c71c..0000000 --- a/src/app/events/event_types/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod event; -pub mod event_status; - -pub use self::{event::*, event_status::*}; diff --git a/src/app/events/event_types/event/handlers/command.rs b/src/app/events/handlers/command.rs similarity index 99% rename from src/app/events/event_types/event/handlers/command.rs rename to src/app/events/handlers/command.rs index 76f2c41..9fb0eca 100644 --- a/src/app/events/event_types/event/handlers/command.rs +++ b/src/app/events/handlers/command.rs @@ -11,7 +11,7 @@ use crate::{ command_transfer_value::{CommandTransferValue, Table}, Api, Command, Debug, Keymaps, Raw, Trinitrix, Ui, }, - events::event_types::EventStatus, + events::EventStatus, keymappings::{ key::{Key, Keys}, trie::Node, diff --git a/src/app/events/event_types/event/handlers/function.rs b/src/app/events/handlers/function.rs similarity index 74% rename from src/app/events/event_types/event/handlers/function.rs rename to src/app/events/handlers/function.rs index 44c848b..ce431f8 100644 --- a/src/app/events/event_types/event/handlers/function.rs +++ b/src/app/events/handlers/function.rs @@ -1,6 +1,8 @@ use anyhow::Result; -use crate::app::{events::event_types::EventStatus, App, command_interface::command_transfer_value::support_types::Function}; +use crate::app::{ + command_interface::command_transfer_value::support_types::Function, events::EventStatus, App, +}; // TODO(@soispha): We just assume for now that all functions originate in lua. This module will in // future versions house check for the language the function came from <2023-10-15> diff --git a/src/app/events/event_types/event/handlers/input.rs b/src/app/events/handlers/input.rs similarity index 98% rename from src/app/events/event_types/event/handlers/input.rs rename to src/app/events/handlers/input.rs index 04df794..d28bff8 100644 --- a/src/app/events/event_types/event/handlers/input.rs +++ b/src/app/events/handlers/input.rs @@ -4,7 +4,7 @@ use crossterm::event::Event as CrosstermEvent; use crate::app::{ command_interface::{Api::Raw, Command, Raw::SendInputUnprocessed, Trinitrix::Api}, - events::event_types::{Event, EventStatus}, + events::{Event, EventStatus}, keymappings::key::{Key, Keys}, status::State, App, diff --git a/src/app/events/event_types/event/handlers/lua_command.rs b/src/app/events/handlers/lua_command.rs similarity index 88% rename from src/app/events/event_types/event/handlers/lua_command.rs rename to src/app/events/handlers/lua_command.rs index 959ddad..d2e53a9 100644 --- a/src/app/events/event_types/event/handlers/lua_command.rs +++ b/src/app/events/handlers/lua_command.rs @@ -1,7 +1,7 @@ use anyhow::Result; use cli_log::trace; -use crate::app::{events::event_types::EventStatus, App}; +use crate::app::{events::EventStatus, App}; // This function is here mainly to reserve this spot for further processing of the lua command. // TODO(@Soispha): Move the lua executor thread code from app to this module diff --git a/src/app/events/event_types/event/handlers/main.rs b/src/app/events/handlers/main.rs similarity index 100% rename from src/app/events/event_types/event/handlers/main.rs rename to src/app/events/handlers/main.rs diff --git a/src/app/events/event_types/event/handlers/matrix.rs b/src/app/events/handlers/matrix.rs similarity index 91% rename from src/app/events/event_types/event/handlers/matrix.rs rename to src/app/events/handlers/matrix.rs index a624a2c..8c2b5d4 100644 --- a/src/app/events/event_types/event/handlers/matrix.rs +++ b/src/app/events/handlers/matrix.rs @@ -1,7 +1,7 @@ use anyhow::Result; use matrix_sdk::deserialized_responses::SyncResponse; -use crate::app::{events::event_types::EventStatus, App}; +use crate::app::{events::EventStatus, App}; pub async fn handle(app: &mut App<'_>, sync: &SyncResponse) -> Result { for (m_room_id, m_room) in sync.rooms.join.iter() { diff --git a/src/app/events/event_types/event/handlers/mod.rs b/src/app/events/handlers/mod.rs similarity index 100% rename from src/app/events/event_types/event/handlers/mod.rs rename to src/app/events/handlers/mod.rs diff --git a/src/app/events/event_types/event/handlers/setup.rs b/src/app/events/handlers/setup.rs similarity index 98% rename from src/app/events/event_types/event/handlers/setup.rs rename to src/app/events/handlers/setup.rs index ab16965..fe20751 100644 --- a/src/app/events/event_types/event/handlers/setup.rs +++ b/src/app/events/handlers/setup.rs @@ -2,7 +2,7 @@ use anyhow::{bail, Context, Result}; use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent}; use crate::{ - app::{events::event_types::EventStatus, App}, + app::{events::EventStatus, App}, ui::setup, }; diff --git a/src/app/events/listeners/input.rs b/src/app/events/listeners/input.rs new file mode 100644 index 0000000..351eb18 --- /dev/null +++ b/src/app/events/listeners/input.rs @@ -0,0 +1,21 @@ +use crate::app::events::Event; +use anyhow::{bail, Result}; +use tokio::{sync::mpsc, time::Duration}; +use tokio_util::sync::CancellationToken; + +pub async fn poll(channel: mpsc::Sender, kill: CancellationToken) -> Result<()> { + async fn stage_2(channel: mpsc::Sender) -> Result<()> { + loop { + if crossterm::event::poll(Duration::from_millis(100))? { + let event = Event::InputEvent(crossterm::event::read()?); + channel.send(event).await?; + } else { + tokio::task::yield_now().await; + } + } + } + tokio::select! { + output = stage_2(channel) => output, + _ = kill.cancelled() => bail!("received kill signal") + } +} diff --git a/src/app/events/listeners/matrix.rs b/src/app/events/listeners/matrix.rs new file mode 100644 index 0000000..5db0c10 --- /dev/null +++ b/src/app/events/listeners/matrix.rs @@ -0,0 +1,41 @@ +/* WARNING(@antifallobst): + * This file is going to be removed while implementing Chat Backend Servers! + * <19-10-2023> + */ + +use crate::app::events::Event; +use anyhow::{bail, Result}; +use matrix_sdk::{config::SyncSettings, Client, LoopCtrl}; +use tokio::sync::mpsc; +use tokio_util::sync::CancellationToken; + +pub async fn poll( + channel: mpsc::Sender, + kill: CancellationToken, + client: Client, +) -> Result<()> { + async fn stage_2(channel: mpsc::Sender, client: Client) -> Result<()> { + let sync_settings = SyncSettings::default(); + // .token(sync_token) + // .timeout(Duration::from_secs(30)); + + let tx = &channel; + + client + .sync_with_callback(sync_settings, |response| async move { + let event = Event::MatrixEvent(response); + + match tx.send(event).await { + Ok(_) => LoopCtrl::Continue, + Err(_) => LoopCtrl::Break, + } + }) + .await?; + + Ok(()) + } + tokio::select! { + output = stage_2(channel, client) => output, + _ = kill.cancelled() => bail!("received kill signal"), + } +} diff --git a/src/app/events/listeners/mod.rs b/src/app/events/listeners/mod.rs new file mode 100644 index 0000000..c8f1fee --- /dev/null +++ b/src/app/events/listeners/mod.rs @@ -0,0 +1,2 @@ +pub mod input; +pub mod matrix; diff --git a/src/app/events/mod.rs b/src/app/events/mod.rs index ebee062..a878497 100644 --- a/src/app/events/mod.rs +++ b/src/app/events/mod.rs @@ -1,62 +1,64 @@ -pub mod event_types; +mod handlers; +pub mod listeners; -use anyhow::{bail, Result}; -use matrix_sdk::{config::SyncSettings, Client, LoopCtrl}; -use tokio::{sync::mpsc, time::Duration}; -use tokio_util::sync::CancellationToken; +use anyhow::{Context, Result}; -use self::event_types::Event; +use crate::app::{ + command_interface::{ + command_transfer_value::{support_types::Function, CommandTransferValue}, + Command, + }, + status::State, + App, +}; +use cli_log::trace; +use crossterm::event::Event as CrosstermEvent; +use handlers::{command, function, input, lua_command, matrix, setup}; +use tokio::sync::oneshot; -pub async fn poll_input_events( - channel: mpsc::Sender, - kill: CancellationToken, -) -> Result<()> { - async fn poll_input_events_stage_2(channel: mpsc::Sender) -> Result<()> { - loop { - if crossterm::event::poll(Duration::from_millis(100))? { - let event = Event::InputEvent(crossterm::event::read()?); - channel.send(event).await?; - } else { - tokio::task::yield_now().await; - } +#[derive(Debug)] +pub enum Event { + InputEvent(CrosstermEvent), + MatrixEvent(matrix_sdk::deserialized_responses::SyncResponse), + CommandEvent(Command, Option>), + LuaCommand(String), + Function(Function), +} + +impl Event { + pub async fn handle(self, app: &mut App<'_>) -> Result { + trace!("Received event to handle: `{:#?}`", &self); + match self { + Event::MatrixEvent(event) => matrix::handle(app, &event) + .await + .with_context(|| format!("Failed to handle matrix event: `{:#?}`", event)), + + Event::CommandEvent(event, callback_tx) => command::handle(app, &event, callback_tx) + .await + .with_context(|| format!("Failed to handle command event: `{:#?}`", event)), + + Event::LuaCommand(lua_code) => lua_command::handle(app, lua_code.to_owned()) + .await + .with_context(|| format!("Failed to handle lua code: `{}`", lua_code)), + Event::Function(function) => function::handle(app, function.to_owned()) + .await + .with_context(|| format!("Failed to handle function: `{}`", function)), + + Event::InputEvent(event) => match app.status.state() { + State::Setup => setup::handle(app, &event).await.with_context(|| { + format!("Failed to handle input (setup) event: `{:#?}`", event) + }), + _ => input::handle(app, &event).await.with_context(|| { + format!("Failed to handle input (non-setup) event: `{:#?}`", event) + }), + }, } } - tokio::select! { - output = poll_input_events_stage_2(channel) => output, - _ = kill.cancelled() => bail!("received kill signal") - } } -pub async fn poll_matrix_events( - channel: mpsc::Sender, - kill: CancellationToken, - client: Client, -) -> Result<()> { - async fn poll_matrix_events_stage_2( - channel: mpsc::Sender, - client: Client, - ) -> Result<()> { - let sync_settings = SyncSettings::default(); - // .token(sync_token) - // .timeout(Duration::from_secs(30)); - - let tx = &channel; - - client - .sync_with_callback(sync_settings, |response| async move { - let event = Event::MatrixEvent(response); - - match tx.send(event).await { - Ok(_) => LoopCtrl::Continue, - Err(_) => LoopCtrl::Break, - } - }) - .await?; - - Ok(()) - } - tokio::select! { - output = poll_matrix_events_stage_2(channel, client) => output, - _ = kill.cancelled() => bail!("received kill signal"), - } +#[derive(Debug)] +pub enum EventStatus { + Ok, + Finished, + Terminate, } diff --git a/src/app/mod.rs b/src/app/mod.rs index fd9c8b0..f53c258 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,7 +1,7 @@ pub mod command_interface; -pub mod keymappings; pub mod config; pub mod events; +pub mod keymappings; pub mod status; use std::{ @@ -20,12 +20,12 @@ use self::{ command_interface::{ command_transfer_value::support_types::Function, lua_command_manager::LuaCommandManager, }, - events::event_types, keymappings::trie::Node, + keymappings::trie::Node, }; use crate::{ accounts::{Account, AccountsManager}, app::{ - events::event_types::Event, + events::{Event, EventStatus}, status::{State, Status}, }, ui::{central, setup}, @@ -83,7 +83,7 @@ impl App<'_> { pub async fn run(&mut self, cli_lua_config_file: Option) -> Result<()> { // Spawn input event listener - tokio::task::spawn(events::poll_input_events( + tokio::task::spawn(events::listeners::input::poll( self.tx.clone(), self.input_listener_killer.clone(), )); @@ -131,8 +131,8 @@ impl App<'_> { let event = self.rx.recv().await.context("Failed to get next event")?; match event.handle(self).await? { - event_types::EventStatus::Ok => (), - event_types::EventStatus::Terminate => break, + EventStatus::Ok => (), + EventStatus::Terminate => break, _ => todo!(), }; } @@ -152,11 +152,9 @@ impl App<'_> { let event = self.rx.recv().await.context("Failed to get next event")?; match event.handle(self).await? { - event_types::EventStatus::Ok => (), - event_types::EventStatus::Finished => return Ok(()), - event_types::EventStatus::Terminate => { - return Err(Error::msg("Terminated by user")) - } + EventStatus::Ok => (), + EventStatus::Finished => return Ok(()), + EventStatus::Terminate => return Err(Error::msg("Terminated by user")), } } } @@ -172,7 +170,7 @@ impl App<'_> { self.matrix_listener_killer = CancellationToken::new(); // Spawn Matrix Event Listener - tokio::task::spawn(events::poll_matrix_events( + tokio::task::spawn(events::listeners::matrix::poll( self.tx.clone(), self.matrix_listener_killer.clone(), client.clone(),