2024-08-16 21:39:39 +10:00
use crate ::{
2024-09-26 23:30:43 +10:00
echo_to_term_frame ,
lua_engine ::LuaState ,
parsing ::{ parse_commands , ParsedCommand } ,
2024-10-05 19:28:39 +10:00
FrameId , GlobalMemoCell ,
2024-08-16 21:39:39 +10:00
} ;
2024-09-26 23:30:43 +10:00
use itertools ::Itertools ;
use wasm_bindgen ::JsValue ;
use web_sys ::console ;
2024-08-16 21:39:39 +10:00
2024-08-23 23:37:58 +10:00
pub fn debrace ( inp : & str ) -> & str {
2024-08-17 23:19:41 +10:00
let v = inp . trim ( ) ;
2024-09-20 22:59:00 +10:00
if v . starts_with ( '{' ) & & v . ends_with ( '}' ) {
2024-08-17 23:19:41 +10:00
& v [ 1 .. ( v . len ( ) - 1 ) ]
} else {
v
}
}
2024-08-16 21:39:39 +10:00
fn reentrant_command_handler (
lua_state : & mut LuaState ,
2024-08-23 23:37:58 +10:00
globals : & GlobalMemoCell ,
2024-10-05 19:28:39 +10:00
term_frame : & FrameId ,
2024-09-26 23:30:43 +10:00
commands_in : & [ ParsedCommand ] ,
2024-08-16 21:39:39 +10:00
) {
2024-08-17 21:36:15 +10:00
lua_state . set_current_frame ( term_frame ) ;
2024-09-26 23:30:43 +10:00
for command in commands_in {
2024-08-16 21:39:39 +10:00
match command . split_out_command ( ) {
None = > ( ) ,
Some ( ( cmd , rest ) ) = > {
2024-08-18 20:58:50 +10:00
if let ( " # " , command_rest ) = cmd . split_at ( 1 ) {
2024-08-17 23:19:41 +10:00
if cmd = = " ## " {
2024-09-20 22:59:00 +10:00
match lua_state . execute ( & rest . forget_guards ( ) . to_string ( ) ) {
2024-08-17 23:19:41 +10:00
Ok ( ( ) ) = > ( ) ,
Err ( msg ) = > {
echo_to_term_frame ( globals , term_frame , & format! ( " {} \r \n " , msg ) )
. unwrap_or ( ( ) )
}
}
2024-08-18 20:58:50 +10:00
} else if let Ok ( repeat_count ) = command_rest . parse ::< u16 > ( ) {
2024-09-26 23:30:43 +10:00
let cmds = & [ rest ] ;
2024-08-18 20:58:50 +10:00
for _ in 0 .. repeat_count {
2024-09-26 23:30:43 +10:00
reentrant_command_handler ( lua_state , globals , term_frame , cmds ) ;
2024-08-18 20:58:50 +10:00
}
2024-08-17 23:19:41 +10:00
} else {
2024-09-20 22:59:00 +10:00
match lua_state . execute_command ( command_rest , & rest ) {
2024-08-17 23:19:41 +10:00
Ok ( ( ) ) = > ( ) ,
Err ( msg ) = > {
echo_to_term_frame ( globals , term_frame , & format! ( " {} \r \n " , msg ) )
. unwrap_or ( ( ) )
}
2024-08-17 16:42:01 +10:00
}
2024-08-16 21:39:39 +10:00
}
2024-09-17 22:14:07 +10:00
} 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 ( ( ) )
}
}
2024-08-16 21:39:39 +10:00
}
}
}
}
}
2024-10-05 19:28:39 +10:00
pub fn command_handler ( globals : & GlobalMemoCell , term_frame : & FrameId , command_in : & str ) {
2024-09-26 23:30:43 +10:00
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 ;
}
}
}
}
}
2024-08-16 21:39:39 +10:00
}
}
}