diff options
author | qkzk <qu3nt1n@gmail.com> | 2024-02-23 19:34:21 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2024-02-23 19:34:21 +0100 |
commit | e271a8b29ee5a178fd9e02ca2827649f5898f420 (patch) | |
tree | 2acc41b32ceddeaaaae051e7661037bfac546dfd | |
parent | 658f94aa591cb354edb1773140b1e0befaa35ed3 (diff) |
wrap event into mpsc
-rw-r--r-- | development.md | 3 | ||||
-rw-r--r-- | src/app/application.rs | 10 | ||||
-rw-r--r-- | src/event/event_dispatch.rs | 10 | ||||
-rw-r--r-- | src/event/event_poller.rs | 24 | ||||
-rw-r--r-- | src/event/events.rs | 15 | ||||
-rw-r--r-- | src/event/mod.rs | 2 |
6 files changed, 52 insertions, 12 deletions
diff --git a/development.md b/development.md index e3ca0c8..3b401da 100644 --- a/development.md +++ b/development.md @@ -918,6 +918,9 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. - [x] FIX: entering sort doesn't set focus - [x] update config from build file by removing references to removed binds. - [x] move to encrypted drive when mounting is successful +- [ ] wrap event into an MPSC to allow internal events + - [x] wrap + - [ ] send/receive custom event ## TODO diff --git a/src/app/application.rs b/src/app/application.rs index 7b00f93..f14c467 100644 --- a/src/app/application.rs +++ b/src/app/application.rs @@ -13,8 +13,10 @@ use crate::common::CONFIG_PATH; use crate::common::{clear_tmp_file, init_term}; use crate::config::load_config; use crate::config::START_FOLDER; +use crate::event::init_events; use crate::event::EventDispatcher; use crate::event::EventReader; +use crate::event::FmEvents; use crate::io::set_loggers; use crate::io::Opener; use crate::log_info; @@ -53,6 +55,7 @@ impl FM { /// /// May fail if the [`tuikit::prelude::term`] can't be started or crashes pub fn start() -> Result<Self> { + let (fm_sender, fm_receiver) = init_events(); set_loggers()?; let Ok(config) = load_config(CONFIG_PATH) else { exit_wrong_config() @@ -62,7 +65,8 @@ impl FM { startfolder = &START_FOLDER.display() ); let term = Arc::new(init_term()?); - let event_reader = EventReader::new(term.clone()); + let fm_sender = Arc::new(fm_sender); + let event_reader = EventReader::new(term.clone(), fm_receiver); let event_dispatcher = EventDispatcher::new(config.binds.clone()); let opener = Opener::new(&config.terminal, &config.terminal_flag); let status = Arc::new(Mutex::new(Status::new( @@ -89,12 +93,12 @@ impl FM { /// # Errors /// /// May fail if the terminal crashes - fn poll_event(&self) -> Result<Event, TuikitError> { + fn poll_event(&self) -> Result<FmEvents> { self.event_reader.poll_event() } /// Update itself, changing its status. - fn update(&mut self, event: Event) -> Result<()> { + fn update(&mut self, event: FmEvents) -> Result<()> { match self.status.lock() { Ok(mut status) => { self.event_dispatcher.dispatch(&mut status, event)?; diff --git a/src/event/event_dispatch.rs b/src/event/event_dispatch.rs index 6d7d359..fe8ad71 100644 --- a/src/event/event_dispatch.rs +++ b/src/event/event_dispatch.rs @@ -6,6 +6,8 @@ use crate::config::{Bindings, REFRESH_KEY}; use crate::event::event_exec::EventAction; use crate::modes::{Display, Edit, InputCompleted, InputSimple, MarkAction, Navigate, Search}; +use super::FmEvents; + /// Struct which mutates `tabs.selected().. /// Holds a mapping which can't be static since it's read from a config file. /// All keys are mapped to relevent events on tabs.selected(). @@ -25,10 +27,12 @@ impl EventDispatcher { /// Only non keyboard events are dealt here directly. /// Keyboard events are configurable and are sent to specific functions /// which needs to know those keybindings. - pub fn dispatch(&self, status: &mut Status, ev: Event) -> Result<()> { + pub fn dispatch(&self, status: &mut Status, ev: FmEvents) -> Result<()> { match ev { - Event::Key(key) => self.match_key_event(status, key), - Event::Resize { width, height } => EventAction::resize(status, width, height), + FmEvents::Event(Event::Key(key)) => self.match_key_event(status, key), + FmEvents::Event(Event::Resize { width, height }) => { + EventAction::resize(status, width, height) + } _ => Ok(()), } } diff --git a/src/event/event_poller.rs b/src/event/event_poller.rs index 2526070..150ed64 100644 --- a/src/event/event_poller.rs +++ b/src/event/event_poller.rs @@ -1,24 +1,36 @@ +use std::sync::mpsc::Receiver; use std::sync::Arc; +use std::time::Duration; use anyhow::Result; -use tuikit::error::TuikitError; -use tuikit::event::Event; use tuikit::term::Term; +use crate::event::FmEvents; + /// Simple struct to read the events. pub struct EventReader { pub term: Arc<Term>, + pub fm_receiver: Receiver<FmEvents>, } impl EventReader { /// Creates a new instance with an Arc to a terminal. - pub fn new(term: Arc<Term>) -> Self { - Self { term } + pub fn new(term: Arc<Term>, fm_receiver: Receiver<FmEvents>) -> Self { + Self { term, fm_receiver } } /// Returns the events as they're received. Wait indefinitely for a new one. /// We should spend most of the application life here, doing nothing :) - pub fn poll_event(&self) -> Result<Event, TuikitError> { - self.term.poll_event() + pub fn poll_event(&self) -> Result<FmEvents> { + loop { + match self.fm_receiver.recv() { + Ok(event) => return Ok(event), + Err(_) => (), + } + match self.term.peek_event(Duration::from_millis(100)) { + Ok(event) => return Ok(FmEvents::Event(event)), + Err(_) => (), + } + } } } diff --git a/src/event/events.rs b/src/event/events.rs new file mode 100644 index 0000000..1f40ae9 --- /dev/null +++ b/src/event/events.rs @@ -0,0 +1,15 @@ +use std::sync::mpsc; +use std::sync::mpsc::{Receiver, Sender}; + +use tuikit::event::Event; + +pub enum FmEvents { + Refresh, + BulkExecute, + Event(Event), +} + +pub fn init_events() -> (Sender<FmEvents>, Receiver<FmEvents>) { + let (sender, receiver) = mpsc::channel::<FmEvents>(); + (sender, receiver) +} diff --git a/src/event/mod.rs b/src/event/mod.rs index e12b9c6..bd8dae1 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -2,8 +2,10 @@ mod action_map; mod event_dispatch; mod event_exec; mod event_poller; +mod events; pub use action_map::ActionMap; pub use event_dispatch::EventDispatcher; pub use event_exec::EventAction; pub use event_poller::EventReader; +pub use events::{init_events, FmEvents}; |