use super::loop_cmd::{LoopRuntimeState, LOOP_STACK_KEY};
#[cfg(feature = "scripts_timing")]
use crate::scripts_builtin::timing::{TimeRuntimeState, TIME_STACK_KEY};
use crate::script_engine::instruction::{InstructionData, InstructionHandler, InstructionMetadata, ScriptError};
use crate::script_engine::VMContext;
pub struct ContinueHandler;
impl InstructionHandler for ContinueHandler {
fn name(&self) -> &str {
"continue"
}
fn parse(&self, _args: &[&str]) -> Result<InstructionData, ScriptError> {
Ok(InstructionData::None)
}
fn execute(
&self,
vm: &mut VMContext,
_data: &InstructionData,
_metadata: Option<&InstructionMetadata>,
) -> Result<(), ScriptError> {
#[cfg(feature = "scripts_timing")]
{
let time_stack = vm.get_or_create_execution_state::<Vec<TimeRuntimeState>>(TIME_STACK_KEY);
if !time_stack.is_empty() {
let time_state = time_stack.last().unwrap();
vm.ip = time_state.end_ip;
return Ok(());
}
}
let loop_stack = vm.get_or_create_execution_state::<Vec<LoopRuntimeState>>(LOOP_STACK_KEY);
if let Some(loop_state) = loop_stack.last() {
vm.ip = loop_state.end_ip;
return Ok(());
}
Err(ScriptError::ExecutionError(
"'continue' instruction used outside of any loop or time block".into()
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_continue_no_params() {
let handler = ContinueHandler;
let result = handler.parse(&[]).unwrap();
assert!(matches!(result, InstructionData::None));
}
}