use std::mem::MaybeUninit; use hashbrown::HashMap; use mlua::{AnyUserData, UserData}; use scopeguard::defer; use tracing::error; use yazi_plugin::LUA; use super::{Core, PtrCell}; use crate::lives::MutCell; pub(super) static TO_DESTROY: MutCell> = MutCell::new(Vec::new()); pub(super) static FILE_CACHE: MutCell< MaybeUninit, AnyUserData>>, > = MutCell::new(MaybeUninit::uninit()); pub struct Lives; impl Lives { pub fn scope(core: &mut yazi_core::Core, f: F) -> mlua::Result where F: FnOnce(&mut yazi_core::Core) -> mlua::Result, { defer! { unsafe { (*FILE_CACHE.get()).assume_init_mut().clear(); for ud in (*TO_DESTROY.get()).drain(..) { ud.destroy().expect("failed to destruct scoped userdata"); } } } LUA.set_named_registry_value("cx", Core::make(core)?)?; LUA.globals().raw_set("cx", Core::make(core)?)?; let result = f(core); if let Err(ref e) = result { error!("{e}"); } result } pub(crate) fn scoped_userdata(data: T) -> mlua::Result where T: UserData + 'static, { let ud = LUA.create_userdata(data)?; unsafe { &mut *TO_DESTROY.get() }.push(ud.clone()); Ok(ud) } }