This commit is contained in:
TimonPost 2018-08-18 12:54:06 +02:00
parent 25bf065c09
commit 18103fced3
4 changed files with 27 additions and 49 deletions

View File

@ -17,10 +17,26 @@ mod input;
use crossterm::{Screen, Crossterm}; use crossterm::{Screen, Crossterm};
use std::{time, thread}; use std::{time, thread};
use std::sync::mpsc;
use crossterm::cursor::cursor; use crossterm::cursor::cursor;
fn main() { fn main() {
let nthreads = 5;
let (tx, rx) = mpsc::channel();
thread::sleep(time::Duration::from_millis(2000));
for i in 0..nthreads {
let tx = tx.clone();
thread::spawn(move || {
let response = Crossterm::new(&Screen::default());
tx.send(response).unwrap();
});
}
for _ in 0..nthreads {
let screen: Crossterm = rx.recv().unwrap();
screen.terminal();
}
} }

View File

@ -60,42 +60,4 @@ pub struct RawModeCommand {
original_mode: Result<Termios>, original_mode: Result<Termios>,
} }
impl RawModeCommand
{
pub fn new() -> Self {
RawModeCommand {
original_mode: terminal::get_terminal_mode(),
}
}
}
impl RawModeCommand {
/// Enables raw mode.
pub fn enable(&mut self) -> Result<()> {
if let Ok(original_mode) = self.original_mode {
let mut new_mode = original_mode;
terminal::make_raw(&mut new_mode);
terminal::set_terminal_mode(&new_mode);
} else {
return Err(Error::new(
ErrorKind::Other,
"Could not set console mode when enabling raw mode",
));
}
Ok(())
}
/// Disables raw mode.
pub fn disable(&self) -> Result<()> {
if let Ok(ref original_mode) = self.original_mode {
let result = terminal::set_terminal_mode(&original_mode)?;
} else {
return Err(Error::new(
ErrorKind::Other,
"Could not set console mode when enabling raw mode",
));
}
Ok(())
}
}

View File

@ -35,7 +35,7 @@ use std::sync::Arc;
/// ///
/// For unix and windows 10 `stdout()` will be used for handle when on windows systems with versions lower than 10 WinApi `HANDLE` will be used. /// For unix and windows 10 `stdout()` will be used for handle when on windows systems with versions lower than 10 WinApi `HANDLE` will be used.
pub struct Stdout { pub struct Stdout {
screen_manager: Box<IStdout + Send>, screen_manager: Box<IStdout + Send + Sync>,
pub is_in_raw_mode:bool, pub is_in_raw_mode:bool,
} }
@ -43,13 +43,13 @@ impl Stdout {
/// Create new screen write instance whereon screen related actions can be performed. /// Create new screen write instance whereon screen related actions can be performed.
pub fn new(is_in_raw_mode: bool) -> Self { pub fn new(is_in_raw_mode: bool) -> Self {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let screen_manager = functions::get_module::<Box<IStdout + Send>>( let screen_manager = functions::get_module::<Box<IStdout + Send + Sync>>(
Box::from(WinApiStdout::new()), Box::from(WinApiStdout::new()),
Box::from(AnsiStdout::new()), Box::from(AnsiStdout::new()),
).unwrap(); ).unwrap();
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let screen_manager = Box::from(AnsiStdout::new()) as Box<IStdout + Send>; let screen_manager = Box::from(AnsiStdout::new()) as Box<IStdout + Send + Sync>;
Stdout { screen_manager , is_in_raw_mode} Stdout { screen_manager , is_in_raw_mode}
} }

View File

@ -6,11 +6,11 @@ use winapi::um::winnt::HANDLE;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::any::Any; use std::any::Any;
use std::io::{self, Write}; use std::io::{self, Write};
use std::sync::Arc; use std::sync::{Mutex,Arc, };
/// This struct is a wrapper for WINAPI `HANDLE` /// This struct is a wrapper for WINAPI `HANDLE`
pub struct WinApiStdout { pub struct WinApiStdout {
pub handle: HANDLE, pub handle: Arc<Mutex<HANDLE>>,
} }
impl IStdout for WinApiStdout { impl IStdout for WinApiStdout {
@ -20,7 +20,7 @@ impl IStdout for WinApiStdout {
} }
fn write(&self, buf: &[u8]) -> io::Result<usize> { fn write(&self, buf: &[u8]) -> io::Result<usize> {
writing::write_char_buffer(&self.handle, buf) writing::write_char_buffer(&self.handle.lock().unwrap(), buf)
} }
fn flush(&self) -> io::Result<()> { fn flush(&self) -> io::Result<()> {
@ -38,19 +38,19 @@ impl IStdout for WinApiStdout {
impl WinApiStdout { impl WinApiStdout {
pub fn new() -> Self { pub fn new() -> Self {
WinApiStdout { handle: handle::get_output_handle().unwrap() } WinApiStdout { handle: Arc::new(Mutex::new(handle::get_output_handle().unwrap())) }
} }
pub fn set(&mut self, handle: HANDLE) pub fn set(&mut self, handle: HANDLE)
{ {
self.handle = handle; self.handle = Arc::new(Mutex::new(handle));
} }
pub fn get_handle(&self) -> &HANDLE pub fn get_handle(&self) -> &Arc<Mutex<HANDLE>>
{ {
return &self.handle; return &self.handle;
} }
} }
unsafe impl Send for WinApiStdout {} unsafe impl Send for WinApiStdout {}
unsafe impl Sync for WinApiStdout {}