From 1ff70a96539c7b33b587374c86dfbbf17a70a65e Mon Sep 17 00:00:00 2001 From: TimonPost Date: Sat, 28 Jul 2018 09:54:05 +0200 Subject: [PATCH] started working on refactoringterminal --- src/terminal/ansi_terminal.rs | 72 ++++++++++++----------------- src/terminal/mod.rs | 11 ++--- src/terminal/terminal.rs | 56 ++++++++++------------- src/terminal/winapi_terminal.rs | 80 ++++++++++++++++----------------- 4 files changed, 98 insertions(+), 121 deletions(-) diff --git a/src/terminal/ansi_terminal.rs b/src/terminal/ansi_terminal.rs index ff6dc41..136c351 100644 --- a/src/terminal/ansi_terminal.rs +++ b/src/terminal/ansi_terminal.rs @@ -4,66 +4,52 @@ use super::super::cursor::cursor; use super::{ClearType, ITerminal, Rc}; use shared::functions; -use Context; +use ScreenManager; /// This struct is an ansi implementation for terminal related actions. -pub struct AnsiTerminal { - context: Rc, -} +pub struct AnsiTerminal; impl AnsiTerminal { - pub fn new(context: Rc) -> Box { - Box::from(AnsiTerminal { context: context }) + pub fn new() -> AnsiTerminal { + AnsiTerminal {} } } impl ITerminal for AnsiTerminal { - fn clear(&self, clear_type: ClearType) { - let mut screen_manager = self.context.screen_manager.lock().unwrap(); - { - match clear_type { - ClearType::All => { - screen_manager.write_str(csi!("2J")); - } - ClearType::FromCursorDown => { - screen_manager.write_str(csi!("J")); - } - ClearType::FromCursorUp => { - screen_manager.write_str(csi!("1J")); - } - ClearType::CurrentLine => { - screen_manager.write_str(csi!("2K")); - } - ClearType::UntilNewLine => { - screen_manager.write_str(csi!("K")); - } - }; - } + fn clear(&self, clear_type: ClearType, screen_manager: &ScreenManager) { + match clear_type { + ClearType::All => { + screen_manager.write_str(csi!("2J")); + } + ClearType::FromCursorDown => { + screen_manager.write_str(csi!("J")); + } + ClearType::FromCursorUp => { + screen_manager.write_str(csi!("1J")); + } + ClearType::CurrentLine => { + screen_manager.write_str(csi!("2K")); + } + ClearType::UntilNewLine => { + screen_manager.write_str(csi!("K")); + } + }; } - fn terminal_size(&self) -> (u16, u16) { + fn terminal_size(&self, screen_manager: &ScreenManager) -> (u16, u16) { functions::get_terminal_size(&self.context.screen_manager) } - fn scroll_up(&self, count: i16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}S"), count)); - } + fn scroll_up(&self, count: i16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}S"), count)); } - fn scroll_down(&self, count: i16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}T"), count)); - } + fn scroll_down(&self, count: i16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}T"), count)); } - fn set_size(&self, width: i16, height: i16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("8;{};{}t"), width, height)); - } + fn set_size(&self, width: i16, height: i16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("8;{};{}t"), width, height)); } fn exit(&self) { diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index 47ee25b..bba27a0 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -16,6 +16,7 @@ use self::ansi_terminal::AnsiTerminal; #[cfg(target_os = "windows")] use self::winapi_terminal::WinApiTerminal; use std::rc::Rc; +use ScreenManager; pub use self::terminal::terminal; use Context; @@ -39,15 +40,15 @@ pub enum ClearType { ///! so that cursor related actions can be preformed on both unix and windows systems. pub trait ITerminal { /// Clear the current cursor by specifying the clear type - fn clear(&self, clear_type: ClearType); + fn clear(&self, clear_type: ClearType, screen_manager: &ScreenManager); /// Get the terminal size (x,y) - fn terminal_size(&self) -> (u16, u16); + fn terminal_size(&self, screen_manager: &ScreenManager) -> (u16, u16); /// Scroll `n` lines up in the current terminal. - fn scroll_up(&self, count: i16); + fn scroll_up(&self, count: i16, screen_manager: &ScreenManager); /// Scroll `n` lines down in the current terminal. - fn scroll_down(&self, count: i16); + fn scroll_down(&self, count: i16,screen_manager: &ScreenManager); /// Resize terminal to the given width and height. - fn set_size(&self, width: i16, height: i16); + fn set_size(&self, width: i16, height: i16, screen_manager: &ScreenManager); /// Close the current terminal fn exit(&self); } diff --git a/src/terminal/terminal.rs b/src/terminal/terminal.rs index 240659f..a380956 100644 --- a/src/terminal/terminal.rs +++ b/src/terminal/terminal.rs @@ -12,26 +12,26 @@ use std::io::Write; use std::rc::Rc; /// Struct that stores an specific platform implementation for terminal related actions. -pub struct Terminal { +pub struct Terminal<'terminal> { terminal: Box, - context: Rc, + screen_manager: &'terminal ScreenManager, } -impl Terminal { +impl<'terminal> Terminal<'terminal> { /// Create new terminal instance whereon terminal related actions can be performed. - pub fn new(context: Rc) -> Terminal { + pub fn new(screen_manager: &'terminal ScreenManager) -> Terminal<'terminal> { #[cfg(target_os = "windows")] let terminal = functions::get_module::>( - WinApiTerminal::new(context.clone()), - AnsiTerminal::new(context.clone()), + Box::new(WinApiTerminal::new()), + Box::new(AnsiTerminal::new()), ).unwrap(); #[cfg(not(target_os = "windows"))] - let terminal = AnsiTerminal::new(context.clone()) as Box; + let terminal = AnsiTerminal::new() as Box; Terminal { terminal, - context: context, + screen_manager: screen_manager } } @@ -61,7 +61,7 @@ impl Terminal { /// /// ``` pub fn clear(&self, clear_type: ClearType) { - self.terminal.clear(clear_type); + self.terminal.clear(clear_type, &self.screen_manager); } /// Get the terminal size (x,y). @@ -82,7 +82,7 @@ impl Terminal { /// /// ``` pub fn terminal_size(&self) -> (u16, u16) { - return self.terminal.terminal_size(); + return self.terminal.terminal_size(&self.screen_manager); } /// Scroll `n` lines up in the current terminal. @@ -103,7 +103,7 @@ impl Terminal { /// /// ``` pub fn scroll_up(&self, count: i16) { - self.terminal.scroll_up(count); + self.terminal.scroll_up(count,&self.screen_manager); } /// Scroll `n` lines up in the current terminal. @@ -124,7 +124,7 @@ impl Terminal { /// /// ``` pub fn scroll_down(&self, count: i16) { - self.terminal.scroll_down(count); + self.terminal.scroll_down(count,&self.screen_manager); } /// Set the terminal size. Note that not all terminals can be set to a very small scale. @@ -145,7 +145,7 @@ impl Terminal { /// /// ``` pub fn set_size(&self, width: i16, height: i16) { - self.terminal.set_size(width, height); + self.terminal.set_size(width, height,&self.screen_manager); } /// Wraps an displayable object so it can be formatted with colors and attributes. @@ -176,12 +176,12 @@ impl Terminal { /// } /// /// ``` - pub fn paint(&self, val: D) -> style::StyledObject - where - D: fmt::Display, - { - style::ObjectStyle::new().apply_to(val, self.context.clone()) - } +// pub fn paint(&self, val: D) -> style::StyledObject +// where +// D: fmt::Display, +// { +// style::ObjectStyle::new().apply_to(val, self.context.clone()) +// } /// Exit the current process. /// @@ -220,17 +220,9 @@ impl Terminal { /// /// ``` pub fn write(&self, value: D) { - let mut mutex = &self.context.screen_manager; - { - let mut screen_manager = mutex.lock().unwrap(); - - use std::fmt::Write; - let mut string = String::new(); - write!(string, "{}", value).unwrap(); - - screen_manager.write_string(string); - screen_manager.flush(); - } + let mut string = String::new(); + write!(string, "{}", value).unwrap(); + self.screen_manager.write_string(string); } } @@ -255,6 +247,6 @@ impl Terminal { /// /// ``` /// -pub fn terminal(context: &Rc) -> Box { - Box::from(Terminal::new(context.clone())) +pub fn terminal(screen_manager: &ScreenManager) -> Terminal { + Terminal::new(screen_manager) } diff --git a/src/terminal/winapi_terminal.rs b/src/terminal/winapi_terminal.rs index 77171f0..36aa093 100644 --- a/src/terminal/winapi_terminal.rs +++ b/src/terminal/winapi_terminal.rs @@ -7,41 +7,39 @@ use super::{ClearType, ITerminal, Rc}; use cursor::cursor; use kernel::windows_kernel::{csbi, kernel, terminal, writing}; use winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT}; -use Context; +use ScreenManager; use std::sync::Mutex; /// This struct is an windows implementation for terminal related actions. -pub struct WinApiTerminal { - context: Rc, -} +pub struct WinApiTerminal; impl WinApiTerminal { - pub fn new(context: Rc) -> Box { - Box::from(WinApiTerminal { context }) + pub fn new() -> WinApiTerminal { + WinApiTerminal { } } } impl ITerminal for WinApiTerminal { - fn clear(&self, clear_type: ClearType) { - let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap(); - let pos = cursor(&self.context).pos(); + fn clear(&self, clear_type: ClearType, screen_manager: &ScreenManager) { + let csbi = csbi::get_csbi(screen_manager).unwrap(); + let pos = cursor(screen_manager).pos(); match clear_type { - ClearType::All => clear_entire_screen(csbi, &self.context), - ClearType::FromCursorDown => clear_after_cursor(pos, csbi, &self.context), - ClearType::FromCursorUp => clear_before_cursor(pos, csbi, &self.context), - ClearType::CurrentLine => clear_current_line(pos, csbi, &self.context), - ClearType::UntilNewLine => clear_until_line(pos, csbi, &self.context), + ClearType::All => clear_entire_screen(csbi, &screen_manager), + ClearType::FromCursorDown => clear_after_cursor(pos, csbi, screen_manager), + ClearType::FromCursorUp => clear_before_cursor(pos, csbi, screen_manager), + ClearType::CurrentLine => clear_current_line(pos, csbi, screen_manager), + ClearType::UntilNewLine => clear_until_line(pos, csbi, screen_manager), }; } - fn terminal_size(&self) -> (u16, u16) { - terminal::terminal_size(&self.context.screen_manager) + fn terminal_size(&self, screen_manager: &ScreenManager) -> (u16, u16) { + terminal::terminal_size(screen_manager) } - fn scroll_up(&self, count: i16) { - let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap(); + fn scroll_up(&self, count: i16, screen_manager: &ScreenManager) { + let csbi = csbi::get_csbi(&screen_manager).unwrap(); // Set srctWindow to the current window size and location. let mut srct_window = csbi.srWindow; @@ -52,15 +50,15 @@ impl ITerminal for WinApiTerminal { srct_window.Bottom = count; // move bottom down let success = - kernel::set_console_info(false, &mut srct_window, &self.context.screen_manager); + kernel::set_console_info(false, &mut srct_window, &screen_manager); if success { panic!("Something went wrong when scrolling down"); } } } - fn scroll_down(&self, count: i16) { - let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap(); + fn scroll_down(&self, count: i16, screen_manager: &ScreenManager) { + let csbi = csbi::get_csbi(&screen_manager).unwrap(); // Set srctWindow to the current window size and location. let mut srct_window = csbi.srWindow; @@ -75,7 +73,7 @@ impl ITerminal for WinApiTerminal { srct_window.Bottom += count; // move bottom down let success = - kernel::set_console_info(true, &mut srct_window, &self.context.screen_manager); + kernel::set_console_info(true, &mut srct_window, &screen_manager); if success { panic!("Something went wrong when scrolling down"); } @@ -83,7 +81,7 @@ impl ITerminal for WinApiTerminal { } /// Set the current terminal size - fn set_size(&self, width: i16, height: i16) { + fn set_size(&self, width: i16, height: i16, screen_manager: &ScreenManager) { if width <= 0 { panic!("Cannot set the terminal width lower than 1"); } @@ -93,7 +91,7 @@ impl ITerminal for WinApiTerminal { } // Get the position of the current console window - let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap(); + let csbi = csbi::get_csbi(&screen_manager).unwrap(); let mut success = false; // If the buffer is smaller than this new window size, resize the @@ -122,7 +120,7 @@ impl ITerminal for WinApiTerminal { } if resize_buffer { - success = csbi::set_console_screen_buffer_size(size, &self.context.screen_manager); + success = csbi::set_console_screen_buffer_size(size, &screen_manager); if !success { panic!("Something went wrong when setting screen buffer size."); @@ -134,12 +132,12 @@ impl ITerminal for WinApiTerminal { fsr_window.Bottom = fsr_window.Top + height; fsr_window.Right = fsr_window.Left + width; - let success = kernel::set_console_info(true, &fsr_window, &self.context.screen_manager); + let success = kernel::set_console_info(true, &fsr_window, &screen_manager); if success { // If we resized the buffer, un-resize it. if resize_buffer { - csbi::set_console_screen_buffer_size(csbi.dwSize, &self.context.screen_manager); + csbi::set_console_screen_buffer_size(csbi.dwSize, &screen_manager); } let bounds = kernel::get_largest_console_window_size(); @@ -167,7 +165,7 @@ impl ITerminal for WinApiTerminal { pub fn clear_after_cursor( pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, - context: &Rc, + screen_manager: &ScreenManager, ) { let (mut x, mut y) = pos; @@ -185,13 +183,13 @@ pub fn clear_after_cursor( // get sum cells before cursor let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32; - clear(start_location, cells_to_write, &context.screen_manager); + clear(start_location, cells_to_write, screen_manager); } pub fn clear_before_cursor( pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, - context: &Rc, + screen_manager: &ScreenManager, ) { let (xpos, ypos) = pos; @@ -208,10 +206,10 @@ pub fn clear_before_cursor( // get sum cells before cursor let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1); - clear(start_location, cells_to_write, &context.screen_manager); + clear(start_location, cells_to_write, &screen_manager); } -pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc) { +pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, screen_manager: &ScreenManager) { // position x at start let x = 0; // position y at start @@ -226,16 +224,16 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc, + screen_manager: &ScreenManager, ) { // position x at start let x = 0; @@ -251,13 +249,13 @@ pub fn clear_current_line( let cells_to_write = csbi.dwSize.X as u32; - clear(start_location, cells_to_write, &context.screen_manager); + clear(start_location, cells_to_write, screen_manager); // put the cursor back at 1 cell on current row - cursor(&context).goto(0, y); + cursor(&screen_manager).goto(0, y); } -pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc) { +pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, screen_manager: &ScreenManager) { let (x, y) = pos; // location where to start clearing @@ -268,13 +266,13 @@ pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, conte // get sum cells before cursor let cells_to_write = (csbi.dwSize.X - x as i16) as u32; - clear(start_location, cells_to_write, &context.screen_manager); + clear(start_location, cells_to_write, &screen_manager); // put the cursor back at original cursor position - cursor(&context).goto(x, y); + cursor(&screen_manager).goto(x, y); } -fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &Rc>) { +fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &ScreenManager) { let mut cells_written = 0; let mut success = false;