switch to tokio channel and add resizing debouncing

macos-click-through
Keith Simmons 5 years ago
parent 376664e65d
commit 54212f73f5

@ -12,9 +12,7 @@ mod ui_commands;
#[macro_use] extern crate rust_embed; #[macro_use] extern crate rust_embed;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
//use std::thread;
use std::process::Stdio; use std::process::Stdio;
use std::sync::mpsc::{channel, Receiver};
use async_trait::async_trait; use async_trait::async_trait;
use rmpv::Value; use rmpv::Value;
@ -22,6 +20,7 @@ use nvim_rs::{create::tokio as create, Neovim, UiAttachOptions, Handler, compat:
use tokio::process::{ChildStdin, Command}; use tokio::process::{ChildStdin, Command};
use tokio::task::spawn_blocking; use tokio::task::spawn_blocking;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender, UnboundedReceiver};
use window::ui_loop; use window::ui_loop;
use editor::Editor; use editor::Editor;
@ -51,14 +50,9 @@ fn create_nvim_command() -> Command {
cmd cmd
} }
#[derive(Clone)]
struct NeovimHandler(Arc<Mutex<Editor>>); struct NeovimHandler(Arc<Mutex<Editor>>);
impl Clone for NeovimHandler {
fn clone(&self) -> Self {
NeovimHandler(Arc::clone(&self.0))
}
}
#[async_trait] #[async_trait]
impl Handler for NeovimHandler { impl Handler for NeovimHandler {
type Writer = Compat<ChildStdin>; type Writer = Compat<ChildStdin>;
@ -73,7 +67,7 @@ impl Handler for NeovimHandler {
} }
} }
async fn start_nvim(editor: Arc<Mutex<Editor>>, receiver: Arc<Mutex<Receiver<UiCommand>>>) { async fn start_nvim(editor: Arc<Mutex<Editor>>, mut receiver: UnboundedReceiver<UiCommand>) {
let (mut nvim, io_handler, _) = create::new_child_cmd(&mut create_nvim_command(), NeovimHandler(editor.clone())).await let (mut nvim, io_handler, _) = create::new_child_cmd(&mut create_nvim_command(), NeovimHandler(editor.clone())).await
.unwrap_or_explained_panic("Could not create nvim process", "Could not locate or start the neovim process"); .unwrap_or_explained_panic("Could not create nvim process", "Could not locate or start the neovim process");
@ -95,16 +89,21 @@ async fn start_nvim(editor: Arc<Mutex<Editor>>, receiver: Arc<Mutex<Receiver<UiC
.unwrap_or_explained_panic("Could not attach.", "Could not attach ui to neovim process"); .unwrap_or_explained_panic("Could not attach.", "Could not attach ui to neovim process");
loop { loop {
let receiver = receiver.clone(); let mut commands = Vec::new();
let r = spawn_blocking(move || { let mut resize_command = None;
let receiver = receiver.lock().unwrap(); while let Ok(ui_command) = receiver.try_recv() {
receiver.recv() if let UiCommand::Resize { .. } = ui_command {
}).await.expect("Could not await blocking call"); resize_command = Some(ui_command);
} else {
commands.push(ui_command);
}
}
if let Some(resize_command) = resize_command {
commands.push(resize_command);
}
if let Ok(ui_command) = r { for ui_command in commands.iter() {
ui_command.execute(&nvim).await; ui_command.execute(&nvim).await;
} else {
return
} }
} }
} }
@ -113,9 +112,8 @@ fn main() {
let rt = Runtime::new().unwrap(); let rt = Runtime::new().unwrap();
let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT)));
let (sender, receiver) = channel::<UiCommand>(); let (sender, receiver) = unbounded_channel::<UiCommand>();
let editor_clone = editor.clone(); let editor_clone = editor.clone();
let receiver = Arc::new(Mutex::new(receiver));
rt.spawn(async move { rt.spawn(async move {
start_nvim(editor_clone, receiver).await; start_nvim(editor_clone, receiver).await;
}); });

@ -2,7 +2,7 @@ use nvim_rs::Neovim;
use nvim_rs::compat::tokio::Compat; use nvim_rs::compat::tokio::Compat;
use tokio::process::ChildStdin; use tokio::process::ChildStdin;
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum UiCommand { pub enum UiCommand {
Resize { width: i64, height: i64 }, Resize { width: i64, height: i64 },
Keyboard(String), Keyboard(String),

@ -8,7 +8,7 @@ use skulpin::winit::dpi::LogicalSize;
use skulpin::winit::event::{ElementState, Event, MouseScrollDelta, StartCause, WindowEvent}; use skulpin::winit::event::{ElementState, Event, MouseScrollDelta, StartCause, WindowEvent};
use skulpin::winit::event_loop::{ControlFlow, EventLoop}; use skulpin::winit::event_loop::{ControlFlow, EventLoop};
use skulpin::winit::window::{Icon, WindowBuilder}; use skulpin::winit::window::{Icon, WindowBuilder};
use std::sync::mpsc::Sender; use tokio::sync::mpsc::UnboundedSender;
use crate::editor::Editor; use crate::editor::Editor;
use crate::keybindings::construct_keybinding_string; use crate::keybindings::construct_keybinding_string;
@ -21,7 +21,7 @@ struct Asset;
const EXTRA_LIVE_FRAMES: usize = 10; const EXTRA_LIVE_FRAMES: usize = 10;
fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, command_channel: &mut Sender<UiCommand>) { fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, command_channel: &mut UnboundedSender<UiCommand>) {
if new_size.width > 0.0 && new_size.height > 0.0 { if new_size.width > 0.0 && new_size.height > 0.0 {
let new_width = ((new_size.width + 1.0) as f32 / renderer.font_width) as u64; let new_width = ((new_size.width + 1.0) as f32 / renderer.font_width) as u64;
let new_height = ((new_size.height + 1.0) as f32 / renderer.font_height) as u64; let new_height = ((new_size.height + 1.0) as f32 / renderer.font_height) as u64;
@ -30,7 +30,7 @@ fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, command_chan
} }
} }
pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: Sender<UiCommand>, initial_size: (u64, u64)) { pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<UiCommand>, initial_size: (u64, u64)) {
let mut renderer = Renderer::new(editor.clone()); let mut renderer = Renderer::new(editor.clone());
let event_loop = EventLoop::<()>::with_user_event(); let event_loop = EventLoop::<()>::with_user_event();
@ -41,7 +41,6 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: Sender<UiCommand
); );
let icon = { let icon = {
dbg!(Asset::iter().map(|file| file.to_string()).collect::<Vec<String>>());
let icon_data = Asset::get("nvim.ico").expect("Failed to read icon data"); let icon_data = Asset::get("nvim.ico").expect("Failed to read icon data");
let icon = load_from_memory(&icon_data).expect("Failed to parse icon data"); let icon = load_from_memory(&icon_data).expect("Failed to parse icon data");
let (width, height) = icon.dimensions(); let (width, height) = icon.dimensions();

Loading…
Cancel
Save