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},
|
Raw::{DisplayOutput, RaiseError},
|
||||||
Trinitrix::Api,
|
Trinitrix::Api,
|
||||||
},
|
},
|
||||||
events::event_types::Event,
|
events::Event,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::command_transfer_value::support_types::Function;
|
use super::command_transfer_value::support_types::Function;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
use cli_log::info;
|
use cli_log::info;
|
||||||
use tokio::{fs, sync::mpsc::Sender};
|
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<()> {
|
pub async fn load(tx: Sender<Event>, path: PathBuf) -> Result<()> {
|
||||||
let lua_config_code = fs::read_to_string(&path).await?;
|
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},
|
command_transfer_value::{CommandTransferValue, Table},
|
||||||
Api, Command, Debug, Keymaps, Raw, Trinitrix, Ui,
|
Api, Command, Debug, Keymaps, Raw, Trinitrix, Ui,
|
||||||
},
|
},
|
||||||
events::event_types::EventStatus,
|
events::EventStatus,
|
||||||
keymappings::{
|
keymappings::{
|
||||||
key::{Key, Keys},
|
key::{Key, Keys},
|
||||||
trie::Node,
|
trie::Node,
|
|
@ -1,6 +1,8 @@
|
||||||
use anyhow::Result;
|
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
|
// 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>
|
// 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::{
|
use crate::app::{
|
||||||
command_interface::{Api::Raw, Command, Raw::SendInputUnprocessed, Trinitrix::Api},
|
command_interface::{Api::Raw, Command, Raw::SendInputUnprocessed, Trinitrix::Api},
|
||||||
events::event_types::{Event, EventStatus},
|
events::{Event, EventStatus},
|
||||||
keymappings::key::{Key, Keys},
|
keymappings::key::{Key, Keys},
|
||||||
status::State,
|
status::State,
|
||||||
App,
|
App,
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cli_log::trace;
|
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.
|
// 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
|
// TODO(@Soispha): Move the lua executor thread code from app to this module
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use matrix_sdk::deserialized_responses::SyncResponse;
|
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> {
|
pub async fn handle(app: &mut App<'_>, sync: &SyncResponse) -> Result<EventStatus> {
|
||||||
for (m_room_id, m_room) in sync.rooms.join.iter() {
|
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 crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{events::event_types::EventStatus, App},
|
app::{events::EventStatus, App},
|
||||||
ui::setup,
|
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 anyhow::{Context, Result};
|
||||||
use matrix_sdk::{config::SyncSettings, Client, LoopCtrl};
|
|
||||||
use tokio::{sync::mpsc, time::Duration};
|
|
||||||
use tokio_util::sync::CancellationToken;
|
|
||||||
|
|
||||||
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(
|
#[derive(Debug)]
|
||||||
channel: mpsc::Sender<Event>,
|
pub enum Event {
|
||||||
kill: CancellationToken,
|
InputEvent(CrosstermEvent),
|
||||||
) -> Result<()> {
|
MatrixEvent(matrix_sdk::deserialized_responses::SyncResponse),
|
||||||
async fn poll_input_events_stage_2(channel: mpsc::Sender<Event>) -> Result<()> {
|
CommandEvent(Command, Option<oneshot::Sender<CommandTransferValue>>),
|
||||||
loop {
|
LuaCommand(String),
|
||||||
if crossterm::event::poll(Duration::from_millis(100))? {
|
Function(Function),
|
||||||
let event = Event::InputEvent(crossterm::event::read()?);
|
|
||||||
channel.send(event).await?;
|
|
||||||
} else {
|
|
||||||
tokio::task::yield_now().await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
#[derive(Debug)]
|
||||||
channel: mpsc::Sender<Event>,
|
pub enum EventStatus {
|
||||||
kill: CancellationToken,
|
Ok,
|
||||||
client: Client,
|
Finished,
|
||||||
) -> Result<()> {
|
Terminate,
|
||||||
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"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod command_interface;
|
pub mod command_interface;
|
||||||
pub mod keymappings;
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
pub mod keymappings;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -20,12 +20,12 @@ use self::{
|
||||||
command_interface::{
|
command_interface::{
|
||||||
command_transfer_value::support_types::Function, lua_command_manager::LuaCommandManager,
|
command_transfer_value::support_types::Function, lua_command_manager::LuaCommandManager,
|
||||||
},
|
},
|
||||||
events::event_types, keymappings::trie::Node,
|
keymappings::trie::Node,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
accounts::{Account, AccountsManager},
|
accounts::{Account, AccountsManager},
|
||||||
app::{
|
app::{
|
||||||
events::event_types::Event,
|
events::{Event, EventStatus},
|
||||||
status::{State, Status},
|
status::{State, Status},
|
||||||
},
|
},
|
||||||
ui::{central, setup},
|
ui::{central, setup},
|
||||||
|
@ -83,7 +83,7 @@ impl App<'_> {
|
||||||
|
|
||||||
pub async fn run(&mut self, cli_lua_config_file: Option<PathBuf>) -> Result<()> {
|
pub async fn run(&mut self, cli_lua_config_file: Option<PathBuf>) -> Result<()> {
|
||||||
// Spawn input event listener
|
// Spawn input event listener
|
||||||
tokio::task::spawn(events::poll_input_events(
|
tokio::task::spawn(events::listeners::input::poll(
|
||||||
self.tx.clone(),
|
self.tx.clone(),
|
||||||
self.input_listener_killer.clone(),
|
self.input_listener_killer.clone(),
|
||||||
));
|
));
|
||||||
|
@ -131,8 +131,8 @@ impl App<'_> {
|
||||||
|
|
||||||
let event = self.rx.recv().await.context("Failed to get next event")?;
|
let event = self.rx.recv().await.context("Failed to get next event")?;
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
EventStatus::Ok => (),
|
||||||
event_types::EventStatus::Terminate => break,
|
EventStatus::Terminate => break,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -152,11 +152,9 @@ impl App<'_> {
|
||||||
let event = self.rx.recv().await.context("Failed to get next event")?;
|
let event = self.rx.recv().await.context("Failed to get next event")?;
|
||||||
|
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
EventStatus::Ok => (),
|
||||||
event_types::EventStatus::Finished => return Ok(()),
|
EventStatus::Finished => return Ok(()),
|
||||||
event_types::EventStatus::Terminate => {
|
EventStatus::Terminate => return Err(Error::msg("Terminated by user")),
|
||||||
return Err(Error::msg("Terminated by user"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +170,7 @@ impl App<'_> {
|
||||||
self.matrix_listener_killer = CancellationToken::new();
|
self.matrix_listener_killer = CancellationToken::new();
|
||||||
|
|
||||||
// Spawn Matrix Event Listener
|
// Spawn Matrix Event Listener
|
||||||
tokio::task::spawn(events::poll_matrix_events(
|
tokio::task::spawn(events::listeners::matrix::poll(
|
||||||
self.tx.clone(),
|
self.tx.clone(),
|
||||||
self.matrix_listener_killer.clone(),
|
self.matrix_listener_killer.clone(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
|
|
Loading…
Reference in New Issue