bridge struct to wrap tokio runtime and channel

macos-click-through
Keith Simmons 5 years ago
parent 35a675c8a4
commit 3efb6879dc

@ -10,7 +10,7 @@ use rmpv::Value;
use nvim_rs::{create::tokio as create, UiAttachOptions}; use nvim_rs::{create::tokio as create, UiAttachOptions};
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::mpsc::UnboundedReceiver; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
pub use events::*; pub use events::*;
pub use keybindings::*; pub use keybindings::*;
@ -37,9 +37,9 @@ fn create_nvim_command() -> Command {
cmd cmd
} }
async fn start_process(editor: Arc<Mutex<Editor>>, mut receiver: UnboundedReceiver<UiCommand>, grid_dimensions: (u64, u64)) { pub async fn start_process(editor: Arc<Mutex<Editor>>, mut receiver: UnboundedReceiver<UiCommand>, grid_dimensions: (u64, u64)) {
let (width, height) = grid_dimensions; let (width, height) = grid_dimensions;
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)).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");
tokio::spawn(async move { tokio::spawn(async move {
@ -80,10 +80,24 @@ async fn start_process(editor: Arc<Mutex<Editor>>, mut receiver: UnboundedReceiv
} }
} }
pub fn start_nvim(editor: Arc<Mutex<Editor>>, receiver: UnboundedReceiver<UiCommand>, grid_dimensions: (u64, u64)) { pub struct Bridge {
let rt = Runtime::new().unwrap(); runtime: Runtime,
sender: UnboundedSender<UiCommand>
}
rt.spawn(async move { impl Bridge {
start_process(editor, receiver, grid_dimensions).await; pub fn new(editor: Arc<Mutex<Editor>>, grid_dimensions: (u64, u64)) -> Bridge {
}); let runtime = Runtime::new().unwrap();
let (sender, receiver) = unbounded_channel::<UiCommand>();
runtime.spawn(async move {
start_process(editor, receiver, grid_dimensions).await;
});
Bridge { runtime, sender }
}
pub fn queue_command(&mut self, command: UiCommand) {
self.sender.send(command);
}
} }

@ -57,7 +57,7 @@ pub struct Editor {
} }
impl Editor { impl Editor {
pub fn new(width: u64, height: u64) -> Editor { pub fn new(dimensions: (u64, u64)) -> Editor {
let mut editor = Editor { let mut editor = Editor {
grid: Vec::new(), grid: Vec::new(),
dirty: Vec::new(), dirty: Vec::new(),
@ -68,7 +68,7 @@ impl Editor {
command_line: CommandLine::new(), command_line: CommandLine::new(),
title: "Neovide".to_string(), title: "Neovide".to_string(),
cursor: Cursor::new(), cursor: Cursor::new(),
size: (width, height), size: dimensions,
font_name: None, font_name: None,
font_size: None, font_size: None,
default_colors: Colors::new(Some(colors::WHITE), Some(colors::BLACK), Some(colors::GREY)), default_colors: Colors::new(Some(colors::WHITE), Some(colors::BLACK), Some(colors::GREY)),

@ -11,20 +11,14 @@ mod error_handling;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime;
use tokio::sync::mpsc::unbounded_channel;
use window::ui_loop; use window::ui_loop;
use editor::Editor; use editor::Editor;
use bridge::{start_nvim, UiCommand}; use bridge::Bridge;
const INITIAL_WIDTH: u64 = 100; const INITIAL_DIMENSIONS: (u64, u64) = (100, 50);
const INITIAL_HEIGHT: u64 = 50;
fn main() { fn main() {
let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); let editor = Arc::new(Mutex::new(Editor::new(INITIAL_DIMENSIONS)));
let (sender, receiver) = unbounded_channel::<UiCommand>(); let bridge = Bridge::new(editor.clone(), INITIAL_DIMENSIONS);
let editor_clone = editor.clone(); ui_loop(editor, bridge, INITIAL_DIMENSIONS);
start_nvim(editor_clone, receiver, (INITIAL_WIDTH, INITIAL_HEIGHT));
ui_loop(editor, sender, (INITIAL_WIDTH, INITIAL_HEIGHT));
} }

@ -8,10 +8,9 @@ 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 tokio::sync::mpsc::UnboundedSender;
use crate::editor::Editor; use crate::editor::Editor;
use crate::bridge::construct_keybinding_string; use crate::bridge::{construct_keybinding_string, Bridge};
use crate::renderer::Renderer; use crate::renderer::Renderer;
use crate::bridge::UiCommand; use crate::bridge::UiCommand;
@ -21,16 +20,16 @@ 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 UnboundedSender<UiCommand>) { fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, bridge: &mut Bridge) {
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;
// Add 1 here to make sure resizing doesn't change the grid size on startup // Add 1 here to make sure resizing doesn't change the grid size on startup
command_channel.send(UiCommand::Resize { width: new_width as i64, height: new_height as i64 }); bridge.queue_command(UiCommand::Resize { width: new_width as i64, height: new_height as i64 });
} }
} }
pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<UiCommand>, initial_size: (u64, u64)) { pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut bridge: Bridge, 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();
@ -94,7 +93,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
event: WindowEvent::Resized(new_size), event: WindowEvent::Resized(new_size),
.. ..
} => { } => {
handle_new_grid_size(new_size, &renderer, &mut command_channel) handle_new_grid_size(new_size, &renderer, &mut bridge)
}, },
Event::WindowEvent { Event::WindowEvent {
@ -106,7 +105,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
} => { } => {
construct_keybinding_string(input) construct_keybinding_string(input)
.map(UiCommand::Keyboard) .map(UiCommand::Keyboard)
.map(|keybinding_string| command_channel.send(keybinding_string)); .map(|keybinding_string| bridge.queue_command(keybinding_string));
}, },
Event::WindowEvent { Event::WindowEvent {
@ -120,7 +119,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
let grid_x = (position.y as f32 / renderer.font_height) as i64; let grid_x = (position.y as f32 / renderer.font_height) as i64;
mouse_pos = (grid_x, grid_y); mouse_pos = (grid_x, grid_y);
if mouse_down { if mouse_down {
command_channel.send(UiCommand::Drag(grid_x, grid_y)); bridge.queue_command(UiCommand::Drag(grid_x, grid_y));
} }
} }
@ -142,7 +141,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
} }
}; };
let (grid_x, grid_y) = mouse_pos; let (grid_x, grid_y) = mouse_pos;
command_channel.send(UiCommand::MouseButton { action: input_type.to_string(), position: (grid_x, grid_y) }); bridge.queue_command(UiCommand::MouseButton { action: input_type.to_string(), position: (grid_x, grid_y) });
} }
Event::WindowEvent { Event::WindowEvent {
@ -161,7 +160,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
}; };
if let Some(input_type) = vertical_input_type { if let Some(input_type) = vertical_input_type {
command_channel.send(UiCommand::Scroll { direction: input_type.to_string(), position: mouse_pos }); bridge.queue_command(UiCommand::Scroll { direction: input_type.to_string(), position: mouse_pos });
} }
let horizontal_input_type = if horizontal > 0.0 { let horizontal_input_type = if horizontal > 0.0 {
@ -173,7 +172,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
}; };
if let Some(input_type) = horizontal_input_type { if let Some(input_type) = horizontal_input_type {
command_channel.send(UiCommand::Scroll { direction: input_type.to_string(), position: mouse_pos }); bridge.queue_command(UiCommand::Scroll { direction: input_type.to_string(), position: mouse_pos });
} }
} }
@ -190,7 +189,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, mut command_channel: UnboundedSender<
} }
if draw_result.font_changed { if draw_result.font_changed {
handle_new_grid_size(window.inner_size(), &renderer, &mut command_channel) handle_new_grid_size(window.inner_size(), &renderer, &mut bridge)
} }
if live_frames > 0 { if live_frames > 0 {

Loading…
Cancel
Save