#[cfg(doc)]
use crate::{
bindings::squirreldatatypes::SQObject,
errors::CallError,
high::squirrel::{call_sq_function, call_sq_object_function},
};
#[macro_export]
macro_rules! call_sq_function {
($sqvm:expr, $sqfunctions:expr, $function_name:expr, $( $arg:expr ),* ) => (
{
{
use $crate::high::squirrel_traits::PushToSquirrelVm;
const ARGS_AMOUNT: i32 = 1 + $crate::macros::sq_utils::__arg_count_helper([$($crate::__replace_expr!($arg)),*]) as i32;
let mut obj = std::mem::MaybeUninit::<$crate::bindings::squirreldatatypes::SQObject>::zeroed();
let ptr = obj.as_mut_ptr();
let function_name = $crate::to_c_string!(std::convert::Into::<String>::into($function_name));
let sqvm = $sqvm;
let result = unsafe {
($sqfunctions.sq_getfunction)(sqvm.as_ptr(), function_name.as_ptr(), ptr, std::ptr::null())
};
if result != 0 {
Err($crate::errors::CallError::FunctionNotFound(function_name.to_string_lossy().into())) } else {
unsafe {
($sqfunctions.sq_pushobject)(sqvm.as_ptr(), ptr);
($sqfunctions.sq_pushroottable)(sqvm.as_ptr());
$(
$arg.push_to_sqvm(sqvm, $sqfunctions);
)*
if ($sqfunctions.sq_call)(sqvm.as_ptr(), ARGS_AMOUNT, true as u32, true as u32) == $crate::bindings::squirrelclasstypes::SQRESULT::SQRESULT_ERROR {
Err($crate::errors::CallError::FunctionFailedToExecute)
} else {
Ok(())
}
}
}
}
}
)
}
#[macro_export]
macro_rules! call_sq_object_function {
($sqvm:expr, $sqfunctions:expr, $obj:expr, $( $arg:expr ),* ) => (
{
{
#[allow(unused_imports)]
use $crate::high::squirrel_traits::PushToSquirrelVm;
const ARGS_AMOUNT: i32 = 1 + $crate::macros::sq_utils::__arg_count_helper([$($crate::__replace_expr!($arg)),*]) as i32;
let sqfunctions = $sqfunctions;
let sqvm = $sqvm;
let ptr = $obj.as_callable();
unsafe {
(sqfunctions.sq_pushobject)(sqvm.as_ptr(), ptr);
(sqfunctions.sq_pushroottable)(sqvm.as_ptr());
$(
$arg.push_to_sqvm(sqvm, sqfunctions);
)*
let result = if (sqfunctions.sq_call)(sqvm.as_ptr(), ARGS_AMOUNT, true as u32, true as u32) == $crate::bindings::squirrelclasstypes::SQRESULT::SQRESULT_ERROR {
Err($crate::errors::CallError::FunctionFailedToExecute)
} else {
Ok(())
};
result
}
}
}
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! __replace_expr {
($_t:tt) => {
()
};
}
#[doc(hidden)]
pub const fn __arg_count_helper<const N: usize>(_: [(); N]) -> usize {
N
}
#[cfg(test)]
#[allow(unused_mut)]
mod test {
use crate as rrplug;
use rrplug::prelude::*;
use rrplug::{bindings::squirreldatatypes::SQClosure, high::squirrel::SQHandle};
use rrplug_proc::*;
#[sqfunction(VM = "Server")]
fn test_call_funcs2(mut func: SQHandle<SQClosure>, test: String) -> Result<String, String> {
call_sq_object_function!(sqvm, sq_functions, func, test.clone())
.map_err(|err| err.to_string())?;
call_sq_function!(sqvm, sq_functions, "SomeSQFunc", 9347, 3892, 23423)
.map_err(|err| err.to_string())?;
Ok("test".to_string())
}
}