bevy_mod_debug_console/
std_io_plugin.rs

1use crate::app::{build_commands, input_pause, match_commands, pause, EnteringConsole, Pause};
2use bevy::{
3    ecs::{archetype::Archetypes, component::Components, entity::Entities},
4    prelude::*,
5    reflect::TypeRegistry,
6    tasks::AsyncComputeTaskPool,
7};
8use crossbeam::channel::{bounded, Receiver};
9use std::io::{self, BufRead, Write};
10
11fn parse_input(
12    a: &Archetypes,
13    c: &Components,
14    e: &Entities,
15    reflect: Res<TypeRegistry>,
16    mut pause: ResMut<Pause>,
17    line_channel: Res<Receiver<String>>,
18) {
19    if let Ok(line) = line_channel.try_recv() {
20        let app_name = "";
21        println!("");
22        let split = line.split_whitespace();
23        let mut args = vec![app_name];
24        args.append(&mut split.collect());
25
26        let matches_result = build_commands(app_name).try_get_matches_from(args);
27
28        if let Err(e) = matches_result {
29            println!("{}", e.to_string());
30            print!(">>> ");
31            io::stdout().flush().unwrap();
32            return;
33        }
34
35        let matches = matches_result.unwrap();
36
37        let output = match_commands(&matches, a, c, e, &mut pause, &*reflect);
38
39        println!("{}", output);
40        print!(">>> ");
41        io::stdout().flush().unwrap();
42    }
43}
44
45fn spawn_io_thread(mut commands: Commands) {
46    let thread_pool = AsyncComputeTaskPool::get();
47    println!("Bevy Console Debugger.  Type 'help' for list of commands.");
48    print!(">>> ");
49    io::stdout().flush().unwrap();
50
51    let (tx, rx) = bounded(1);
52    let task = thread_pool.spawn(async move {
53        let stdin = io::stdin();
54        loop {
55            let line = stdin.lock().lines().next().unwrap().unwrap();
56            tx.send(line)
57                .expect("error sending user input to other thread");
58        }
59    });
60    task.detach();
61    commands.insert_resource(rx);
62}
63
64pub struct ConsoleDebugPlugin;
65impl Plugin for ConsoleDebugPlugin {
66    fn build(&self, app: &mut App) {
67        app.insert_resource(Pause(false))
68            .insert_resource(EnteringConsole(false))
69            .add_startup_system(spawn_io_thread)
70            .add_system(parse_input.with_run_criteria(pause))
71            .add_system(input_pause);
72    }
73}