use crate::{
create_raw_string, free_raw_string,
python::{
add_new_name_idx_fn, exec_py, make_private, pocketpy, pocketpy_bridge, var_to_pocketpyref,
},
shared::{
PtrMagic,
module::pxs_Module,
var::pxs_Var,
},
};
pub(super) fn create_module(module: &pxs_Module) {
let module_name = module.name.clone();
let c_module_name = create_raw_string!(module_name.clone());
let pymodule = unsafe {
let posmodule = pocketpy::py_getmodule(c_module_name);
if posmodule.is_null() {
pocketpy::py_newmodule(c_module_name)
} else {
posmodule
}
};
for var in module.variables.iter() {
let var_name = var.name.clone();
let c_var_name = create_raw_string!(var_name);
let tmp = unsafe { pocketpy::py_pushtmp() };
var_to_pocketpyref(
tmp,
unsafe { pxs_Var::from_borrow(var.var) },
Some(&module_name),
);
unsafe {
let py_name = pocketpy::py_name(c_var_name);
pocketpy::py_setattr(pymodule, py_name, tmp);
free_raw_string!(c_var_name);
}
}
for method in module.callbacks.iter() {
let full_name = method.full_name.clone();
add_new_name_idx_fn(full_name.clone(), method.idx);
let private_name = make_private(&full_name);
let c_name = create_raw_string!(private_name.clone());
let bridge_code = format!(
r#"
def {}(*args):
return {private_name}('{}', *args)
"#,
method.name, full_name
);
unsafe {
pocketpy::py_bindfunc(pymodule, c_name, Some(pocketpy_bridge));
}
exec_py(
&bridge_code,
format!("<{}>", module_name).as_str(),
&module_name,
);
unsafe {
free_raw_string!(c_name);
}
}
for im in module.modules.iter() {
create_module(im);
}
unsafe {
free_raw_string!(c_module_name);
}
}