diff --git a/src/bridge/mod.rs b/src/bridge/mod.rs index 364f418..1060cf2 100644 --- a/src/bridge/mod.rs +++ b/src/bridge/mod.rs @@ -10,7 +10,7 @@ use rmpv::Value; use nvim_rs::{create::tokio as create, UiAttachOptions}; use tokio::runtime::Runtime; use tokio::process::Command; -use tokio::sync::mpsc::UnboundedReceiver; +use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; pub use events::*; pub use keybindings::*; @@ -37,9 +37,9 @@ fn create_nvim_command() -> Command { cmd } -async fn start_process(editor: Arc>, mut receiver: UnboundedReceiver, grid_dimensions: (u64, u64)) { +pub async fn start_process(editor: Arc>, mut receiver: UnboundedReceiver, grid_dimensions: (u64, u64)) { 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"); tokio::spawn(async move { @@ -80,10 +80,24 @@ async fn start_process(editor: Arc>, mut receiver: UnboundedReceiv } } -pub fn start_nvim(editor: Arc>, receiver: UnboundedReceiver, grid_dimensions: (u64, u64)) { - let rt = Runtime::new().unwrap(); +pub struct Bridge { + runtime: Runtime, + sender: UnboundedSender +} - rt.spawn(async move { - start_process(editor, receiver, grid_dimensions).await; - }); +impl Bridge { + pub fn new(editor: Arc>, grid_dimensions: (u64, u64)) -> Bridge { + let runtime = Runtime::new().unwrap(); + let (sender, receiver) = unbounded_channel::(); + + 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); + } } diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 13c5074..43675c8 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -57,7 +57,7 @@ pub struct Editor { } impl Editor { - pub fn new(width: u64, height: u64) -> Editor { + pub fn new(dimensions: (u64, u64)) -> Editor { let mut editor = Editor { grid: Vec::new(), dirty: Vec::new(), @@ -68,7 +68,7 @@ impl Editor { command_line: CommandLine::new(), title: "Neovide".to_string(), cursor: Cursor::new(), - size: (width, height), + size: dimensions, font_name: None, font_size: None, default_colors: Colors::new(Some(colors::WHITE), Some(colors::BLACK), Some(colors::GREY)), diff --git a/src/main.rs b/src/main.rs index d98c073..dfe385a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,20 +11,14 @@ mod error_handling; use std::sync::{Arc, Mutex}; -use tokio::runtime::Runtime; -use tokio::sync::mpsc::unbounded_channel; - use window::ui_loop; use editor::Editor; -use bridge::{start_nvim, UiCommand}; +use bridge::Bridge; -const INITIAL_WIDTH: u64 = 100; -const INITIAL_HEIGHT: u64 = 50; +const INITIAL_DIMENSIONS: (u64, u64) = (100, 50); fn main() { - let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT))); - let (sender, receiver) = unbounded_channel::(); - let editor_clone = editor.clone(); - start_nvim(editor_clone, receiver, (INITIAL_WIDTH, INITIAL_HEIGHT)); - ui_loop(editor, sender, (INITIAL_WIDTH, INITIAL_HEIGHT)); + let editor = Arc::new(Mutex::new(Editor::new(INITIAL_DIMENSIONS))); + let bridge = Bridge::new(editor.clone(), INITIAL_DIMENSIONS); + ui_loop(editor, bridge, INITIAL_DIMENSIONS); } diff --git a/src/window.rs b/src/window.rs index 68fe1c3..c2c8576 100644 --- a/src/window.rs +++ b/src/window.rs @@ -8,10 +8,9 @@ use skulpin::winit::dpi::LogicalSize; use skulpin::winit::event::{ElementState, Event, MouseScrollDelta, StartCause, WindowEvent}; use skulpin::winit::event_loop::{ControlFlow, EventLoop}; use skulpin::winit::window::{Icon, WindowBuilder}; -use tokio::sync::mpsc::UnboundedSender; use crate::editor::Editor; -use crate::bridge::construct_keybinding_string; +use crate::bridge::{construct_keybinding_string, Bridge}; use crate::renderer::Renderer; use crate::bridge::UiCommand; @@ -21,16 +20,16 @@ struct Asset; const EXTRA_LIVE_FRAMES: usize = 10; -fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, command_channel: &mut UnboundedSender) { +fn handle_new_grid_size(new_size: LogicalSize, renderer: &Renderer, bridge: &mut Bridge) { 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_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 - 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>, mut command_channel: UnboundedSender, initial_size: (u64, u64)) { +pub fn ui_loop(editor: Arc>, mut bridge: Bridge, initial_size: (u64, u64)) { let mut renderer = Renderer::new(editor.clone()); let event_loop = EventLoop::<()>::with_user_event(); @@ -94,7 +93,7 @@ pub fn ui_loop(editor: Arc>, mut command_channel: UnboundedSender< 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 { @@ -106,7 +105,7 @@ pub fn ui_loop(editor: Arc>, mut command_channel: UnboundedSender< } => { construct_keybinding_string(input) .map(UiCommand::Keyboard) - .map(|keybinding_string| command_channel.send(keybinding_string)); + .map(|keybinding_string| bridge.queue_command(keybinding_string)); }, Event::WindowEvent { @@ -120,7 +119,7 @@ pub fn ui_loop(editor: Arc>, mut command_channel: UnboundedSender< let grid_x = (position.y as f32 / renderer.font_height) as i64; mouse_pos = (grid_x, grid_y); 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>, mut command_channel: UnboundedSender< } }; 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 { @@ -161,7 +160,7 @@ pub fn ui_loop(editor: Arc>, mut command_channel: UnboundedSender< }; 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 { @@ -173,7 +172,7 @@ pub fn ui_loop(editor: Arc>, mut command_channel: UnboundedSender< }; 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>, mut command_channel: UnboundedSender< } 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 {