47 lines
1.7 KiB
Rust
47 lines
1.7 KiB
Rust
//! Konsolen-REPL — Headless-Treiber für Tests und Betrieb ohne GPU.
|
|
//!
|
|
//! Liest Zeilen von stdin, gibt sie an `Session::exec` und druckt die
|
|
//! Ausgabe. Befehls- und Dialoglogik liegen in `session`, damit das
|
|
//! Fenster-Frontend dieselbe Session ohne Duplikat steuern kann.
|
|
|
|
use std::io::{self, Write};
|
|
|
|
use crate::session::{Mode, Session};
|
|
|
|
pub fn run(mut session: Session, signals_path: &str) {
|
|
println!("wds-Konsole — {} Signale aus {}. `help` für Befehle.",
|
|
session.game.signals.len(), signals_path);
|
|
|
|
// Reserviertes `[init]`-Signal: KV-Defaults setzen, bevor Stories laufen.
|
|
for line in session.start() { println!("{line}"); }
|
|
|
|
loop {
|
|
let Some(input) = read_line(prompt_for(&session.mode)) else { break };
|
|
let r = session.exec(input.trim());
|
|
for line in r.output { println!("{line}"); }
|
|
if r.quit { break; }
|
|
}
|
|
}
|
|
|
|
/// Prompt je nach Zustand: Befehl, Dialog-Weiterblättern oder Choice-Wahl.
|
|
fn prompt_for(mode: &Mode) -> &'static str {
|
|
match mode {
|
|
Mode::Dialog(d) if !d.choices.is_empty() => " wahl> ",
|
|
Mode::Dialog(_) => " [Enter] ",
|
|
Mode::Menu => "menü> ",
|
|
Mode::FirstPerson => "spiel> ",
|
|
Mode::Free => "> ",
|
|
}
|
|
}
|
|
|
|
/// Zeile von stdin lesen; `None` bei EOF (Ctrl-D) oder Lesefehler.
|
|
fn read_line(prompt: &str) -> Option<String> {
|
|
print!("{prompt}");
|
|
io::stdout().flush().ok();
|
|
let mut buf = String::new();
|
|
match io::stdin().read_line(&mut buf) {
|
|
Ok(0) | Err(_) => None,
|
|
Ok(_) => Some(buf.trim_end().to_string()),
|
|
}
|
|
}
|