tui logger w/ patched bevy_ratatui

This commit is contained in:
Tao Tien 2026-01-09 03:34:54 -08:00
parent 3fb03cfbcb
commit 78029687d7
10 changed files with 885 additions and 162 deletions

922
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -11,12 +11,17 @@ readme = false
[dependencies] [dependencies]
bevy = { version = "0.17.3", features = ["dynamic_linking"] } bevy = { version = "0.17.3", features = ["dynamic_linking"] }
bevy_ratatui = "0.10.0" # bevy_ratatui = { git = "https://github.com/kenianbei/bevy_ratatui.git", rev = "e4b022308e08ab360ef89eca8e9f8b1c969e9a56" }
bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" }
clap = { version = "4.5.54", features = ["derive"] } clap = { version = "4.5.54", features = ["derive"] }
log = { version = "0.4.29", features = ["release_max_level_error", "max_level_trace"] } log = { version = "0.4.29", features = [
ratatui = "0.29.0" "release_max_level_error",
"max_level_trace",
] }
ratatui = "0.30.0"
strum = { version = "0.27.2", features = ["derive"] } strum = { version = "0.27.2", features = ["derive"] }
tracing-subscriber = "0.3.22" tracing-subscriber = "0.3.22"
tui-logger = { version = "0.18.0", features = ["tracing-support", "crossterm"] }
[profile.dev] [profile.dev]
opt-level = 1 opt-level = 1

View file

@ -53,7 +53,7 @@
xorg.libXcursor xorg.libXcursor
libxkbcommon libxkbcommon
]; ];
# RUST_LOG = "jong=off"; RUST_LOG = "jong=trace";
}; };
} }
); );

View file

