use godot_ffi::conv::u32_to_usize;
use crate::builtin::{StringName, Variant};
use crate::meta::ClassId;
use crate::registry::info::{MethodFlags, PropertyInfo};
use crate::sys;
#[derive(Clone, Debug)]
pub struct MethodInfo {
pub id: i32,
pub method_name: StringName,
pub class_name: ClassId,
pub return_type: PropertyInfo,
pub arguments: Vec<PropertyInfo>,
pub default_arguments: Vec<Variant>,
pub flags: MethodFlags,
}
impl MethodInfo {
#[doc(hidden)]
pub fn into_owned_method_sys(self) -> sys::GDExtensionMethodInfo {
use crate::obj::EngineBitfield as _;
let Self {
id,
method_name,
class_name: _class_name,
return_type,
arguments,
default_arguments,
flags,
} = self;
let argument_count: u32 = arguments
.len()
.try_into()
.expect("cannot have more than `u32::MAX` arguments");
let arguments = arguments
.into_iter()
.map(|arg| arg.into_owned_property_sys())
.collect::<Box<[_]>>();
let arguments = Box::leak(arguments).as_mut_ptr();
let default_argument_count: u32 = default_arguments
.len()
.try_into()
.expect("cannot have more than `u32::MAX` default arguments");
let default_argument = default_arguments
.into_iter()
.map(|arg| arg.into_owned_var_sys())
.collect::<Box<[_]>>();
let default_arguments = Box::leak(default_argument).as_mut_ptr();
sys::GDExtensionMethodInfo {
id,
name: method_name.into_owned_string_sys(),
return_value: return_type.into_owned_property_sys(),
argument_count,
arguments,
default_argument_count,
default_arguments,
flags: flags.ord().try_into().expect("flags should be valid"),
}
}
#[doc(hidden)]
pub unsafe fn free_owned_method_sys(info: sys::GDExtensionMethodInfo) {
let sys::GDExtensionMethodInfo {
name,
return_value,
flags: _flags,
id: _id,
argument_count,
arguments,
default_argument_count,
default_arguments,
} = info;
let _name = unsafe { StringName::from_owned_string_sys(name) };
unsafe { PropertyInfo::free_owned_property_sys(return_value) };
let arguments = unsafe {
let slice = std::slice::from_raw_parts_mut(arguments, u32_to_usize(argument_count));
Box::from_raw(slice)
};
for info in arguments.iter() {
unsafe { PropertyInfo::free_owned_property_sys(*info) }
}
let default_arguments = unsafe {
let slice = std::slice::from_raw_parts_mut(
default_arguments,
u32_to_usize(default_argument_count),
);
Box::from_raw(slice)
};
for variant in default_arguments.iter() {
let _variant = unsafe { Variant::from_owned_var_sys(*variant) };
}
}
}