122 lines
4.6 KiB
Rust
122 lines
4.6 KiB
Rust
use crate::{
|
|
echo_to_term_frame,
|
|
lua_engine::LuaState,
|
|
parsing::{parse_commands, ParsedCommand},
|
|
FrameId, GlobalMemoCell,
|
|
};
|
|
use itertools::Itertools;
|
|
use wasm_bindgen::JsValue;
|
|
use web_sys::console;
|
|
|
|
pub fn debrace(inp: &str) -> &str {
|
|
let v = inp.trim();
|
|
if v.starts_with('{') && v.ends_with('}') {
|
|
&v[1..(v.len() - 1)]
|
|
} else {
|
|
v
|
|
}
|
|
}
|
|
|
|
fn reentrant_command_handler(
|
|
lua_state: &mut LuaState,
|
|
globals: &GlobalMemoCell,
|
|
term_frame: &FrameId,
|
|
commands_in: &[ParsedCommand],
|
|
) {
|
|
lua_state.set_current_frame(term_frame);
|
|
for command in commands_in {
|
|
match command.split_out_command() {
|
|
None => (),
|
|
Some((cmd, rest)) => {
|
|
if let ("#", command_rest) = cmd.split_at(1) {
|
|
if cmd == "##" {
|
|
match lua_state.execute(&rest.forget_guards().to_string()) {
|
|
Ok(()) => (),
|
|
Err(msg) => {
|
|
echo_to_term_frame(globals, term_frame, &format!("{}\r\n", msg))
|
|
.unwrap_or(())
|
|
}
|
|
}
|
|
} else if let Ok(repeat_count) = command_rest.parse::<u16>() {
|
|
let cmds = &[rest];
|
|
for _ in 0..repeat_count {
|
|
reentrant_command_handler(lua_state, globals, term_frame, cmds);
|
|
}
|
|
} else {
|
|
match lua_state.execute_command(command_rest, &rest) {
|
|
Ok(()) => (),
|
|
Err(msg) => {
|
|
echo_to_term_frame(globals, term_frame, &format!("{}\r\n", msg))
|
|
.unwrap_or(())
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// A normal command. Try dispatching it to the frame object in Lua...
|
|
match lua_state
|
|
.dispatch_normal_command(term_frame, &command.arguments.iter().join(" "))
|
|
{
|
|
Ok(()) => (),
|
|
Err(msg) => {
|
|
echo_to_term_frame(globals, term_frame, &format!("{}\r\n", msg))
|
|
.unwrap_or(())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn command_handler(globals: &GlobalMemoCell, term_frame: &FrameId, command_in: &str) {
|
|
echo_to_term_frame(globals, term_frame, "\r").unwrap_or(());
|
|
{
|
|
let mut cq = globals.command_queue.borrow_mut();
|
|
for cmd in parse_commands(command_in).commands {
|
|
cq.push_back((term_frame.clone(), cmd));
|
|
}
|
|
}
|
|
execute_queue(globals);
|
|
}
|
|
|
|
pub fn execute_queue(globals: &GlobalMemoCell) {
|
|
let mut steps: u64 = 0;
|
|
const STEP_LIMIT: u64 = 500;
|
|
loop {
|
|
let queue_head = globals.command_queue.borrow_mut().pop_front();
|
|
match queue_head {
|
|
None => return,
|
|
Some((frame, command_in)) => {
|
|
steps += 1;
|
|
match globals.lua_engine.try_borrow_mut() {
|
|
Err(_) => console::log_1(&JsValue::from_str(
|
|
"Can't borrow lua_engine when executing queue!",
|
|
)),
|
|
Ok(mut lua_state_m) => {
|
|
reentrant_command_handler(
|
|
&mut lua_state_m,
|
|
globals,
|
|
&frame,
|
|
&[command_in.clone()],
|
|
);
|
|
if steps > STEP_LIMIT {
|
|
let new_queue = globals.command_queue.take();
|
|
if !new_queue.is_empty() {
|
|
echo_to_term_frame(
|
|
globals,
|
|
&frame,
|
|
&format!("Executing queued actions resulted in more than {} steps. This usually means a command is creating similar commands in a loop. The following commands were dropped from the queue to stop execution: {}.",
|
|
STEP_LIMIT,
|
|
&new_queue.iter().map(
|
|
|(_fr, cmd)| cmd.to_string())
|
|
.join("; "))).unwrap_or(());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|