From 05081a76628fc6d418168727eda0679841c2ea80 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Sat, 31 May 2025 00:37:07 -0400 Subject: [PATCH] Only show 1000 lines of history in terminal --- src/emulator.rs | 7 +++++-- src/window/terminal.rs | 34 ++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/emulator.rs b/src/emulator.rs index 5d4cf13..b4d0ba8 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -47,7 +47,7 @@ impl SimId { match index { 0 => Some(Self::Player1), 1 => Some(Self::Player2), - _ => None + _ => None, } } } @@ -239,7 +239,10 @@ impl Emulator { while self.sims.len() <= index { let new_index = self.sims.len(); self.sims.push(Sim::new()); - if self.stdouts.contains_key(&SimId::from_index(new_index).unwrap()) { + if self + .stdouts + .contains_key(&SimId::from_index(new_index).unwrap()) + { self.sims[new_index].watch_stdout(true); } self.sim_state[new_index].store(SimState::NoGame, Ordering::Release); diff --git a/src/window/terminal.rs b/src/window/terminal.rs index 36f7323..fa04500 100644 --- a/src/window/terminal.rs +++ b/src/window/terminal.rs @@ -1,4 +1,4 @@ -use std::sync::mpsc; +use std::{collections::VecDeque, sync::mpsc}; use egui::{ Align, CentralPanel, Context, FontFamily, Label, RichText, ScrollArea, ViewportBuilder, @@ -9,20 +9,24 @@ use crate::emulator::{EmulatorClient, EmulatorCommand, SimId}; use super::AppWindow; +const SCROLLBACK: usize = 1000; + pub struct TerminalWindow { sim_id: SimId, receiver: mpsc::Receiver, - text: String, + lines: VecDeque, } impl TerminalWindow { pub fn new(sim_id: SimId, client: &EmulatorClient) -> Self { let (sender, receiver) = mpsc::channel(); client.send_command(EmulatorCommand::WatchStdout(sim_id, sender)); + let mut lines = VecDeque::new(); + lines.push_back(String::new()); Self { sim_id, receiver, - text: String::new(), + lines, } } } @@ -44,17 +48,31 @@ impl AppWindow for TerminalWindow { fn show(&mut self, ctx: &Context) { if let Ok(text) = self.receiver.try_recv() { - self.text.push_str(&text); + let mut rest = text.as_str(); + while let Some(index) = rest.find('\n') { + let (line, lines) = rest.split_at(index); + let current = self.lines.back_mut().unwrap(); + current.push_str(line); + self.lines.push_back(String::new()); + if self.lines.len() > SCROLLBACK { + self.lines.pop_front(); + } + rest = &lines[1..]; + } + self.lines.back_mut().unwrap().push_str(rest); } CentralPanel::default().show(ctx, |ui| { ScrollArea::vertical() .stick_to_bottom(true) .auto_shrink([false, false]) + .animated(false) .show(ui, |ui| { - let label = Label::new(RichText::new(&self.text).family(FontFamily::Monospace)) - .halign(Align::LEFT) - .wrap(); - ui.add(label); + for line in &self.lines { + let label = Label::new(RichText::new(line).family(FontFamily::Monospace)) + .halign(Align::LEFT) + .wrap(); + ui.add(label); + } }); }); }