use mlua::{Table, UserData, Value}; use super::{cell::Cell, loader::Loader, luaref::SheetLuaRef, Sheet}; static mut REGISTER: Vec = Vec::new(); pub type SheetId = usize; #[derive(Debug)] pub struct Register; impl Register { pub fn create(width: usize, height: usize) -> SheetId { unsafe { let id = REGISTER.len(); let sheet = Sheet::new(width, height, id); REGISTER.push(sheet); id } } pub fn create_from_table(table: Table) -> mlua::Result { let id = unsafe { REGISTER.len() }; let height = table.len()? as usize; let mut width: usize = 0; for column in table.clone().pairs::() { width = width.max(column?.1.len()? as usize) } let mut sheet = Sheet::new(width, height, id); for row_res in table.pairs::() { let (row, c) = row_res?; for column_res in c.pairs::() { let (column, cell) = column_res?; sheet.set_cell(row, column, cell) } } unsafe { REGISTER.push(sheet) }; Ok(id) } pub fn get(id: SheetId) -> Option<&'static mut Sheet> { unsafe { REGISTER.get_mut(id) } } } impl UserData for Register { fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("create", |lua, table: Table| { let id = Register::create_from_table(table)?; let luaref = SheetLuaRef::new(id); if let Ok(ud) = lua.create_userdata(luaref) { Ok(Value::UserData(ud)) } else { Ok(Value::Nil) } }); methods.add_function("open", |lua, path: String| { if let Some(id) = Loader::get().load_sheet(path, lua) { let luaref = SheetLuaRef::new(id); if let Ok(ud) = lua.create_userdata(luaref) { return Ok(Value::UserData(ud)); } } Ok(Value::Nil) }); methods.add_function("get", |lua, id: SheetId| { if Register::get(id).is_some() { let luaref = SheetLuaRef::new(id); if let Ok(ud) = lua.create_userdata(luaref) { Ok(Value::UserData(ud)) } else { Ok(Value::Nil) } } else { Ok(Value::Nil) } }) } }