forked from trinitrix/core
refactor: restructured event sources
This commit is contained in:
parent
4e839d4e2c
commit
a538877b5b
|
@ -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;
|
||||
|
|
|
@ -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<Event>, path: PathBuf) -> Result<()> {
|
||||
let lua_config_code = fs::read_to_string(&path).await?;
|
||||
|
|
|
@ -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<oneshot::Sender<CommandTransferValue>>),
|
||||
LuaCommand(String),
|
||||
Function(Function),
|
||||
}
|
||||
|
||||
impl Event {
|
||||
pub async fn handle(self, app: &mut App<'_>) -> Result<EventStatus> {
|
||||
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)
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#[derive(Debug)]
|
||||
pub enum EventStatus {
|
||||
Ok,
|
||||
Finished,
|
||||
Terminate,
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
pub mod event;
|
||||
pub mod event_status;
|
||||
|
||||
pub use self::{event::*, event_status::*};
|
|
@ -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,
|
|
@ -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>
|
|
@ -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,
|
|
@ -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
|
|
@ -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<EventStatus> {
|
||||
for (m_room_id, m_room) in sync.rooms.join.iter() {
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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<Event>, kill: CancellationToken) -> Result<()> {
|
||||
async fn stage_2(channel: mpsc::Sender<Event>) -> 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")
|
||||
}
|
||||
}
|
|
@ -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<Event>,
|
||||
kill: CancellationToken,
|
||||
client: Client,
|
||||
) -> Result<()> {
|
||||
async fn stage_2(channel: mpsc::Sender<Event>, 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"),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod input;
|
||||
pub mod matrix;
|
|
@ -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<Event>,
|
||||
kill: CancellationToken,
|
||||
) -> Result<()> {
|
||||
async fn poll_input_events_stage_2(channel: mpsc::Sender<Event>) -> 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<oneshot::Sender<CommandTransferValue>>),
|
||||
LuaCommand(String),
|
||||
Function(Function),
|
||||
}
|
||||
|
||||
impl Event {
|
||||
pub async fn handle(self, app: &mut App<'_>) -> Result<EventStatus> {
|
||||
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<Event>,
|
||||
kill: CancellationToken,
|
||||
client: Client,
|
||||
) -> Result<()> {
|
||||
async fn poll_matrix_events_stage_2(
|
||||
channel: mpsc::Sender<Event>,
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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<PathBuf>) -> 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(),
|
||||
|
|
Loading…
Reference in New Issue