Skip to content

Commit

Permalink
Perform log initialization earlier and re-implement saving log
Browse files Browse the repository at this point in the history
  • Loading branch information
melody-rs committed Mar 23, 2024
1 parent dbdecb8 commit b22df4e
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 20 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ tokio = { version = "1.33", features = [
] } # *sigh*
tempfile.workspace = true
luminol-term.workspace = true
ringbuf = "0.3.3"

# Set poll promise features here based on the target
# I'd much rather do it in the workspace, but cargo doesn't support that yet
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ impl<'res> UpdateState<'res> {
&'this mut self,
edit_windows: &'this mut window::EditWindows,
) -> UpdateState<'this> {
tracing::info!("dvasacjkfsadcdfngaxjnfdsa");
UpdateState {
ctx: self.ctx,
audio: self.audio,
Expand Down
65 changes: 51 additions & 14 deletions src/app/log_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,58 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.

use std::sync::mpsc::{Receiver, Sender};

use ringbuf::{ring_buffer::RbBase, Rb};

pub struct LogWindow {
pub(super) term_shown: bool,
byte_rx: Receiver<u8>,
byte_tx: Sender<u8>,
ringbuf: RingBuf, // Should we use a temporary file instead of a ringbuffer?
term: luminol_term::widget::ChannelTerminal,
save_promise: Option<poll_promise::Promise<luminol_filesystem::Result<()>>>,
}
const MAX_BUFFER_CAPACITY: usize = 1 << 24;
type RingBuf = ringbuf::LocalRb<u8, Vec<std::mem::MaybeUninit<u8>>>;

impl LogWindow {
pub fn new(
config: &luminol_config::terminal::Config,
byte_rx: std::sync::mpsc::Receiver<u8>,
) -> Self {
let (byte_tx, term_byte_rx) = std::sync::mpsc::channel();
let term = luminol_term::widget::Terminal::channel(config, term_byte_rx);
let ringbuf = RingBuf::new(2 << 12);

Self {
byte_rx,
byte_tx,
ringbuf,
term,
term_shown: false,
save_promise: None,
term: luminol_term::widget::Terminal::channel(config, byte_rx),
}
}

pub fn ui(&mut self, ui: &mut egui::Ui, update_state: &mut luminol_core::UpdateState<'_>) {
for byte in self.byte_rx.try_iter() {
let _ = self.byte_tx.send(byte);

// resize ringbuffer if it is full
let capacity = self.ringbuf.capacity();
if self.ringbuf.is_full() && capacity < MAX_BUFFER_CAPACITY {
let mut new_ringbuf = RingBuf::new(capacity << 1);

let (front, back) = self.ringbuf.as_slices();
new_ringbuf.push_slice(front);
new_ringbuf.push_slice(back);

self.ringbuf = new_ringbuf;
}
self.ringbuf.push_overwrite(byte);
}

// We update the log terminal even if it's not open so that we don't encounter
// performance problems when the terminal has to parse all the new input at once
self.term.update();
Expand Down Expand Up @@ -79,19 +112,12 @@ impl LogWindow {
Err(p) => self.save_promise = Some(p),
}
} else if ui.button("Save to file").clicked() {
// self.buffer.make_contiguous();
// let buffer = self.buffer.clone();

// self.save_promise = Some(luminol_core::spawn_future(async move {
// use futures_lite::AsyncWriteExt;

// let mut tmp = luminol_filesystem::host::File::new()?;
// let mut cursor = async_std::io::Cursor::new(buffer.as_slices().0);
// async_std::io::copy(&mut cursor, &mut tmp).await?;
// tmp.flush().await?;
// tmp.save("luminol.log", "Log files").await?;
// Ok(())
// }));
let (left, right) = self.ringbuf.as_slices();
let mut buffer = left.to_vec();
buffer.extend_from_slice(right);

self.save_promise =
Some(luminol_core::spawn_future(Self::save_promise(buffer)));
}
});

Expand All @@ -105,4 +131,15 @@ impl LogWindow {
}
});
}

async fn save_promise(buffer: Vec<u8>) -> luminol_filesystem::Result<()> {
use futures_lite::AsyncWriteExt;

let mut tmp = luminol_filesystem::host::File::new()?;
let mut cursor = async_std::io::Cursor::new(buffer);
async_std::io::copy(&mut cursor, &mut tmp).await?;
tmp.flush().await?;
tmp.save("luminol.log", "Log files").await?;
Ok(())
}
}
11 changes: 8 additions & 3 deletions src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@

use std::io::Write;
use std::sync::mpsc::Sender;
use std::sync::Arc;

use once_cell::sync::OnceCell;

#[derive(Clone)]
struct LogWriter {
sender: Sender<u8>,
context: egui::Context,
context: Arc<OnceCell<egui::Context>>,
}

impl std::io::Write for LogWriter {
Expand All @@ -40,7 +43,9 @@ impl std::io::Write for LogWriter {
let _ = self.sender.send(byte);
}

self.context.request_repaint();
if let Some(ctx) = self.context.get() {
ctx.request_repaint();
}

Ok(buf.len())
}
Expand Down Expand Up @@ -68,7 +73,7 @@ where
}
}

pub fn initialize_log(sender: Sender<u8>, context: egui::Context) {
pub fn initialize_log(sender: Sender<u8>, context: Arc<OnceCell<egui::Context>>) {
let log_writer = LogWriter { sender, context };
tracing_subscriber::fmt()
// we clone + move the log_writer so this closure impls Fn()
Expand Down
11 changes: 8 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ fn main() {
}
}));

let (log_byte_tx, log_byte_rx) = std::sync::mpsc::channel();
let ctx_cell = std::sync::Arc::new(once_cell::sync::OnceCell::new());
log::initialize_log(log_byte_tx, ctx_cell.clone());

let image = image::load_from_memory(ICON).expect("Failed to load Icon data.");

let native_options = luminol_eframe::NativeOptions {
Expand Down Expand Up @@ -239,9 +243,10 @@ fn main() {
luminol_eframe::run_native(
"Luminol",
native_options,
Box::new(|cc| {
let (log_byte_tx, log_byte_rx) = std::sync::mpsc::channel();
log::initialize_log(log_byte_tx, cc.egui_ctx.clone());
Box::new(move |cc| {
ctx_cell
.set(cc.egui_ctx.clone())
.expect("egui context cell already set (this shouldn't happen!)");

Box::new(app::App::new(
cc,
Expand Down

0 comments on commit b22df4e

Please sign in to comment.