pub async fn run<F, A, T>(self, start: F) -> Result<T, Error>
    where
        F: FnOnce(Terminal) -> A + Send + 'static,
        A: Future<Output = T> + Send + 'static,
        T: Send + 'static,
    {
        // Ensures there are no other terminal sevices executing.
        let _guard = RunGuard::acquire()?;

        // Initializes terminal structures.
        let initial_size = self.initial_size()?;
        let terminal = self.finish(initial_size).await;
        let shared = terminal.shared.clone();
        shared.screen().setup().await?;

        // Synchronization between parties.
        let barrier = Arc::new(Barrier::new(3));

        // Event listener task future.
        let events_fut = {
            let interval = self.event_interval;
            let barrier = barrier.clone();
            let shared = shared.clone();
            tokio::spawn(events_task(barrier, interval, shared, initial_size))
        };

        // Renderer task future.
        let renderer_fut = {
            let barrier = barrier.clone();
            let shared = shared.clone();
            tokio::spawn(renderer_task(barrier, shared))
        };

        // Main task future.
        let main_fut = {
            let barrier = barrier.clone();
            tokio::spawn(main_task(barrier, terminal, start))
        };

        // Joins every task.
        let (main_ret, events_ret, renderer_ret) =
            tokio::join!(main_fut, events_fut, renderer_fut);

        // Cleans up screen configurations (such as raw mode).
        let _ = shared.screen().cleanup().await;

        // Matches the error of events task result.
        if let Err(error) = events_ret? {
            match error.kind() {
                ErrorKind::ServicesOff(_) => (),
                _ => Err(error)?,
            }
        }

        // Matches the error of renderer task result.
        if let Err(error) = renderer_ret? {
            match error.kind() {
                ErrorKind::ServicesOff(_) => (),
                _ => Err(error)?,
            }
        }

        // Finally returns main task return value.
        Ok(main_ret?)
    }
/// Starts the application and gives it a handle to the terminal. When the
/// given start function finishes, the application's execution stops as
/// well.
///
/// After that `start`'s future returns, terminal services such as screen
/// handle and events handle are not guaranteed to be available. One would
/// prefer spawning tasks that use the terminal handle by joining them, and
/// not detaching.
///
/// Returns an [`AlreadyRunning`] error if there is already an instance of
/// terminal services executing. In other words, one should not call
/// this function again if another call did not finish yet, otherwise it
/// will panic.
///
/// Beware! If the given `start` future returns a `Result`, then `run` will
/// return a double `Result`!!
Starts the application and gives it a handle to the terminal. When the
given start function finishes, the application's execution stops as
well.

After that `start`'s future returns, terminal services such as screen
handle and events handle are not guaranteed to be available. One would
prefer spawning tasks that use the terminal handle by joining them, and
not detaching.

Returns an [`AlreadyRunning`] error if there is already an instance of
terminal services executing. In other words, one should not call
this function again if another call did not finish yet, otherwise it
will panic.

Beware.
Starts the application and gives it a handle to the terminal . When the given start function finishes the application ' s execution stops as well . After that ` start ` ' s future returns terminal services such as screen handle and events handle are not guaranteed to be available . One would prefer spawning tasks that use the terminal handle by joining them and not detaching . Returns an [ ` AlreadyRunning ` ] error if there is already an instance of terminal services executing . In other words one should not call this function again if another call did not finish yet otherwise it will panic . Beware .
pub async fn run<F, A, T>(self, start: F) -> Result<T, Error>
    where
        F: FnOnce(Terminal) -> A + Send + 'static,
        A: Future<Output = T> + Send + 'static,
        T: Send + 'static,
    {
        // Ensures there are no other terminal sevices executing.
        let _guard = RunGuard::acquire()?;
        // Initializes terminal structures.
        let initial_size = self.initial_size()?;
        let terminal = self.finish(initial_size).await;
        let shared = terminal.shared.clone();
        shared.screen().setup().await?;
        // Synchronization between parties.
        let barrier = Arc::new(Barrier::new(3));
        // Event listener task future.
        let events_fut = {
            let interval = self.event_interval;
            let barrier = barrier.clone();
            let shared = shared.clone();
            tokio::spawn(events_task(barrier, interval, shared, initial_size))
        };
        // Renderer task future.
        let renderer_fut = {
            let barrier = barrier.clone();
            let shared = shared.clone();
            tokio::spawn(renderer_task(barrier, shared))
        };
        // Main task future.
        let main_fut = {
            let barrier = barrier.clone();
            tokio::spawn(main_task(barrier, terminal, start))
        };
        // Joins every task.
        let (main_ret, events_ret, renderer_ret) =
            tokio::join!(main_fut, events_fut, renderer_fut);
        // Cleans up screen configurations (such as raw mode).
        let _ = shared.screen().cleanup().await;
        // Matches the error of events task result.
        if let Err(error) = events_ret? {
            match error.kind() {
                ErrorKind::ServicesOff(_) => (),
                _ => Err(error)?,
            }
        }
        // Matches the error of renderer task result.
        if let Err(error) = renderer_ret? {
            match error.kind() {
                ErrorKind::ServicesOff(_) => (),
                _ => Err(error)?,
            }
        }
        // Finally returns main task return value.
        Ok(main_ret?)
    }
pub async fn run < F , A , T > ( self , start : F ) -> Result < T , Error > where F : FnOnce ( Terminal ) -> A + Send + ' static , A : Future < Output = T > + Send + ' static , T : Send + ' static , { // Ensures there are no other terminal sevices executing. let _guard = RunGuard :: acquire ( ) ? ; // Initializes terminal structures. let initial_size = self . initial_size ( ) ? ; let terminal = self . finish ( initial_size ) . await ; let shared = terminal . shared . clone ( ) ; shared . screen ( ) . setup ( ) . await ? ; // Synchronization between parties. let barrier = Arc :: new ( Barrier :: new ( 3 ) ) ; // Event listener task future. let events_fut = { let interval = self . event_interval ; let barrier = barrier . clone ( ) ; let shared = shared . clone ( ) ; tokio :: spawn ( events_task ( barrier , interval , shared , initial_size ) ) } ; // Renderer task future. let renderer_fut = { let barrier = barrier . clone ( ) ; let shared = shared . clone ( ) ; tokio :: spawn ( renderer_task ( barrier , shared ) ) } ; // Main task future. let main_fut = { let barrier = barrier . clone ( ) ; tokio :: spawn ( main_task ( barrier , terminal , start ) ) } ; // Joins every task. let ( main_ret , events_ret , renderer_ret ) = tokio :: join ! ( main_fut events_fut renderer_fut ) ; // Cleans up screen configurations (such as raw mode). let _ = shared . screen ( ) . cleanup ( ) . await ; // Matches the error of events task result. if let Err ( error ) = events_ret ? { match error . kind ( ) { ErrorKind :: ServicesOff ( _ ) => ( ) , _ => Err ( error ) ? , } } // Matches the error of renderer task result. if let Err ( error ) = renderer_ret ? { match error . kind ( ) { ErrorKind :: ServicesOff ( _ ) => ( ) , _ => Err ( error ) ? , } } // Finally returns main task return value. Ok ( main_ret ? ) }
Starts the application and gives it a handle to the terminal.
Starts the application and gives it a handle to the terminal .
self
start
F
self
start
F