@ -1,4 +1,3 @@
use std::collections::VecDeque;
use bevy::prelude::*; use bevy::prelude::*;
@ -48,7 +47,7 @@ pub(crate) struct MatchSettings {
pub(crate) player_count: u8, pub(crate) player_count: u8,
} }
pub(crate) fn next_round(mut compass: Res<Compass>) {} pub(crate) fn next_round(_compass: Res<Compass>) {}
pub(crate) fn init_match( pub(crate) fn init_match(
mut commands: Commands, mut commands: Commands,

View file

@ -1,4 +1,3 @@
use std::collections::VecDeque;
use bevy::prelude::*; use bevy::prelude::*;
@ -7,6 +6,6 @@ use crate::tiles::Tile;
#[derive(Component)] #[derive(Component)]
pub(crate) struct Wall(Vec<Entity>); pub(crate) struct Wall(Vec<Entity>);
pub(crate) fn build_wall(tiles: Query<&Tile>) { pub(crate) fn build_wall(_tiles: Query<&Tile>) {
info!("built a wall!") info!("built a wall!")
} }

View file

@ -1,5 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use tracing_subscriber::{layer::SubscriberExt, registry::LookupSpan, util::SubscriberInitExt};
mod gui; mod gui;
mod tui; mod tui;
@ -17,17 +18,25 @@ enum Mode {
} }
fn main() { fn main() {
tracing_subscriber::fmt() // tracing_subscriber::fmt()
.with_writer(std::io::stderr) // .with_writer(std::io::stderr)
.with_env_filter("warn,jong=trace") // .with_env_filter("warn,jong=trace")
.init(); // .init();
let args = Args::parse(); let args = Args::parse();
let mut app = App::new(); let mut app = App::new();
let app = match args.mode { let app = match args.mode {
Mode::RunGui => app.add_plugins(DefaultPlugins), Mode::RunGui => app.add_plugins(DefaultPlugins),
Mode::RunTui => app.add_plugins(tui::RiichiTui), Mode::RunTui => {
tracing_subscriber::registry()
.with(tui_logger::TuiTracingSubscriberLayer)
.init();
tui_logger::init_logger(tui_logger::LevelFilter::Trace).unwrap();
tui_logger::set_env_filter_from_string("warn,jong=trace");
app.add_plugins(tui::RiichiTui)
}
}; };
app.add_plugins(jong::game::Riichi); app.add_plugins(jong::game::Riichi);

View file

@ -1,7 +1,6 @@
use bevy::{ecs::entity::MapEntities, prelude::*}; use bevy::{ecs::entity::MapEntities, prelude::*};
use strum::FromRepr; use strum::FromRepr;
use crate::game::wall::Wall;
// #[derive(Component)] // #[derive(Component)]
// #[derive(relasionship(re))] // #[derive(relasionship(re))]

42
src/tui/console.rs Normal file
View file

@ -0,0 +1,42 @@
use tui_logger::TuiLoggerWidget;
use bevy_ratatui::RatatuiContext;
use bevy::input::keyboard::Key;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
pub(crate) enum ConsoleState {
Open,
#[default]
Closed,
}
impl std::ops::Not for ConsoleState {
type Output = Self;
fn not(self) -> Self::Output {
match self {
ConsoleState::Open => ConsoleState::Closed,
ConsoleState::Closed => ConsoleState::Open,
}
}
}
pub(crate) fn toggle_console(
input: Res<ButtonInput<Key>>,
curr_state: Res<State<ConsoleState>>,
mut next_state: ResMut<NextState<ConsoleState>>,
) {
if input.just_pressed(Key::Character("`".into())) {
trace!("toggled");
next_state.set(!*curr_state.get());
}
}
pub(crate) fn draw_console(mut tui_ctx: ResMut<RatatuiContext>) -> Result {
tui_ctx.draw(|frame| {
frame.render_widget(TuiLoggerWidget::default(), frame.area());
})?;
Ok(())
}

View file

@ -1,11 +1,22 @@
// use bevy::ecs::message::MessageReader; // use bevy::ecs::message::MessageReader;
use bevy::app::AppExit; use bevy::app::AppExit;
use bevy::input::keyboard::Key; use bevy::input::keyboard::{Key, KeyboardInput};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_ratatui::crossterm::event::KeyCode;
use crate::tui::console::ConsoleState;
pub(crate) fn keyboard_input_system( pub(crate) fn keyboard_input_system(
input: Option<Res<ButtonInput<KeyCode>>>, // keycode_input: Option<Res<ButtonInput<KeyCode>>>,
key_input: Option<Res<ButtonInput<Key>>>, // key_input: Option<Res<ButtonInput<Key>>>,
// mut next_state: ResMut<State<TuiState>>,
mut keyboard_events: MessageReader<KeyboardInput>,
) { ) {
// if let Some(keycode_input) = keycode_input {
// if keycode_input.just_pressed(KeyCode::Backquote) {
// // console_state.set;
// }
// }
for keyboard_input in keyboard_events.read() {
trace!("{:?}", keyboard_input);
}
} }

View file

@ -1,10 +1,11 @@
use std::time::Duration; use std::time::Duration;
use bevy::{app::ScheduleRunnerPlugin, prelude::*}; use bevy::{app::ScheduleRunnerPlugin, input::keyboard::Key, prelude::*, state::app::StatesPlugin};
use bevy_ratatui::{RatatuiContext, RatatuiPlugins}; use bevy_ratatui::{RatatuiContext, RatatuiPlugins};
use jong::tiles::Tile; use jong::tiles::Tile;
use tui_logger::TuiLoggerSmartWidget;
mod console;
mod input; mod input;
pub struct RiichiTui; pub struct RiichiTui;
@ -13,7 +14,7 @@ impl Plugin for RiichiTui {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(( app.add_plugins((
MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32( MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32(
1. / 1., 1. / 60.,
))), ))),
RatatuiPlugins { RatatuiPlugins {
// enable_kitty_protocol: todo!(), // enable_kitty_protocol: todo!(),
@ -22,13 +23,25 @@ impl Plugin for RiichiTui {
..Default::default() ..Default::default()
}, },
)) ))
.add_plugins(StatesPlugin)
.init_state::<console::ConsoleState>()
.add_systems(Update, console::toggle_console)
.add_systems(Update, console::draw_console.run_if(in_state(console::ConsoleState::Open)))
.add_systems(Update, input::keyboard_input_system) .add_systems(Update, input::keyboard_input_system)
.add_systems(Update, draw_system); .add_systems(Update, draw_system)
// semicolon stopper
;
} }
} }
pub(crate) fn draw_system(mut context: ResMut<RatatuiContext>, query: Query<&Tile>) -> Result { // #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, States)]
context.draw(|frame| { // enum TuiState {
// MainMenu,
// InGame,
// }
pub(crate) fn draw_system(mut tui_ctx: ResMut<RatatuiContext>, query: Query<&Tile>) -> Result {
tui_ctx.draw(|frame| {
let text = ratatui::text::Text::raw("tiny riichi"); let text = ratatui::text::Text::raw("tiny riichi");
frame.render_widget(text, frame.area()); frame.render_widget(text, frame.area());
})?; })?;