//! Definitions and helpers for sending and receiving messages between threads. use crate::{ os_input_output::ServerOsApi, pty::PtyInstruction, screen::ScreenInstruction, wasm_vm::PluginInstruction, ServerInstruction, }; use zellij_utils::{channels, channels::SenderWithContext, errors::ErrorContext}; /// A container for senders to the different threads in zellij on the server side #[derive(Clone)] pub(crate) struct ThreadSenders { pub to_screen: Option>, pub to_pty: Option>, pub to_plugin: Option>, pub to_server: Option>, } impl ThreadSenders { pub fn send_to_screen( &self, instruction: ScreenInstruction, ) -> Result<(), channels::SendError<(ScreenInstruction, ErrorContext)>> { self.to_screen.as_ref().unwrap().send(instruction) } pub fn send_to_pty( &self, instruction: PtyInstruction, ) -> Result<(), channels::SendError<(PtyInstruction, ErrorContext)>> { self.to_pty.as_ref().unwrap().send(instruction) } pub fn send_to_plugin( &self, instruction: PluginInstruction, ) -> Result<(), channels::SendError<(PluginInstruction, ErrorContext)>> { self.to_plugin.as_ref().unwrap().send(instruction) } pub fn send_to_server( &self, instruction: ServerInstruction, ) -> Result<(), channels::SendError<(ServerInstruction, ErrorContext)>> { self.to_server.as_ref().unwrap().send(instruction) } } /// A container for a receiver, OS input and the senders to a given thread pub(crate) struct Bus { receivers: Vec>, pub senders: ThreadSenders, pub os_input: Option>, } impl Bus { pub fn new( receivers: Vec>, to_screen: Option<&SenderWithContext>, to_pty: Option<&SenderWithContext>, to_plugin: Option<&SenderWithContext>, to_server: Option<&SenderWithContext>, os_input: Option>, ) -> Self { Bus { receivers, senders: ThreadSenders { to_screen: to_screen.cloned(), to_pty: to_pty.cloned(), to_plugin: to_plugin.cloned(), to_server: to_server.cloned(), }, os_input: os_input.clone(), } } pub fn recv(&self) -> Result<(T, ErrorContext), channels::RecvError> { let mut selector = channels::Select::new(); self.receivers.iter().for_each(|r| { selector.recv(r); }); let oper = selector.select(); let idx = oper.index(); oper.recv(&self.receivers[idx]) } }