diff --git a/Cargo.lock b/Cargo.lock index 3fe4632..c9c73ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -398,6 +398,7 @@ dependencies = [ "ciborium", "clap", "criterion-plot", + "futures", "is-terminal", "itertools 0.10.5", "num-traits", @@ -410,6 +411,7 @@ dependencies = [ "serde_derive", "serde_json", "tinytemplate", + "tokio", "walkdir", ] @@ -574,6 +576,20 @@ dependencies = [ "libc", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -581,6 +597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -637,6 +654,7 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", @@ -1452,7 +1470,7 @@ dependencies = [ [[package]] name = "ratatui-image" version = "1.0.0" -source = "git+https://github.com/itsjunetime/ratatui-image.git?branch=vb64_on_personal#e5c13ed29c9decdff093c2be5d673d84fb3589a9" +source = "git+https://github.com/itsjunetime/ratatui-image.git?branch=vb64_on_personal#88876c749898cce7801379345eb4e0bc69111b8a" dependencies = [ "base64 0.22.1", "dyn-clone", diff --git a/Cargo.toml b/Cargo.toml index 8f8f047..7358c45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ default = [] tracing = ["tokio/tracing", "dep:console-subscriber"] [dev-dependencies] -criterion = "0.5.1" +criterion = { version = "0.5.1", features = ["async_tokio"] } [[bench]] name = "rendering" diff --git a/benches/rendering.rs b/benches/rendering.rs index 0f4bd8e..4a98081 100644 --- a/benches/rendering.rs +++ b/benches/rendering.rs @@ -1,25 +1,19 @@ mod utils; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use utils::{render_doc, render_first_page}; -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; - const FILES: [&str; 2] = [ - "./benches/example_dictionary.pdf", - "./benches/adobe_example.pdf" + "benches/example_dictionary.pdf", + "benches/adobe_example.pdf" ]; fn render_full(c: &mut Criterion) { for file in FILES { - c.bench_with_input( - BenchmarkId::new("render_full", file), - &file, - |b, &file| b.iter(|| - tokio::runtime::Runtime::new() - .unwrap() - .block_on(render_doc(file)) - ) - ); + c.bench_with_input(BenchmarkId::new("render_full", file), &file, |b, &file| { + b.to_async(tokio::runtime::Runtime::new().unwrap()) + .iter(|| render_doc(file)) + }); } } @@ -28,18 +22,17 @@ fn render_to_first_page(c: &mut Criterion) { c.bench_with_input( BenchmarkId::new("render_first_page", file), &file, - |b, &file| b.iter(|| - tokio::runtime::Runtime::new() - .unwrap() - .block_on(render_first_page(file)) - ) + |b, &file| { + b.to_async(tokio::runtime::Runtime::new().unwrap()) + .iter(|| render_first_page(file)) + } ); } } criterion_group!( name = benches; - config = Criterion::default().sample_size(10); + config = Criterion::default().sample_size(40); targets = render_full, render_to_first_page ); criterion_main!(benches); diff --git a/benches/utils.rs b/benches/utils.rs index ca43048..c15d86f 100644 --- a/benches/utils.rs +++ b/benches/utils.rs @@ -2,21 +2,24 @@ use std::{hint::black_box, path::Path}; use crossterm::terminal::WindowSize; use flume::{r#async::RecvStream, unbounded, Sender}; +use futures_util::stream::StreamExt as _; use ratatui::layout::Rect; use ratatui_image::picker::{Picker, ProtocolType}; -use tdf::{converter::{run_conversion_loop, ConvertedPage, ConverterMsg}, renderer::{fill_default, start_rendering, RenderError, RenderInfo, RenderNotif}}; -use futures_util::stream::StreamExt as _; +use tdf::{ + converter::{run_conversion_loop, ConvertedPage, ConverterMsg}, + renderer::{fill_default, start_rendering, RenderError, RenderInfo, RenderNotif} +}; fn handle_renderer_msg( msg: Result, pages: &mut Vec>, - to_converter_tx: &mut Sender, + to_converter_tx: &mut Sender ) { match msg { Ok(RenderInfo::NumPages(num)) => { fill_default(pages, num); to_converter_tx.send(ConverterMsg::NumPages(num)).unwrap(); - }, + } Ok(RenderInfo::Page(info)) => to_converter_tx.send(ConverterMsg::AddImg(info)).unwrap(), Err(e) => panic!("Got error from renderer: {e:?}") } @@ -32,13 +35,13 @@ fn handle_converter_msg( pages[num] = Some(page); - let num_got = pages.iter() - .filter(|p| p.is_some()) - .count(); + let num_got = pages.iter().filter(|p| p.is_some()).count(); // we have to tell it to jump to a certain page so that it will actually render it (since // it only renders fanning out from the page that we currently have selected) - to_converter_tx.send(ConverterMsg::GoToPage(num_got)).unwrap(); + to_converter_tx + .send(ConverterMsg::GoToPage(num_got)) + .unwrap(); } struct RenderState { @@ -66,9 +69,7 @@ fn start_all_rendering(path: impl AsRef) -> RenderState { width: columns * font_size.0 }; - std::thread::spawn(move || { - start_rendering(str_path, to_main_tx, from_main_rx, size) - }); + std::thread::spawn(move || start_rendering(str_path, to_main_tx, from_main_rx, size)); let (to_converter_tx, from_main_rx) = unbounded(); let (to_main_tx, from_converter_rx) = unbounded(); diff --git a/ratatui-image b/ratatui-image index e5c13ed..88876c7 160000 --- a/ratatui-image +++ b/ratatui-image @@ -1 +1 @@ -Subproject commit e5c13ed29c9decdff093c2be5d673d84fb3589a9 +Subproject commit 88876c749898cce7801379345eb4e0bc69111b8a diff --git a/src/converter.rs b/src/converter.rs index 55be9bb..a48deb7 100644 --- a/src/converter.rs +++ b/src/converter.rs @@ -1,8 +1,8 @@ use flume::{Receiver, SendError, Sender, TryRecvError}; +use futures_util::stream::StreamExt; use image::ImageFormat; use itertools::Itertools; use ratatui_image::{picker::Picker, protocol::Protocol, Resize}; -use futures_util::stream::StreamExt; use crate::renderer::{fill_default, PageInfo, RenderError}; @@ -67,7 +67,7 @@ pub async fn run_conversion_loop( // size for the area given, so to save ratatui the work of having to // resize it, we tell them to crop it to fit. let txt_img = picker - .new_protocol(dyn_img, img_area, Resize::Crop) + .new_protocol(dyn_img, img_area, Resize::None) .map_err(|e| { RenderError::Render(format!( "Couldn't convert DynamicImage to ratatui image: {e}" diff --git a/src/lib.rs b/src/lib.rs index 4f1e060..a9f3c82 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ #![feature(if_let_guard)] -pub mod renderer; pub mod converter; -pub mod tui; +pub mod renderer; pub mod skip; +pub mod tui; diff --git a/src/main.rs b/src/main.rs index e44e5e0..7098cac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,9 @@ async fn main() -> Result<(), Box> { #[cfg(feature = "tracing")] console_subscriber::init(); - let file = std::env::args().nth(1).ok_or("Program requires a file to process")?; + let file = std::env::args() + .nth(1) + .ok_or("Program requires a file to process")?; let path = PathBuf::from_str(&file)?.canonicalize()?; //let (watch_tx, render_rx) = tokio::sync::mpsc::unbounded_channel(); diff --git a/src/renderer.rs b/src/renderer.rs index 255de73..6d05e28 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -198,11 +198,10 @@ pub fn start_rendering( // We know this is in range 'cause we're iterating over it but we still just want // to be safe let Some(page) = doc.page(num as i32) else { - sender - .send(Err(RenderError::Render(format!( - "Couldn't get page {num} ({}) of doc?", - num as i32 - ))))?; + sender.send(Err(RenderError::Render(format!( + "Couldn't get page {num} ({}) of doc?", + num as i32 + ))))?; continue; }; @@ -242,7 +241,7 @@ pub fn start_rendering( render_ctx_to_png(ctx, &mut sender, (col_w, col_h), num) }); } - }, + } // And if we got an error, then obviously we need to propagate that Err(e) => sender.send(Err(RenderError::Render(e)))? } @@ -285,7 +284,7 @@ fn render_single_page_to_ctx( page: Page, search_term: &Option, already_rendered_no_results: bool, - (area_w, area_h): (f64, f64), + (area_w, area_h): (f64, f64) ) -> Result, String> { let mut result_rects = search_term .as_ref() @@ -393,9 +392,9 @@ fn render_ctx_to_png( let mut img_data = Vec::with_capacity((ctx.surface_height * ctx.surface_width) as usize); match ctx.surface.write_to_png(&mut img_data) { - Err(e) => sender.send(Err(RenderError::Render( - format!("Couldn't write surface to png: {e}") - ))), + Err(e) => sender.send(Err(RenderError::Render(format!( + "Couldn't write surface to png: {e}" + )))), Ok(()) => sender.send(Ok(RenderInfo::Page(PageInfo { img_data: ImageData { data: img_data,