From ae6192d698fb4ddbd8514eb4fff26543034d13de Mon Sep 17 00:00:00 2001 From: Kyle Sutherland-Cash Date: Sat, 1 May 2021 08:26:57 -0700 Subject: [PATCH] Use Bus type for screen thread --- src/common/mod.rs | 47 ++++++++++++++++++++++++++++++-------- src/common/screen.rs | 54 ++++++++++++++++---------------------------- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/common/mod.rs b/src/common/mod.rs index ba506e8b..2b8adf4e 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -119,6 +119,34 @@ pub enum AppInstruction { } pub struct Bus { + receiver: mpsc::Receiver<(T, ErrorContext)>, + to_screen: Option>, + to_pty: Option>, + to_plugin: Option>, + to_app: Option>, + os_input: Option>, +} + +impl Bus { + fn new( + receiver: mpsc::Receiver<(T, ErrorContext)>, + to_screen: Option<&SenderWithContext>, + to_pty: Option<&SenderWithContext>, + to_plugin: Option<&SenderWithContext>, + to_app: Option<&SenderWithContext>, + os_input: Option<&Box>, + ) -> Self { + Bus { + receiver, + to_screen: to_screen.cloned(), + to_pty: to_pty.cloned(), + to_plugin: to_plugin.cloned(), + to_app: to_app.cloned(), + os_input: os_input.cloned(), + } + } +} + /// Start Zellij with the specified [`OsApi`] and command-line arguments. // FIXME this should definitely be modularized and split into different functions. pub fn start(mut os_input: Box, opts: CliArgs) { @@ -263,25 +291,26 @@ pub fn start(mut os_input: Box, opts: CliArgs) { .name("screen".to_string()) .spawn({ let mut command_is_executing = command_is_executing.clone(); - let os_input = os_input.clone(); - let send_pty_instructions = send_pty_instructions.clone(); - let send_plugin_instructions = send_plugin_instructions.clone(); - let send_app_instructions = send_app_instructions.clone(); + let screen_bus = Bus::new( + receive_screen_instructions, + None, + Some(&send_pty_instructions), + Some(&send_plugin_instructions), + Some(&send_app_instructions), + Some(&os_input), + ); let max_panes = opts.max_panes; move || { let mut screen = Screen::new( - receive_screen_instructions, - send_pty_instructions, - send_plugin_instructions, - send_app_instructions, + screen_bus, &full_screen_ws, - os_input, max_panes, ModeInfo::default(), ); loop { let (event, mut err_ctx) = screen + .bus .receiver .recv() .expect("failed to receive event on channel"); diff --git a/src/common/screen.rs b/src/common/screen.rs index eee1166f..513368c7 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -6,6 +6,7 @@ use std::str; use std::sync::mpsc::Receiver; use super::{AppInstruction, SenderWithContext}; +use crate::common::Bus; use crate::os_input_output::OsApi; use crate::panes::PositionAndSize; use crate::pty_bus::{PtyInstruction, VteBytes}; @@ -62,51 +63,33 @@ pub enum ScreenInstruction { /// A [`Screen`] holds multiple [`Tab`]s, each one holding multiple [`panes`](crate::client::panes). /// It only directly controls which tab is active, delegating the rest to the individual `Tab`. pub struct Screen { - /// A [`ScreenInstruction`] and [`ErrorContext`] receiver. - pub receiver: Receiver<(ScreenInstruction, ErrorContext)>, + /// A Bus for sending and receiving messages with the other threads. + pub bus: Bus, /// An optional maximal amount of panes allowed per [`Tab`] in this [`Screen`] instance. max_panes: Option, /// A map between this [`Screen`]'s tabs and their ID/key. tabs: BTreeMap, - /// A [`PtyInstruction`] and [`ErrorContext`] sender. - pub send_pty_instructions: SenderWithContext, - /// A [`PluginInstruction`] and [`ErrorContext`] sender. - pub send_plugin_instructions: SenderWithContext, - /// An [`AppInstruction`] and [`ErrorContext`] sender. - pub send_app_instructions: SenderWithContext, /// The full size of this [`Screen`]. full_screen_ws: PositionAndSize, /// The index of this [`Screen`]'s active [`Tab`]. active_tab_index: Option, - /// The [`OsApi`] this [`Screen`] uses. - os_api: Box, mode_info: ModeInfo, } impl Screen { - // FIXME: This lint needs actual fixing! Maybe by bundling the Senders /// Creates and returns a new [`Screen`]. - #[allow(clippy::too_many_arguments)] pub fn new( - receive_screen_instructions: Receiver<(ScreenInstruction, ErrorContext)>, - send_pty_instructions: SenderWithContext, - send_plugin_instructions: SenderWithContext, - send_app_instructions: SenderWithContext, + bus: Bus, full_screen_ws: &PositionAndSize, - os_api: Box, max_panes: Option, mode_info: ModeInfo, ) -> Self { Screen { - receiver: receive_screen_instructions, + bus, max_panes, - send_pty_instructions, - send_plugin_instructions, - send_app_instructions, full_screen_ws: *full_screen_ws, active_tab_index: None, tabs: BTreeMap::new(), - os_api, mode_info, } } @@ -121,10 +104,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.os_api.clone(), - self.send_pty_instructions.clone(), - self.send_plugin_instructions.clone(), - self.send_app_instructions.clone(), + self.bus.os_input.as_ref().unwrap().clone(), + self.bus.to_pty.as_ref().unwrap().clone(), + self.bus.to_plugin.as_ref().unwrap().clone(), + self.bus.to_app.as_ref().unwrap().clone(), self.max_panes, Some(PaneId::Terminal(pane_id)), self.mode_info.clone(), @@ -207,11 +190,14 @@ impl Screen { // because this might be happening when the app is closing, at which point the pty thread // has already closed and this would result in an error let _ = self - .send_pty_instructions + .bus + .to_pty + .as_ref() + .unwrap() .send(PtyInstruction::CloseTab(pane_ids)); if self.tabs.is_empty() { self.active_tab_index = None; - self.send_app_instructions + self.bus.to_app.as_ref().unwrap() .send(AppInstruction::Exit) .unwrap(); } else { @@ -225,7 +211,7 @@ impl Screen { } pub fn resize_to_screen(&mut self) { - let new_screen_size = self.os_api.get_terminal_size_using_fd(0); + let new_screen_size = self.bus.os_input.as_ref().unwrap().get_terminal_size_using_fd(0); self.full_screen_ws = new_screen_size; for (_, tab) in self.tabs.iter_mut() { tab.resize_whole_tab(new_screen_size); @@ -276,10 +262,10 @@ impl Screen { position, String::new(), &self.full_screen_ws, - self.os_api.clone(), - self.send_pty_instructions.clone(), - self.send_plugin_instructions.clone(), - self.send_app_instructions.clone(), + self.bus.os_input.as_ref().unwrap().clone(), + self.bus.to_pty.as_ref().unwrap().clone(), + self.bus.to_plugin.as_ref().unwrap().clone(), + self.bus.to_app.as_ref().unwrap().clone(), self.max_panes, None, self.mode_info.clone(), @@ -301,7 +287,7 @@ impl Screen { is_sync_panes_active: tab.is_sync_panes_active(), }); } - self.send_plugin_instructions + self.bus.to_plugin.as_ref().unwrap() .send(PluginInstruction::Update(None, Event::TabUpdate(tab_data))) .unwrap(); }