1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
mod command;
use std::{ thread, time, sync::mpsc, io::{ stdout, stdin, Write } };
use command::parse_and_exec;
use super::vm::{ VirtualMachine, VirtualMachineInterface };
pub(crate) struct VirtualMachineMonitor {
refresh_rate: u64,
}
macro_rules! info {
() => {
print!("\x1B[90m|\x1B[0m{:^8}\x1B[90m|> \x1B[0m", "RUN")
};
(error $str:expr) => {
info!(format!("\x1B[41m{:^8}\x1B[0m", $str))
};
($str:expr) => {
print!("\x1B7\x1B[1G\x1B[90m|\x1B[0m{:^8}\x1B[90m|> \x1B[0m\x1B8", $str)
};
}
impl VirtualMachineMonitor {
pub(crate) fn new(refresh_rate: u64) -> VirtualMachineMonitor {
VirtualMachineMonitor {
refresh_rate,
}
}
pub(crate) fn start(&mut self, mut vm: VirtualMachine) {
// Spawn input handling thread
let (tx, rx) = mpsc::channel::<String>();
thread::spawn(move || loop {
let mut buffer = String::new();
stdin().read_line(&mut buffer).unwrap();
tx.send(buffer).unwrap();
});
info!();
loop {
match rx.try_recv() {
Ok(input) => {
if let Err(msg) = parse_and_exec(input, &mut vm) {
if msg.is_empty() {
break;
}
else {
println!("{}", msg);
}
}
else if vm.is_single_step() {
println!("");
}
info!();
},
_ => {},
}
if vm.is_single_step() {
info!("STEP");
}
else if vm.is_halted() {
info!(error "HALTED");
}
let _ = stdout().flush();
thread::sleep(time::Duration::from_millis(self.refresh_rate));
}
}
}
|