diff --git a/src/cursive.rs b/src/cursive.rs index b0f647b..bec555d 100644 --- a/src/cursive.rs +++ b/src/cursive.rs @@ -15,6 +15,24 @@ use views::{self, LayerPosition}; /// Identifies a screen in the cursive root. pub type ScreenId = usize; +/// Asynchronous callback function trait. +/// +/// Every `FnOnce(&mut Cursive) -> () + Send` automatically +/// implements this. +/// +/// This is a workaround only because `Box` is not +/// working and `FnBox` is unstable. +pub trait CbFunc: Send { + /// Calls the function. + fn call_box(self: Box, &mut Cursive); +} + +impl () + Send> CbFunc for F { + fn call_box(self: Box, siv: &mut Cursive) { + (*self)(siv) + } +} + /// Central part of the cursive library. /// /// It initializes ncurses on creation and cleans up on drop. @@ -38,8 +56,8 @@ pub struct Cursive { backend: backend::Concrete, - cb_source: mpsc::Receiver>, - cb_sink: mpsc::Sender>, + cb_source: mpsc::Receiver>, + cb_sink: mpsc::Sender>, } new_default!(Cursive); @@ -80,8 +98,22 @@ impl Cursive { /// Note that you currently need to call [`set_fps`] to force cursive to /// regularly check for messages. /// + /// # Examples + /// + /// ```rust,no_run + /// # extern crate cursive; + /// # use cursive::*; + /// # fn main() { + /// let mut siv = Cursive::new(); + /// siv.set_fps(10); + /// + /// // quit() will be called during the next event cycle + /// siv.cb_sink().send(Box::new(|s: &mut Cursive| s.quit())); + /// # } + /// ``` + /// /// [`set_fps`]: #method.set_fps - pub fn cb_sink(&self) -> &mpsc::Sender> { + pub fn cb_sink(&self) -> &mpsc::Sender> { &self.cb_sink } @@ -526,8 +558,8 @@ impl Cursive { /// /// [`run(&mut self)`]: #method.run pub fn step(&mut self) { - if let Ok(cb) = self.cb_source.try_recv() { - cb(self); + while let Ok(cb) = self.cb_source.try_recv() { + cb.call_box(self); } // Do we need to redraw everytime? diff --git a/src/lib.rs b/src/lib.rs index 272184c..0134c96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,7 @@ mod utf8; #[doc(hidden)] pub mod backend; -pub use cursive::{Cursive, ScreenId}; +pub use cursive::{CbFunc, Cursive, ScreenId}; pub use printer::Printer; pub use with::With; pub use xy::XY;