diff options
| author | Aram Drevekenin <aram@poor.dev> | 2022-12-06 22:29:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-06 22:29:57 +0100 |
| commit | b1ab4eac1041db4b550bb51eb0801500b39fa683 (patch) | |
| tree | c2bde6be7735f46392991436a55dda97f115e0cd /zellij-server/src/plugins | |
| parent | docs(changelog): plugin loading data flow (diff) | |
| download | sl0ppij-b1ab4eac1041db4b550bb51eb0801500b39fa683.tar.gz sl0ppij-b1ab4eac1041db4b550bb51eb0801500b39fa683.tar.xz sl0ppij-b1ab4eac1041db4b550bb51eb0801500b39fa683.zip | |
refactor(messaging): reduce extraneous cross-thread messaging (#1996)
* refactor(messaging): reduce extraneous cross-thread messaging
* style(fmt): rustfmt
Diffstat (limited to 'zellij-server/src/plugins')
| -rw-r--r-- | zellij-server/src/plugins/mod.rs | 10 | ||||
| -rw-r--r-- | zellij-server/src/plugins/wasm_bridge.rs | 125 |
2 files changed, 71 insertions, 64 deletions
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index c5f3781e..100833ae 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -21,9 +21,9 @@ use zellij_utils::{ #[derive(Clone, Debug)] pub enum PluginInstruction { Load(RunPlugin, usize, ClientId, Size), // plugin metadata, tab_index, client_ids - Update(Option<u32>, Option<ClientId>, Event), // Focused plugin / broadcast, client_id, event data - Unload(u32), // plugin_id - Resize(u32, usize, usize), // plugin_id, columns, rows + Update(Vec<(Option<u32>, Option<ClientId>, Event)>), // Focused plugin / broadcast, client_id, event data + Unload(u32), // plugin_id + Resize(u32, usize, usize), // plugin_id, columns, rows AddClient(ClientId), RemoveClient(ClientId), NewTab( @@ -73,8 +73,8 @@ pub(crate) fn plugin_thread_main( PluginInstruction::Load(run, tab_index, client_id, size) => { wasm_bridge.load_plugin(&run, tab_index, size, client_id)?; }, - PluginInstruction::Update(pid, cid, event) => { - wasm_bridge.update_plugins(pid, cid, event)?; + PluginInstruction::Update(updates) => { + wasm_bridge.update_plugins(updates)?; }, PluginInstruction::Unload(pid) => { wasm_bridge.unload_plugin(pid)?; diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index 374b1dd4..098434a9 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -398,6 +398,7 @@ impl WasmBridge { } pub fn resize_plugin(&mut self, pid: u32, new_columns: usize, new_rows: usize) -> Result<()> { let err_context = || format!("failed to resize plugin {pid}"); + let mut plugin_bytes = vec![]; for ((plugin_id, client_id), (instance, plugin_env, (current_rows, current_columns))) in self.plugin_map.iter_mut() { @@ -418,84 +419,90 @@ impl WasmBridge { ]) .with_context(err_context)?; let rendered_bytes = wasi_read_string(&plugin_env.wasi_env); - drop(self.senders.send_to_screen(ScreenInstruction::PluginBytes( - *plugin_id, - *client_id, - rendered_bytes.as_bytes().to_vec(), - ))); + plugin_bytes.push((*plugin_id, *client_id, rendered_bytes.as_bytes().to_vec())); } } + let _ = self + .senders + .send_to_screen(ScreenInstruction::PluginBytes(plugin_bytes)); Ok(()) } pub fn update_plugins( &mut self, - pid: Option<u32>, - cid: Option<ClientId>, - event: Event, + mut updates: Vec<(Option<u32>, Option<ClientId>, Event)>, ) -> Result<()> { let err_context = || { if *DEBUG_MODE.get().unwrap_or(&true) { - format!("failed to update plugin state with event: {event:#?}") + format!("failed to update plugin state") } else { "failed to update plugin state".to_string() } }; - for (&(plugin_id, client_id), (instance, plugin_env, (rows, columns))) in &self.plugin_map { - let subs = plugin_env - .subscriptions - .lock() - .to_anyhow() - .with_context(err_context)?; - // FIXME: This is very janky... Maybe I should write my own macro for Event -> EventType? - let event_type = EventType::from_str(&event.to_string()).with_context(err_context)?; - if subs.contains(&event_type) - && ((pid.is_none() && cid.is_none()) - || (pid.is_none() && cid == Some(client_id)) - || (cid.is_none() && pid == Some(plugin_id)) - || (cid == Some(client_id) && pid == Some(plugin_id))) + let mut plugin_bytes = vec![]; + for (pid, cid, event) in updates.drain(..) { + for (&(plugin_id, client_id), (instance, plugin_env, (rows, columns))) in + &self.plugin_map { - let update = instance - .exports - .get_function("update") + let subs = plugin_env + .subscriptions + .lock() + .to_anyhow() .with_context(err_context)?; - wasi_write_object(&plugin_env.wasi_env, &event); - let update_return = update.call(&[]).or_else::<anyError, _>(|e| { - match e.downcast::<serde_json::Error>() { - Ok(_) => panic!( - "{}", - anyError::new(VersionMismatchError::new( - VERSION, - "Unavailable", - &plugin_env.plugin.path, - plugin_env.plugin.is_builtin(), - )) - ), - Err(e) => Err(e).with_context(err_context), - } - })?; - let should_render = match update_return.get(0) { - Some(Value::I32(n)) => *n == 1, - _ => false, - }; - - if *rows > 0 && *columns > 0 && should_render { - let render = instance + // FIXME: This is very janky... Maybe I should write my own macro for Event -> EventType? + let event_type = + EventType::from_str(&event.to_string()).with_context(err_context)?; + if subs.contains(&event_type) + && ((pid.is_none() && cid.is_none()) + || (pid.is_none() && cid == Some(client_id)) + || (cid.is_none() && pid == Some(plugin_id)) + || (cid == Some(client_id) && pid == Some(plugin_id))) + { + let update = instance .exports - .get_function("render") + .get_function("update") .with_context(err_context)?; - render - .call(&[Value::I32(*rows as i32), Value::I32(*columns as i32)]) - .with_context(err_context)?; - let rendered_bytes = wasi_read_string(&plugin_env.wasi_env); - drop(self.senders.send_to_screen(ScreenInstruction::PluginBytes( - plugin_id, - client_id, - rendered_bytes.as_bytes().to_vec(), - ))); + wasi_write_object(&plugin_env.wasi_env, &event); + let update_return = update.call(&[]).or_else::<anyError, _>(|e| { + match e.downcast::<serde_json::Error>() { + Ok(_) => panic!( + "{}", + anyError::new(VersionMismatchError::new( + VERSION, + "Unavailable", + &plugin_env.plugin.path, + plugin_env.plugin.is_builtin(), + )) + ), + Err(e) => Err(e).with_context(err_context), + } + })?; + let should_render = match update_return.get(0) { + Some(Value::I32(n)) => *n == 1, + _ => false, + }; + + if *rows > 0 && *columns > 0 && should_render { + let render = instance + .exports + .get_function("render") + .with_context(err_context)?; + render + .call(&[Value::I32(*rows as i32), Value::I32(*columns as i32)]) + .with_context(err_context)?; + let rendered_bytes = wasi_read_string(&plugin_env.wasi_env); + plugin_bytes.push(( + plugin_id, + client_id, + rendered_bytes.as_bytes().to_vec(), + )); + } } } } + let _ = self + .senders + .send_to_screen(ScreenInstruction::PluginBytes(plugin_bytes)); Ok(()) } pub fn remove_client(&mut self, client_id: ClientId) { @@ -673,11 +680,11 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) { send_plugin_instructions .unwrap() - .send(PluginInstruction::Update( + .send(PluginInstruction::Update(vec![( update_target, Some(client_id), Event::Timer(elapsed_time), - )) + )])) .unwrap(); }); } |
