mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-01 23:51:46 -04:00
it's almost working !!
This commit is contained in:
+5
-4
@@ -76,11 +76,11 @@ pub async fn run_conversion_loop(
|
||||
|
||||
// then we go through all the indices available to us and find the first one that has an
|
||||
// image available to steal
|
||||
let Some((page_info, new_iter)) = (idx_start..page)
|
||||
let Some((page_info, new_iter, page_num)) = (idx_start..page)
|
||||
.interleave(page..idx_end)
|
||||
.enumerate()
|
||||
// .skip(*iteration)
|
||||
.find_map(|(i_idx, p_idx)| images[p_idx].take().map(|p| (p, i_idx)))
|
||||
.find_map(|(i_idx, p_idx)| images[p_idx].take().map(|p| (p, i_idx, p_idx)))
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -124,10 +124,11 @@ pub async fn run_conversion_loop(
|
||||
|
||||
match kittage::image::Image::shm_from(
|
||||
dyn_img,
|
||||
format!("__tdf_kittage_{pid}_page_{page}").into()
|
||||
format!("__tdf_kittage_{pid}_page_{page_num}").into()
|
||||
) {
|
||||
Ok((mut img, map)) => {
|
||||
img.num_or_id = NumberOrId::Id(NonZeroU32::new(page as u32 + 1).unwrap());
|
||||
img.num_or_id =
|
||||
NumberOrId::Id(NonZeroU32::new(page_num as u32 + 1).unwrap());
|
||||
ConvertedImage::Kitty {
|
||||
img: MaybeTransferred::NotYet(img, map),
|
||||
area
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use std::io::Write;
|
||||
|
||||
use crossterm::event::EventStream;
|
||||
use kittage::{AsyncInputReader, ImageId, action::Action, error::TransmitError};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DbgWriter<W: Write> {
|
||||
w: W,
|
||||
#[cfg(debug_assertions)]
|
||||
buf: String
|
||||
}
|
||||
|
||||
impl<W: Write> Write for DbgWriter<W> {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if let Ok(s) = std::str::from_utf8(buf) {
|
||||
self.buf.push_str(s);
|
||||
}
|
||||
}
|
||||
self.w.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
log::debug!("wrote {:?}", self.buf);
|
||||
self.buf.clear();
|
||||
}
|
||||
self.w.flush()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_action<'image, 'data, 'es>(
|
||||
action: Action<'image, 'data>,
|
||||
ev_stream: &'es mut EventStream
|
||||
) -> Result<ImageId, TransmitError<'image, 'data, <&'es mut EventStream as AsyncInputReader>::Error>>
|
||||
{
|
||||
let writer = DbgWriter {
|
||||
w: std::io::stdout().lock(),
|
||||
#[cfg(debug_assertions)]
|
||||
buf: String::new()
|
||||
};
|
||||
action
|
||||
.execute_async(writer, ev_stream)
|
||||
.await
|
||||
.map(|(_, i)| i)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ pub enum PrerenderLimit {
|
||||
}
|
||||
|
||||
pub mod converter;
|
||||
pub mod kitty;
|
||||
pub mod renderer;
|
||||
pub mod skip;
|
||||
pub mod tui;
|
||||
|
||||
+97
-28
@@ -2,7 +2,7 @@ use core::error::Error;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
ffi::OsString,
|
||||
io::{BufReader, Read, StdoutLock, Write, stdout},
|
||||
io::{BufReader, Read, Write, stdout},
|
||||
num::{NonZeroU32, NonZeroUsize},
|
||||
path::PathBuf
|
||||
};
|
||||
@@ -16,10 +16,12 @@ use crossterm::{
|
||||
}
|
||||
};
|
||||
use flume::{Sender, r#async::RecvStream};
|
||||
use flexi_logger::FileSpec;
|
||||
use futures_util::{FutureExt, stream::StreamExt};
|
||||
use kittage::{
|
||||
ImageDimensions, PixelFormat,
|
||||
action::Action,
|
||||
delete::{ClearOrDelete, DeleteConfig, WhichToDelete},
|
||||
display::{DisplayConfig, DisplayLocation},
|
||||
error::TransmitError,
|
||||
image::Image as KImage,
|
||||
@@ -27,10 +29,11 @@ use kittage::{
|
||||
};
|
||||
use notify::{Event, EventKind, RecursiveMode, Watcher};
|
||||
use ratatui::{Terminal, backend::CrosstermBackend};
|
||||
use ratatui_image::picker::Picker;
|
||||
use ratatui_image::picker::{Picker, ProtocolType};
|
||||
use tdf::{
|
||||
PrerenderLimit,
|
||||
converter::{ConvertedPage, ConverterMsg, MaybeTransferred, run_conversion_loop},
|
||||
kitty::run_action,
|
||||
renderer::{self, RenderError, RenderInfo, RenderNotif},
|
||||
tui::{BottomMessage, InputAction, MessageSetting, Tui}
|
||||
};
|
||||
@@ -97,6 +100,23 @@ async fn main() -> Result<(), WrappedErr> {
|
||||
)
|
||||
})?;
|
||||
|
||||
// need to keep it around throughout the lifetime of the program, but don't rly need to use it.
|
||||
// Just need to make sure it doesn't get dropped yet.
|
||||
let mut maybe_logger = None;
|
||||
|
||||
if std::env::var("RUST_LOG").is_ok() {
|
||||
maybe_logger =
|
||||
Some(
|
||||
flexi_logger::Logger::try_with_env()
|
||||
.map_err(|e| WrappedErr(format!("Couldn't create initial logger: {e}")))?
|
||||
.log_to_file(FileSpec::try_from("./debug.log").map_err(|e| {
|
||||
WrappedErr(format!("Couldn't create FileSpec for logger: {e}"))
|
||||
})?)
|
||||
.start()
|
||||
.map_err(|e| WrappedErr(format!("Can't start logger: {e}")))?
|
||||
);
|
||||
}
|
||||
|
||||
let (watch_to_render_tx, render_rx) = flume::unbounded();
|
||||
let tui_tx = watch_to_render_tx.clone();
|
||||
|
||||
@@ -233,6 +253,7 @@ async fn main() -> Result<(), WrappedErr> {
|
||||
let (to_converter, from_main) = flume::unbounded();
|
||||
let (to_main, from_converter) = flume::unbounded();
|
||||
|
||||
let is_kitty = picker.protocol_type() == ProtocolType::Kitty;
|
||||
tokio::spawn(run_conversion_loop(to_main, from_main, picker, 20));
|
||||
|
||||
let file_name = path.file_name().map_or_else(
|
||||
@@ -266,6 +287,17 @@ async fn main() -> Result<(), WrappedErr> {
|
||||
)
|
||||
})?;
|
||||
|
||||
if is_kitty {
|
||||
run_action(
|
||||
Action::Delete(DeleteConfig {
|
||||
effect: ClearOrDelete::Delete,
|
||||
which: WhichToDelete::IdRange(NonZeroU32::new(1).unwrap()..=NonZeroU32::MAX)
|
||||
}),
|
||||
&mut ev_stream
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let fullscreen = flags.fullscreen.unwrap_or_default();
|
||||
let main_area = Tui::main_layout(&term.get_frame(), fullscreen);
|
||||
tui_tx
|
||||
@@ -326,9 +358,10 @@ async fn enter_redraw_loop(
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
loop {
|
||||
let mut needs_redraw = true;
|
||||
let next_ev = ev_stream.next().fuse();
|
||||
tokio::select! {
|
||||
// First we check if we have any keystrokes
|
||||
Some(ev) = ev_stream.next().fuse() => {
|
||||
Some(ev) = next_ev => {
|
||||
// If we can't get user input, just crash.
|
||||
let ev = ev.expect("Couldn't get any user input");
|
||||
|
||||
@@ -386,9 +419,9 @@ async fn enter_redraw_loop(
|
||||
to_display = tui.render(f, &main_area);
|
||||
})?;
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
let mut maybe_err = Ok(());
|
||||
for (img, area) in to_display {
|
||||
let mut to_replace = Vec::new();
|
||||
for (page_num, img, area) in to_display {
|
||||
let config = DisplayConfig {
|
||||
location: DisplayLocation {
|
||||
x: area.x.into(),
|
||||
@@ -398,6 +431,8 @@ async fn enter_redraw_loop(
|
||||
..DisplayConfig::default()
|
||||
};
|
||||
|
||||
log::debug!("looking at img {img:#?}");
|
||||
|
||||
maybe_err = match img {
|
||||
MaybeTransferred::NotYet(image, _map) => {
|
||||
let mut fake_image = KImage {
|
||||
@@ -416,16 +451,22 @@ async fn enter_redraw_loop(
|
||||
};
|
||||
std::mem::swap(image, &mut fake_image);
|
||||
|
||||
let res = Action::TransmitAndDisplay {
|
||||
image: fake_image,
|
||||
config,
|
||||
placement_id: None
|
||||
}
|
||||
.execute_async(&mut stdout, &mut ev_stream)
|
||||
log::debug!("Actually trying to display an image now: {fake_image:?}...");
|
||||
|
||||
let res = run_action(
|
||||
Action::TransmitAndDisplay {
|
||||
image: fake_image,
|
||||
config,
|
||||
placement_id: None
|
||||
},
|
||||
&mut ev_stream
|
||||
)
|
||||
.await;
|
||||
|
||||
log::debug!("And it should've gone through: {res:?}!...");
|
||||
|
||||
match res {
|
||||
Ok((_, img_id)) => {
|
||||
Ok(img_id) => {
|
||||
// We need the `_map` to be dropped here, but can't explicitly carry it
|
||||
// over to here. So we're just relying on the overwrite of `img` to
|
||||
// drop `_map` (and thus unmap the memory) for us
|
||||
@@ -433,40 +474,68 @@ async fn enter_redraw_loop(
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(match e {
|
||||
TransmitError::Writing(
|
||||
Action::TransmitAndDisplay {
|
||||
TransmitError::Writing(action, e) => {
|
||||
if let Action::TransmitAndDisplay {
|
||||
image: failed_img, ..
|
||||
},
|
||||
e
|
||||
) => {
|
||||
*image = failed_img;
|
||||
} = *action
|
||||
{
|
||||
*image = failed_img;
|
||||
} else {
|
||||
to_replace.push(page_num);
|
||||
}
|
||||
|
||||
e.to_string()
|
||||
}
|
||||
_ => {
|
||||
to_replace.push(page_num);
|
||||
e.to_string()
|
||||
}
|
||||
_ => e.to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
MaybeTransferred::Transferred(image_id) => Action::Display {
|
||||
image_id: *image_id,
|
||||
placement_id: NonZeroU32::new(1).unwrap(),
|
||||
config
|
||||
MaybeTransferred::Transferred(image_id) => {
|
||||
let e = run_action(
|
||||
Action::Display {
|
||||
image_id: *image_id,
|
||||
placement_id: NonZeroU32::new(1).unwrap(),
|
||||
config
|
||||
},
|
||||
&mut ev_stream
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.map_err(|e| e.to_string());
|
||||
|
||||
log::debug!("Just tried to display: {e:?}");
|
||||
e
|
||||
}
|
||||
.execute_async(&mut stdout, &mut ev_stream)
|
||||
.await
|
||||
.map(|(_, _)| ())
|
||||
.map_err(|e| e.to_string())
|
||||
};
|
||||
}
|
||||
|
||||
for page_num in to_replace {
|
||||
tui.page_failed_display(page_num);
|
||||
}
|
||||
|
||||
if let Err(e) = maybe_err {
|
||||
tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!(
|
||||
"Couldn't transfer image to the terminal: {e}"
|
||||
))));
|
||||
}
|
||||
|
||||
execute!(&mut stdout, EndSynchronizedUpdate)?;
|
||||
execute!(stdout().lock(), EndSynchronizedUpdate)?;
|
||||
}
|
||||
}
|
||||
|
||||
execute!(
|
||||
term.backend_mut(),
|
||||
LeaveAlternateScreen,
|
||||
crossterm::cursor::Show
|
||||
)?;
|
||||
disable_raw_mode()?;
|
||||
|
||||
drop(maybe_logger);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_notify_ev(
|
||||
|
||||
+8
-3
@@ -133,7 +133,7 @@ impl Tui {
|
||||
&'s mut self,
|
||||
frame: &mut Frame<'_>,
|
||||
full_layout: &RenderLayout
|
||||
) -> Vec<(&'s mut MaybeTransferred, Rect)> {
|
||||
) -> Vec<(usize, &'s mut MaybeTransferred, Rect)> {
|
||||
if self.showing_help_msg {
|
||||
self.render_help_msg(frame);
|
||||
return vec![];
|
||||
@@ -293,11 +293,12 @@ impl Tui {
|
||||
|
||||
let to_display = page_widths
|
||||
.into_iter()
|
||||
.filter_map(|(width, img)| {
|
||||
.enumerate()
|
||||
.filter_map(|(idx, (width, img))| {
|
||||
let maybe_img =
|
||||
Self::render_single_page(frame, img, Rect { width, ..img_area });
|
||||
img_area.x += width;
|
||||
maybe_img
|
||||
maybe_img.map(|(img, r)| (idx + self.page, img, r))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -400,6 +401,10 @@ impl Tui {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn page_failed_display(&mut self, page_num: usize) {
|
||||
self.rendered[page_num].img = None;
|
||||
}
|
||||
|
||||
pub fn got_num_results_on_page(&mut self, page_num: usize, num_results: usize) {
|
||||
self.rendered[page_num].num_results = Some(num_results);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user