From b83003a8ecfb1538bbd026ba3eb776096d7359ac Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 6 Jan 2022 16:52:09 +0200 Subject: [PATCH] Fix notification event ordering Use a single thread instead of spawning a new task for each notification. This makes sure they are processed in the correct order. --- src/bridge/handler.rs | 83 ++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 28 deletions(-) diff --git a/src/bridge/handler.rs b/src/bridge/handler.rs index ef77302..f4cc55f 100644 --- a/src/bridge/handler.rs +++ b/src/bridge/handler.rs @@ -1,8 +1,11 @@ use async_trait::async_trait; +use futures::lock::Mutex; use log::trace; use nvim_rs::{Handler, Neovim}; use rmpv::Value; -use tokio::task; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::Arc; +use std::thread; #[cfg(windows)] use crate::bridge::ui_commands::{ParallelCommand, UiCommand}; @@ -14,12 +17,54 @@ use crate::{ settings::SETTINGS, }; +struct NotificationEvent { + event_name: String, + arguments: Vec, +} + #[derive(Clone)] -pub struct NeovimHandler {} +pub struct NeovimHandler { + sender: Arc>>, +} impl NeovimHandler { pub fn new() -> Self { - Self {} + let (sender, receiver): (Sender, Receiver) = + channel(); + thread::spawn(|| { + for event in receiver { + match event.event_name.as_ref() { + "redraw" => { + for events in event.arguments { + let parsed_events = parse_redraw_event(events) + .unwrap_or_explained_panic("Could not parse event from neovim"); + + for parsed_event in parsed_events { + EVENT_AGGREGATOR + .send(EditorCommand::NeovimRedrawEvent(parsed_event)); + } + } + } + "setting_changed" => { + SETTINGS.handle_changed_notification(event.arguments); + } + #[cfg(windows)] + "neovide.register_right_click" => { + EVENT_AGGREGATOR + .send(UiCommand::Parallel(ParallelCommand::RegisterRightClick)); + } + #[cfg(windows)] + "neovide.unregister_right_click" => { + EVENT_AGGREGATOR + .send(UiCommand::Parallel(ParallelCommand::UnregisterRightClick)); + } + _ => {} + } + } + }); + Self { + sender: Arc::new(Mutex::new(sender)), + } } } @@ -34,30 +79,12 @@ impl Handler for NeovimHandler { _neovim: Neovim, ) { trace!("Neovim notification: {:?}", &event_name); - - task::spawn_blocking(move || match event_name.as_ref() { - "redraw" => { - for events in arguments { - let parsed_events = parse_redraw_event(events) - .unwrap_or_explained_panic("Could not parse event from neovim"); - - for parsed_event in parsed_events { - EVENT_AGGREGATOR.send(EditorCommand::NeovimRedrawEvent(parsed_event)); - } - } - } - "setting_changed" => { - SETTINGS.handle_changed_notification(arguments); - } - #[cfg(windows)] - "neovide.register_right_click" => { - EVENT_AGGREGATOR.send(UiCommand::Parallel(ParallelCommand::RegisterRightClick)); - } - #[cfg(windows)] - "neovide.unregister_right_click" => { - EVENT_AGGREGATOR.send(UiCommand::Parallel(ParallelCommand::UnregisterRightClick)); - } - _ => {} - }); + let sender = self.sender.lock().await; + sender + .send(NotificationEvent { + event_name, + arguments, + }) + .ok(); } }