added scripting because of course i did

This commit is contained in:
Schrottkatze 2025-06-18 19:29:45 +02:00
parent 3a3c238cd8
commit d43b5b64e1
Signed by: schrottkatze
SSH key fingerprint: SHA256:FPOYVeBy3QP20FEM42uWF1Wa/Qhlk+L3S2+Wuau/Auo
6 changed files with 95 additions and 25 deletions

View file

@ -1,34 +1,15 @@
//! Seperate out debugging uis/plugins in it's own module for cleanliness. //! Seperate out debugging uis/plugins in it's own module for cleanliness.
use std::{fs, path::PathBuf};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_inspector_egui::bevy_egui::EguiPlugin; use bevy_inspector_egui::bevy_egui::EguiPlugin;
use clap::Subcommand; use clap::Subcommand;
use console::ConsoleLog; use console::{ConsoleLog, exec_script};
use util::{console_err, console_log};
use crate::AppState; use crate::AppState;
mod console; mod console;
mod util {
use bevy::prelude::*;
use super::DebugEvent;
pub fn console_log(dbg_writer: &mut EventWriter<DebugEvent>, s: impl Into<String>) {
dbg_writer.write(DebugEvent::PrintToConsole {
error: false,
text: s.into(),
});
}
pub fn console_err(dbg_writer: &mut EventWriter<DebugEvent>, s: impl Into<String>) {
dbg_writer.write(DebugEvent::PrintToConsole {
error: false,
text: s.into(),
});
}
}
/// Debug system set. /// Debug system set.
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct DebugSet; pub struct DebugSet;
@ -37,8 +18,12 @@ pub fn plugin(app: &mut App) {
app.add_plugins(EguiPlugin { app.add_plugins(EguiPlugin {
enable_multipass_for_primary_context: true, enable_multipass_for_primary_context: true,
}) })
.add_systems(Update, start_game.in_set(DebugSet))
.add_event::<DebugEvent>() .add_event::<DebugEvent>()
.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); .add_plugins(console::plugin);
} }
@ -49,17 +34,32 @@ enum DebugEvent {
CloseDebugConsole, CloseDebugConsole,
/// Output a string to the console. /// 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"])] #[command(name = "echo", aliases = ["print", "print-to-console"])]
PrintToConsole { PrintToConsole {
/// Print as error /// Print as error.
#[arg(short, long)] #[arg(short, long)]
error: bool, error: bool,
/// The text to be printed in the console. /// The text to be printed in the console.
text: String, 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 /// Start the game
StartGame, StartGame,
/// Run a tx file (the games debug scripting lang :3)
#[command(name = "run")]
RunFile { file: PathBuf },
} }
fn start_game( fn start_game(
@ -79,3 +79,40 @@ fn start_game(
} }
} }
} }
fn handle_debug_logs(mut dbg_reader: EventReader<DebugEvent>) {
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<DebugEvent>) -> 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(),
))
})?
}

View file

@ -1,6 +1,7 @@
use std::panic::Location; use std::panic::Location;
use bevy::prelude::*; use bevy::prelude::*;
use cli::respond;
use ui::{ use ui::{
DebugConsole, autofocus, autoscroll, handle_open_console, process_prompt, update_content, DebugConsole, autofocus, autoscroll, handle_open_console, process_prompt, update_content,
update_scroll_position, update_scroll_position,
@ -110,3 +111,24 @@ fn execute_console_events(
}; };
} }
} }
pub fn exec_script(
file: In<Option<(String, String)>>,
mut dbg_writer: EventWriter<DebugEvent>,
mut logger: ResMut<ConsoleLog>,
) {
let Some((file, file_name)) = &*file else {
return;
};
for (line_nr, line) in file.lines().enumerate() {
if !line.trim().is_empty() && !line.trim().starts_with("//") {
match respond(line) {
Ok(ev) => {
dbg_writer.write(ev);
}
Err(err) => logger.err(&format!("{err}\n\n({file_name}:{line_nr})")),
}
}
}
}

View file

@ -1,7 +1,10 @@
use bevy::prelude::*;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use crate::debug::DebugEvent; use crate::debug::DebugEvent;
use super::ConsoleLog;
pub(super) fn respond(line: &str) -> Result<DebugEvent, String> { pub(super) fn respond(line: &str) -> Result<DebugEvent, String> {
let args = shlex::split(line).ok_or("Invalid Quoting")?; let args = shlex::split(line).ok_or("Invalid Quoting")?;
let cli = Cli::try_parse_from(args).map_err(|e| e.to_string()); let cli = Cli::try_parse_from(args).map_err(|e| e.to_string());

View file

@ -90,7 +90,7 @@ pub fn update_content(
) { ) {
c.entity(*content).with_children(|parent| { c.entity(*content).with_children(|parent| {
for item in log.unread() { for item in log.unread() {
match dbg!(item) { match item {
ConsoleEvent::Input(s) => { ConsoleEvent::Input(s) => {
parent.spawn(components::input(s.to_string(), &asset_server)); parent.spawn(components::input(s.to_string(), &asset_server));
} }

2
startup.tx Normal file
View file

@ -0,0 +1,2 @@
log "hello from startup script!!"
start-game

6
test.tx Normal file
View file

@ -0,0 +1,6 @@
// test comment
echo hii
echo "meow"
echo 42
start-game