maked stdout sync and send and tested it
This commit is contained in:
parent
18103fced3
commit
81aa62b6ce
@ -11,7 +11,7 @@ exclude = ["target", "Cargo.lock"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
lazy_static = "1.1.0"
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
|
winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
//! - Run program with: `cargo run --example examples`
|
//! - Run program with: `cargo run --example examples`
|
||||||
|
|
||||||
extern crate crossterm;
|
extern crate crossterm;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
// modules that could be test
|
// modules that could be test
|
||||||
mod terminal;
|
mod terminal;
|
||||||
@ -16,27 +18,59 @@ mod some_types;
|
|||||||
mod input;
|
mod input;
|
||||||
|
|
||||||
use crossterm::{Screen, Crossterm};
|
use crossterm::{Screen, Crossterm};
|
||||||
|
use crossterm::terminal::{Terminal, ClearType};
|
||||||
|
use crossterm::cursor::TerminalCursor;
|
||||||
|
|
||||||
use std::{time, thread};
|
use std::{time, thread};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
use std::sync::{Arc,Mutex};
|
||||||
use crossterm::cursor::cursor;
|
use crossterm::cursor::cursor;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let nthreads = 5;
|
let input = CROSSTERM.input();
|
||||||
let (tx, rx) = mpsc::channel();
|
let mut stdin = input.read_async().bytes();
|
||||||
|
CROSSTERM.cursor().hide();
|
||||||
|
|
||||||
|
let mut input_buf = Arc::new(Mutex::new(String::new()));
|
||||||
|
|
||||||
for i in 0..nthreads {
|
loop
|
||||||
let tx = tx.clone();
|
{
|
||||||
thread::spawn(move || {
|
let a = stdin.next();
|
||||||
let response = Crossterm::new(&Screen::default());
|
|
||||||
tx.send(response).unwrap();
|
swap_write("dddd", &input_buf.lock().unwrap());
|
||||||
});
|
|
||||||
|
match a {
|
||||||
|
Some(Ok(b'\r')) =>
|
||||||
|
{
|
||||||
|
input_buf.lock().unwrap().clear();
|
||||||
|
|
||||||
|
// need to start receiving again because if pressed enter then async reading will stop
|
||||||
|
stdin = input.read_async().bytes();
|
||||||
|
}
|
||||||
|
Some(Ok(val)) =>
|
||||||
|
{
|
||||||
|
input_buf.lock().unwrap().push(val as char);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..nthreads {
|
thread::sleep(time::Duration::from_millis(100));
|
||||||
let screen: Crossterm = rx.recv().unwrap();
|
}
|
||||||
screen.terminal();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn swap_write(msg: &str, input_buf: &String) {
|
||||||
|
let term = CROSSTERM.terminal();
|
||||||
|
let (_, term_height) = term.terminal_size();
|
||||||
|
CROSSTERM.cursor().goto(0, term_height);
|
||||||
|
term.clear(ClearType::CurrentLine);
|
||||||
|
term.write(format!("{}\r\n", msg));
|
||||||
|
term.write(format!(">{}", input_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CROSSTERM: Crossterm = {
|
||||||
|
let screen = Screen::new(true);
|
||||||
|
Crossterm::new(&screen)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ pub fn get_current_handle(screen_manager: &Arc<Stdout>) -> Result<HANDLE> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
handle = Ok(*winapi_screen_manager.get_handle());
|
handle = Ok(winapi_screen_manager.get_handle());
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ 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 + Sync>>(
|
let screen_manager: Box<IStdout + Send + Sync> = 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();
|
||||||
@ -87,13 +87,13 @@ impl Default for Stdout
|
|||||||
/// Get the default handle to the current screen.
|
/// Get the default handle to the current screen.
|
||||||
fn default() -> Self {
|
fn default() -> 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: false}
|
Stdout { screen_manager , is_in_raw_mode: false}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ 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: Arc<Mutex<HANDLE>>,
|
pub handle: Mutex<HANDLE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IStdout for WinApiStdout {
|
impl IStdout for WinApiStdout {
|
||||||
@ -38,19 +38,21 @@ impl IStdout for WinApiStdout {
|
|||||||
|
|
||||||
impl WinApiStdout {
|
impl WinApiStdout {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
WinApiStdout { handle: Arc::new(Mutex::new(handle::get_output_handle().unwrap())) }
|
WinApiStdout { handle: Mutex::new(handle::get_output_handle().unwrap()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, handle: HANDLE)
|
pub fn set(&mut self, handle: HANDLE)
|
||||||
{
|
{
|
||||||
self.handle = Arc::new(Mutex::new(handle));
|
self.handle = Mutex::new(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_handle(&self) -> &Arc<Mutex<HANDLE>>
|
pub fn get_handle(&self) -> HANDLE
|
||||||
{
|
{
|
||||||
return &self.handle;
|
let gx = self.handle.lock();
|
||||||
|
gx.unwrap().clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for WinApiStdout {}
|
unsafe impl Send for WinApiStdout {}
|
||||||
|
|
||||||
unsafe impl Sync for WinApiStdout {}
|
unsafe impl Sync for WinApiStdout {}
|
||||||
|
Loading…
Reference in New Issue
Block a user