Added configurable logfile path
This commit is contained in:
parent
363157a7f8
commit
56aafda849
@ -1,21 +1,22 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "grex_terminal_display"
|
name = "grex_terminal_display"
|
||||||
version = "0.1.3"
|
version = "0.1.5"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crossterm = "0.27.0"
|
crossterm = "0.27.0"
|
||||||
|
once_cell = "1.19.0"
|
||||||
|
|
||||||
[dependencies.bevy]
|
[dependencies.bevy]
|
||||||
version = "0.13"
|
version = "0.13"
|
||||||
|
|
||||||
[dependencies.grex_framebuffer_extract]
|
[dependencies.grex_framebuffer_extract]
|
||||||
git = "https://github.com/exvacuum/grex_framebuffer_extract"
|
git = "https://github.com/exvacuum/grex_framebuffer_extract"
|
||||||
tag = "v0.1.0"
|
tag = "v0.1.1"
|
||||||
|
|
||||||
[dependencies.grex_dither_post_process]
|
[dependencies.grex_dither_post_process]
|
||||||
git = "https://github.com/exvacuum/grex_dither_post_process"
|
git = "https://github.com/exvacuum/grex_dither_post_process"
|
||||||
tag = "v0.1.2"
|
tag = "v0.1.3"
|
||||||
|
|
||||||
[dependencies.ratatui]
|
[dependencies.ratatui]
|
||||||
version = "0.26.2"
|
version = "0.26.2"
|
||||||
|
@ -11,6 +11,8 @@ use grex_framebuffer_extract::{
|
|||||||
render_assets::FramebufferExtractSource,
|
render_assets::FramebufferExtractSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::resources::TerminalWidget;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct TerminalDisplay;
|
pub struct TerminalDisplay;
|
||||||
|
|
||||||
@ -72,3 +74,12 @@ impl TerminalDisplayBundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Widget {
|
||||||
|
pub widget: Box<dyn TerminalWidget + Send + Sync>,
|
||||||
|
pub depth: u32,
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Tooltip(pub String);
|
||||||
|
21
src/lib.rs
21
src/lib.rs
@ -1,4 +1,4 @@
|
|||||||
use std::{io::stdout, fs::OpenOptions};
|
use std::{fs::OpenOptions, io::stdout, path::PathBuf, sync::{Arc, Mutex}};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
log::{
|
log::{
|
||||||
@ -16,6 +16,7 @@ use grex_dither_post_process::DitherPostProcessPlugin;
|
|||||||
use grex_framebuffer_extract::FramebufferExtractPlugin;
|
use grex_framebuffer_extract::FramebufferExtractPlugin;
|
||||||
|
|
||||||
pub use crossterm;
|
pub use crossterm;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
pub use ratatui;
|
pub use ratatui;
|
||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
@ -23,10 +24,23 @@ pub mod events;
|
|||||||
pub mod resources;
|
pub mod resources;
|
||||||
mod systems;
|
mod systems;
|
||||||
|
|
||||||
pub struct TerminalDisplayPlugin;
|
static LOG_PATH: Lazy<Arc<Mutex<PathBuf>>> = Lazy::new(|| Arc::new(Mutex::new(PathBuf::default())));
|
||||||
|
|
||||||
|
pub struct TerminalDisplayPlugin {
|
||||||
|
pub log_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TerminalDisplayPlugin {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
log_path: "debug.log".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Plugin for TerminalDisplayPlugin {
|
impl Plugin for TerminalDisplayPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
|
*LOG_PATH.lock().expect("Failed to get lock on log path mutex") = self.log_path.clone();
|
||||||
app.add_plugins((
|
app.add_plugins((
|
||||||
DitherPostProcessPlugin,
|
DitherPostProcessPlugin,
|
||||||
FramebufferExtractPlugin,
|
FramebufferExtractPlugin,
|
||||||
@ -36,7 +50,7 @@ impl Plugin for TerminalDisplayPlugin {
|
|||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.open("debug.log")
|
.open(LOG_PATH.lock().expect("Failed to get lock on log path mutex").clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let file_layer = tracing_subscriber::fmt::Layer::new()
|
let file_layer = tracing_subscriber::fmt::Layer::new()
|
||||||
.with_writer(log_file)
|
.with_writer(log_file)
|
||||||
@ -59,7 +73,6 @@ impl Plugin for TerminalDisplayPlugin {
|
|||||||
.insert_resource(resources::Terminal::default())
|
.insert_resource(resources::Terminal::default())
|
||||||
.insert_resource(resources::EventQueue::default())
|
.insert_resource(resources::EventQueue::default())
|
||||||
.insert_resource(resources::TerminalInput::default())
|
.insert_resource(resources::TerminalInput::default())
|
||||||
.insert_resource(resources::TerminalUI::default())
|
|
||||||
.add_event::<events::TerminalInputEvent>();
|
.add_event::<events::TerminalInputEvent>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use std::{
|
use std::{
|
||||||
io::{stdout, Stdout},
|
any::Any, io::{stdout, Stdout}, sync::{Arc, Mutex}
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
utils::{HashMap, HashSet, Uuid},
|
utils::HashSet,
|
||||||
};
|
};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{
|
event::{
|
||||||
@ -72,34 +71,34 @@ impl Default for Terminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
// #[derive(Resource, Default)]
|
||||||
pub struct TerminalUI {
|
// pub struct TerminalUI {
|
||||||
widgets: HashMap<Uuid, Box<dyn TerminalWidget + Sync + Send>>,
|
// widgets: HashMap<Uuid, Box<dyn TerminalWidget + Sync + Send>>,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// impl TerminalUI {
|
||||||
|
// pub fn insert_widget(&mut self, widget: Box<dyn TerminalWidget + Sync + Send>) -> Uuid {
|
||||||
|
// let id = Uuid::new_v4();
|
||||||
|
// self.widgets.insert(id, widget);
|
||||||
|
// id
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn get_widget(&mut self, id: Uuid) -> Option<&mut Box<dyn TerminalWidget + Sync + Send>> {
|
||||||
|
// self.widgets.get_mut(&id)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn destroy_widget(&mut self, id: Uuid) {
|
||||||
|
// self.widgets.remove(&id);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn widgets(&mut self) -> Vec<&mut Box<dyn TerminalWidget + Sync + Send>> {
|
||||||
|
// let mut vec = self.widgets.values_mut().collect::<Vec<_>>();
|
||||||
|
// vec.sort_by(|a, b| a.depth().cmp(&b.depth()).reverse());
|
||||||
|
// vec
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl TerminalUI {
|
pub trait TerminalWidget: Any {
|
||||||
pub fn insert_widget(&mut self, widget: Box<dyn TerminalWidget + Sync + Send>) -> Uuid {
|
|
||||||
let id = Uuid::new_v4();
|
|
||||||
self.widgets.insert(id, widget);
|
|
||||||
id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_widget(&mut self, id: Uuid) -> Option<&mut Box<dyn TerminalWidget + Sync + Send>> {
|
|
||||||
self.widgets.get_mut(&id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn destroy_widget(&mut self, id: Uuid) {
|
|
||||||
self.widgets.remove(&id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn widgets(&mut self) -> Vec<&mut Box<dyn TerminalWidget + Sync + Send>> {
|
|
||||||
let mut vec = self.widgets.values_mut().collect::<Vec<_>>();
|
|
||||||
vec.sort_by(|a, b| a.depth().cmp(&b.depth()).reverse());
|
|
||||||
vec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait TerminalWidget {
|
|
||||||
fn init(&mut self) {}
|
fn init(&mut self) {}
|
||||||
fn update(&mut self) {}
|
fn update(&mut self) {}
|
||||||
fn render(&mut self, frame: &mut Frame, rect: Rect);
|
fn render(&mut self, frame: &mut Frame, rect: Rect);
|
||||||
|
@ -8,8 +8,7 @@ use grex_framebuffer_extract::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::TerminalInputEvent,
|
components::Widget, events::TerminalInputEvent, resources::{EventQueue, Terminal, TerminalInput}
|
||||||
resources::{EventQueue, Terminal, TerminalInput, TerminalUI},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
@ -40,7 +39,7 @@ pub fn setup(event_queue: Res<EventQueue>) {
|
|||||||
|
|
||||||
pub fn print_to_terminal(
|
pub fn print_to_terminal(
|
||||||
mut terminal: ResMut<Terminal>,
|
mut terminal: ResMut<Terminal>,
|
||||||
mut terminal_ui: ResMut<TerminalUI>,
|
mut widgets: Query<&mut Widget>,
|
||||||
image_exports: Query<&FramebufferExtractDestination>,
|
image_exports: Query<&FramebufferExtractDestination>,
|
||||||
) {
|
) {
|
||||||
for image_export in image_exports.iter() {
|
for image_export in image_exports.iter() {
|
||||||
@ -96,8 +95,10 @@ pub fn print_to_terminal(
|
|||||||
.wrap(Wrap { trim: true }),
|
.wrap(Wrap { trim: true }),
|
||||||
area,
|
area,
|
||||||
);
|
);
|
||||||
for widget in terminal_ui.widgets().iter_mut() {
|
let mut active_widgets = widgets.iter_mut().filter(|widget| widget.enabled).collect::<Vec<_>>();
|
||||||
widget.render(frame, area);
|
active_widgets.sort_by(|a, b| a.depth.cmp(&b.depth));
|
||||||
|
for mut widget in active_widgets {
|
||||||
|
widget.widget.render(frame, area);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.expect("Failed to draw terminal frame");
|
.expect("Failed to draw terminal frame");
|
||||||
@ -117,13 +118,13 @@ fn braille_char(mask: u8) -> char {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn widget_input_handling(
|
pub fn widget_input_handling(
|
||||||
mut terminal_ui: ResMut<TerminalUI>,
|
mut widgets: Query<&mut Widget>,
|
||||||
mut event_reader: EventReader<TerminalInputEvent>,
|
mut event_reader: EventReader<TerminalInputEvent>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for event in event_reader.read() {
|
for event in event_reader.read() {
|
||||||
for widget in terminal_ui.widgets().iter_mut() {
|
for mut widget in widgets.iter_mut().filter(|widget| widget.enabled) {
|
||||||
widget.handle_events(event, &mut commands);
|
widget.widget.handle_events(event, &mut commands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user