use crate::{Error, Result};
use il2cpp_bridge_rs::structs::Field;
use std::ffi::c_void;
pub unsafe trait Il2CppValueType: Copy + 'static {
unsafe fn load_field(field: &Field) -> Result<Self>;
unsafe fn store_field(field: &Field, val: Self) -> Result<()>;
unsafe fn invoke_result(
method: &il2cpp_bridge_rs::structs::Method,
args: &[*mut std::ffi::c_void],
) -> Result<Self> {
unsafe { method.call::<Self>(args).map_err(Error::Bridge) }
}
}
macro_rules! impl_value_type_direct {
($($t:ty),*) => {
$(
unsafe impl Il2CppValueType for $t {
unsafe fn load_field(field: &Field) -> Result<Self> {
unsafe { field.get_value::<$t>().map_err(Error::Bridge) }
}
unsafe fn store_field(field: &il2cpp_bridge_rs::structs::Field, val: Self) -> Result<()> {
unsafe { field.set_value::<$t>(val).map_err(Error::Bridge) }
}
}
)*
};
}
impl_value_type_direct!(i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool);
pub unsafe trait Args {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn to_arg_ptrs(&self) -> Vec<*mut c_void>;
}
unsafe impl Args for () {
fn len(&self) -> usize {
0
}
fn to_arg_ptrs(&self) -> Vec<*mut c_void> {
Vec::new()
}
}
macro_rules! impl_args_tuple {
($($T:ident),+) => {
#[allow(non_snake_case)]
unsafe impl<$($T: Il2CppValueType),*> Args for ($($T,)*) {
fn len(&self) -> usize {
let ($($T,)*) = self;
let mut n = 0;
$(let _ = $T; n += 1;)*
n
}
fn to_arg_ptrs(&self) -> Vec<*mut c_void> {
let ($($T,)*) = self;
vec![$($T as *const $T as *mut c_void),*]
}
}
};
}
impl_args_tuple!(A);
impl_args_tuple!(A, B);
impl_args_tuple!(A, B, C);
impl_args_tuple!(A, B, C, D);
impl_args_tuple!(A, B, C, D, E);
impl_args_tuple!(A, B, C, D, E, F);
impl_args_tuple!(A, B, C, D, E, F, G);
impl_args_tuple!(A, B, C, D, E, F, G, H);
impl_args_tuple!(A, B, C, D, E, F, G, H, I);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
impl_args_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);