mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-01 23:51:46 -04:00
- Run fmt
- Use built-in async benching - Use custom Resize::None when making ratatui images to save some cycles
This commit is contained in:
Generated
+19
-1
@@ -398,6 +398,7 @@ dependencies = [
|
|||||||
"ciborium",
|
"ciborium",
|
||||||
"clap",
|
"clap",
|
||||||
"criterion-plot",
|
"criterion-plot",
|
||||||
|
"futures",
|
||||||
"is-terminal",
|
"is-terminal",
|
||||||
"itertools 0.10.5",
|
"itertools 0.10.5",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -410,6 +411,7 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tinytemplate",
|
"tinytemplate",
|
||||||
|
"tokio",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -574,6 +576,20 @@ dependencies = [
|
|||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.30"
|
version = "0.3.30"
|
||||||
@@ -581,6 +597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -637,6 +654,7 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
@@ -1452,7 +1470,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ratatui-image"
|
name = "ratatui-image"
|
||||||
version = "1.0.0"
|
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 = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ default = []
|
|||||||
tracing = ["tokio/tracing", "dep:console-subscriber"]
|
tracing = ["tokio/tracing", "dep:console-subscriber"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.5.1"
|
criterion = { version = "0.5.1", features = ["async_tokio"] }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "rendering"
|
name = "rendering"
|
||||||
|
|||||||
+12
-19
@@ -1,25 +1,19 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||||
use utils::{render_doc, render_first_page};
|
use utils::{render_doc, render_first_page};
|
||||||
|
|
||||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
|
||||||
|
|
||||||
const FILES: [&str; 2] = [
|
const FILES: [&str; 2] = [
|
||||||
"./benches/example_dictionary.pdf",
|
"benches/example_dictionary.pdf",
|
||||||
"./benches/adobe_example.pdf"
|
"benches/adobe_example.pdf"
|
||||||
];
|
];
|
||||||
|
|
||||||
fn render_full(c: &mut Criterion) {
|
fn render_full(c: &mut Criterion) {
|
||||||
for file in FILES {
|
for file in FILES {
|
||||||
c.bench_with_input(
|
c.bench_with_input(BenchmarkId::new("render_full", file), &file, |b, &file| {
|
||||||
BenchmarkId::new("render_full", file),
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
||||||
&file,
|
.iter(|| render_doc(file))
|
||||||
|b, &file| b.iter(||
|
});
|
||||||
tokio::runtime::Runtime::new()
|
|
||||||
.unwrap()
|
|
||||||
.block_on(render_doc(file))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,18 +22,17 @@ fn render_to_first_page(c: &mut Criterion) {
|
|||||||
c.bench_with_input(
|
c.bench_with_input(
|
||||||
BenchmarkId::new("render_first_page", file),
|
BenchmarkId::new("render_first_page", file),
|
||||||
&file,
|
&file,
|
||||||
|b, &file| b.iter(||
|
|b, &file| {
|
||||||
tokio::runtime::Runtime::new()
|
b.to_async(tokio::runtime::Runtime::new().unwrap())
|
||||||
.unwrap()
|
.iter(|| render_first_page(file))
|
||||||
.block_on(render_first_page(file))
|
}
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(
|
criterion_group!(
|
||||||
name = benches;
|
name = benches;
|
||||||
config = Criterion::default().sample_size(10);
|
config = Criterion::default().sample_size(40);
|
||||||
targets = render_full, render_to_first_page
|
targets = render_full, render_to_first_page
|
||||||
);
|
);
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|||||||
+12
-11
@@ -2,21 +2,24 @@ use std::{hint::black_box, path::Path};
|
|||||||
|
|
||||||
use crossterm::terminal::WindowSize;
|
use crossterm::terminal::WindowSize;
|
||||||
use flume::{r#async::RecvStream, unbounded, Sender};
|
use flume::{r#async::RecvStream, unbounded, Sender};
|
||||||
|
use futures_util::stream::StreamExt as _;
|
||||||
use ratatui::layout::Rect;
|
use ratatui::layout::Rect;
|
||||||
use ratatui_image::picker::{Picker, ProtocolType};
|
use ratatui_image::picker::{Picker, ProtocolType};
|
||||||
use tdf::{converter::{run_conversion_loop, ConvertedPage, ConverterMsg}, renderer::{fill_default, start_rendering, RenderError, RenderInfo, RenderNotif}};
|
use tdf::{
|
||||||
use futures_util::stream::StreamExt as _;
|
converter::{run_conversion_loop, ConvertedPage, ConverterMsg},
|
||||||
|
renderer::{fill_default, start_rendering, RenderError, RenderInfo, RenderNotif}
|
||||||
|
};
|
||||||
|
|
||||||
fn handle_renderer_msg(
|
fn handle_renderer_msg(
|
||||||
msg: Result<RenderInfo, RenderError>,
|
msg: Result<RenderInfo, RenderError>,
|
||||||
pages: &mut Vec<Option<ConvertedPage>>,
|
pages: &mut Vec<Option<ConvertedPage>>,
|
||||||
to_converter_tx: &mut Sender<tdf::converter::ConverterMsg>,
|
to_converter_tx: &mut Sender<tdf::converter::ConverterMsg>
|
||||||
) {
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
Ok(RenderInfo::NumPages(num)) => {
|
Ok(RenderInfo::NumPages(num)) => {
|
||||||
fill_default(pages, num);
|
fill_default(pages, num);
|
||||||
to_converter_tx.send(ConverterMsg::NumPages(num)).unwrap();
|
to_converter_tx.send(ConverterMsg::NumPages(num)).unwrap();
|
||||||
},
|
}
|
||||||
Ok(RenderInfo::Page(info)) => to_converter_tx.send(ConverterMsg::AddImg(info)).unwrap(),
|
Ok(RenderInfo::Page(info)) => to_converter_tx.send(ConverterMsg::AddImg(info)).unwrap(),
|
||||||
Err(e) => panic!("Got error from renderer: {e:?}")
|
Err(e) => panic!("Got error from renderer: {e:?}")
|
||||||
}
|
}
|
||||||
@@ -32,13 +35,13 @@ fn handle_converter_msg(
|
|||||||
|
|
||||||
pages[num] = Some(page);
|
pages[num] = Some(page);
|
||||||
|
|
||||||
let num_got = pages.iter()
|
let num_got = pages.iter().filter(|p| p.is_some()).count();
|
||||||
.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
|
// 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)
|
// 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 {
|
struct RenderState {
|
||||||
@@ -66,9 +69,7 @@ fn start_all_rendering(path: impl AsRef<Path>) -> RenderState {
|
|||||||
width: columns * font_size.0
|
width: columns * font_size.0
|
||||||
};
|
};
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || start_rendering(str_path, to_main_tx, from_main_rx, size));
|
||||||
start_rendering(str_path, to_main_tx, from_main_rx, size)
|
|
||||||
});
|
|
||||||
|
|
||||||
let (to_converter_tx, from_main_rx) = unbounded();
|
let (to_converter_tx, from_main_rx) = unbounded();
|
||||||
let (to_main_tx, from_converter_rx) = unbounded();
|
let (to_main_tx, from_converter_rx) = unbounded();
|
||||||
|
|||||||
+1
-1
Submodule ratatui-image updated: e5c13ed29c...88876c7498
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
use flume::{Receiver, SendError, Sender, TryRecvError};
|
use flume::{Receiver, SendError, Sender, TryRecvError};
|
||||||
|
use futures_util::stream::StreamExt;
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ratatui_image::{picker::Picker, protocol::Protocol, Resize};
|
use ratatui_image::{picker::Picker, protocol::Protocol, Resize};
|
||||||
use futures_util::stream::StreamExt;
|
|
||||||
|
|
||||||
use crate::renderer::{fill_default, PageInfo, RenderError};
|
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
|
// size for the area given, so to save ratatui the work of having to
|
||||||
// resize it, we tell them to crop it to fit.
|
// resize it, we tell them to crop it to fit.
|
||||||
let txt_img = picker
|
let txt_img = picker
|
||||||
.new_protocol(dyn_img, img_area, Resize::Crop)
|
.new_protocol(dyn_img, img_area, Resize::None)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
RenderError::Render(format!(
|
RenderError::Render(format!(
|
||||||
"Couldn't convert DynamicImage to ratatui image: {e}"
|
"Couldn't convert DynamicImage to ratatui image: {e}"
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
|
||||||
pub mod renderer;
|
|
||||||
pub mod converter;
|
pub mod converter;
|
||||||
pub mod tui;
|
pub mod renderer;
|
||||||
pub mod skip;
|
pub mod skip;
|
||||||
|
pub mod tui;
|
||||||
|
|||||||
+3
-1
@@ -44,7 +44,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
console_subscriber::init();
|
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 path = PathBuf::from_str(&file)?.canonicalize()?;
|
||||||
|
|
||||||
//let (watch_tx, render_rx) = tokio::sync::mpsc::unbounded_channel();
|
//let (watch_tx, render_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
|
|||||||
+9
-10
@@ -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
|
// We know this is in range 'cause we're iterating over it but we still just want
|
||||||
// to be safe
|
// to be safe
|
||||||
let Some(page) = doc.page(num as i32) else {
|
let Some(page) = doc.page(num as i32) else {
|
||||||
sender
|
sender.send(Err(RenderError::Render(format!(
|
||||||
.send(Err(RenderError::Render(format!(
|
"Couldn't get page {num} ({}) of doc?",
|
||||||
"Couldn't get page {num} ({}) of doc?",
|
num as i32
|
||||||
num as i32
|
))))?;
|
||||||
))))?;
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -242,7 +241,7 @@ pub fn start_rendering(
|
|||||||
render_ctx_to_png(ctx, &mut sender, (col_w, col_h), num)
|
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
|
// And if we got an error, then obviously we need to propagate that
|
||||||
Err(e) => sender.send(Err(RenderError::Render(e)))?
|
Err(e) => sender.send(Err(RenderError::Render(e)))?
|
||||||
}
|
}
|
||||||
@@ -285,7 +284,7 @@ fn render_single_page_to_ctx(
|
|||||||
page: Page,
|
page: Page,
|
||||||
search_term: &Option<String>,
|
search_term: &Option<String>,
|
||||||
already_rendered_no_results: bool,
|
already_rendered_no_results: bool,
|
||||||
(area_w, area_h): (f64, f64),
|
(area_w, area_h): (f64, f64)
|
||||||
) -> Result<Option<RenderedContext>, String> {
|
) -> Result<Option<RenderedContext>, String> {
|
||||||
let mut result_rects = search_term
|
let mut result_rects = search_term
|
||||||
.as_ref()
|
.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);
|
let mut img_data = Vec::with_capacity((ctx.surface_height * ctx.surface_width) as usize);
|
||||||
|
|
||||||
match ctx.surface.write_to_png(&mut img_data) {
|
match ctx.surface.write_to_png(&mut img_data) {
|
||||||
Err(e) => sender.send(Err(RenderError::Render(
|
Err(e) => sender.send(Err(RenderError::Render(format!(
|
||||||
format!("Couldn't write surface to png: {e}")
|
"Couldn't write surface to png: {e}"
|
||||||
))),
|
)))),
|
||||||
Ok(()) => sender.send(Ok(RenderInfo::Page(PageInfo {
|
Ok(()) => sender.send(Ok(RenderInfo::Page(PageInfo {
|
||||||
img_data: ImageData {
|
img_data: ImageData {
|
||||||
data: img_data,
|
data: img_data,
|
||||||
|
|||||||
Reference in New Issue
Block a user