//! Seperate out debugging uis/plugins in it's own module for cleanliness. use std::{fs, path::PathBuf}; use bevy::prelude::*; use bevy_inspector_egui::bevy_egui::EguiPlugin; use clap::Subcommand; use console::{ConsoleLog, exec_script}; use crate::AppState; mod console; /// Debug system set. #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] pub struct DebugSet; pub fn plugin(app: &mut App) { app.add_plugins(EguiPlugin { enable_multipass_for_primary_context: true, }) .add_event::() .add_systems( Update, (handle_debug_logs, start_game, run_file.pipe(exec_script)).in_set(DebugSet), ) .add_systems(Startup, startup_file.pipe(exec_script)) .add_plugins(console::plugin); } #[derive(Event, Debug, Subcommand, PartialEq, Eq)] enum DebugEvent { /// Close the debug console. #[command(name = "close", aliases = ["close-console"])] CloseDebugConsole, /// Output a string to the console. /// /// Needed for logging in startup scripts, since the console isn't initialized yet. #[command(name = "echo", aliases = ["print", "print-to-console"])] PrintToConsole { /// Print as error. #[arg(short, long)] error: bool, /// The text to be printed in the console. text: String, }, /// Log as INFO or ERROR to stdout. Log { /// Log as error. #[arg(short, long)] error: bool, /// The text to be logged. text: String, }, /// Start the game StartGame, /// Run a tx file (the games debug scripting lang :3) #[command(name = "run")] RunFile { file: PathBuf }, } fn start_game( mut dbg_reader: EventReader, mut log: ResMut, cur_state: Res>, mut next_state: ResMut>, ) { for ev in dbg_reader.read() { if *ev == DebugEvent::StartGame { if *cur_state == AppState::Ingame { log.err("Can't start game since it's already started."); } else { log.write("Starting game..."); next_state.set(AppState::Ingame); } } } } fn handle_debug_logs(mut dbg_reader: EventReader) { for ev in dbg_reader.read() { if let DebugEvent::Log { error, text } = ev { if *error { error!("{text}") } else { info!("{text}") }; } } } fn run_file(mut dbg_reader: EventReader) -> Option<(String, String)> { for ev in dbg_reader.read() { if let DebugEvent::RunFile { file } = ev { let f = std::fs::read_to_string(file); if let Ok(f) = f { return Some((f, String::from(file.file_name().unwrap().to_string_lossy()))); } } } None } fn startup_file() -> Option<(String, String)> { let path: PathBuf = "./startup.tx".into(); fs::exists(&path).unwrap_or(false).then(|| { Some(( fs::read_to_string(&path).unwrap(), path.file_name().unwrap().to_string_lossy().to_string(), )) })? }