use std::sync::Arc;
use crate::{
lua::{func::internal_add_callback, get_lua_state, into_lua},
shared::{PtrMagic, module::pxs_Module, var::pxs_Var},
};
use anyhow::Result;
use mlua::prelude::*;
fn create_module(context: &Lua, module: &pxs_Module) -> Result<LuaTable> {
let module_table = context.create_table()?;
for variable in module.variables.iter() {
let var = unsafe {pxs_Var::from_borrow(variable.var) };
module_table
.set(
variable.name.to_owned(),
into_lua(context, var)?
)?;
}
for callback in module.callbacks.iter() {
let lua_function = internal_add_callback(context, callback.idx);
module_table
.set(callback.name.as_str(), lua_function?)?;
}
Ok(module_table)
}
pub fn add_module(module: Arc<pxs_Module>) -> Result<()> {
let state = get_lua_state();
let module_for_lua = Arc::clone(&module);
let package: LuaTable = state
.engine
.globals()
.get("package")?;
let preload: LuaTable = package
.get("preload")?;
for child in module.modules.iter() {
let child_module = child.clone();
add_module(Arc::clone(&child_module))?;
}
let loader = state
.engine
.create_function(move |lua, _: ()| {
let module_table = create_module(lua, &module_for_lua);
if module_table.is_err() {
Err(LuaError::RuntimeError(module_table.unwrap_err().to_string()))
} else {
Ok(module_table.unwrap())
}
})?;
preload
.set(module.name.clone(), loader)?;
Ok(())
}