mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
Manually manage the lifecycle of scope userdata through Scope::add_destructor() and UserData::destroy()
This commit is contained in:
parent
2ee619193e
commit
0f00808146
16 changed files with 50 additions and 39 deletions
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, UserData, UserDataFields};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Config {
|
||||
inner: *const yazi_core::tab::Config,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Config {
|
|||
impl Config {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Config) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use yazi_config::THEME;
|
|||
use yazi_plugin::{bindings::Range, elements::Style};
|
||||
use yazi_shared::MIME_DIR;
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
use crate::Ctx;
|
||||
|
||||
pub(super) struct File {
|
||||
|
|
@ -31,7 +31,7 @@ impl File {
|
|||
folder: &yazi_fs::Folder,
|
||||
tab: &yazi_core::tab::Tab,
|
||||
) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { idx, folder, tab })
|
||||
Lives::scoped_userdata(Self { idx, folder, tab })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::{Deref, Range};
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::{File, Filter, SCOPE};
|
||||
use super::{File, Filter, Lives};
|
||||
|
||||
pub(super) struct Files {
|
||||
window: Range<usize>,
|
||||
|
|
@ -23,7 +23,7 @@ impl Files {
|
|||
folder: &yazi_fs::Folder,
|
||||
tab: &yazi_core::tab::Tab,
|
||||
) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { window, folder, tab })
|
||||
Lives::scoped_userdata(Self { window, folder, tab })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Filter {
|
||||
inner: *const yazi_fs::Filter,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Filter {
|
|||
impl Filter {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_fs::Filter) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Finder {
|
||||
inner: *const yazi_core::tab::Finder,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Finder {
|
|||
impl Finder {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Finder) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use mlua::{AnyUserData, Lua, UserData, UserDataFields};
|
|||
use yazi_config::LAYOUT;
|
||||
use yazi_plugin::{bindings::Cast, url::Url};
|
||||
|
||||
use super::{File, Files, SCOPE};
|
||||
use super::{File, Files, Lives};
|
||||
|
||||
pub(super) struct Folder {
|
||||
window: Range<usize>,
|
||||
|
|
@ -33,7 +33,7 @@ impl Folder {
|
|||
}
|
||||
};
|
||||
|
||||
SCOPE.create_userdata(Self { window, inner, tab })
|
||||
Lives::scoped_userdata(Self { window, inner, tab })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use mlua::{AnyUserData, UserData};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Iter<I: Iterator<Item = T>, T> {
|
||||
inner: I,
|
||||
|
|
@ -10,7 +10,7 @@ pub(super) struct Iter<I: Iterator<Item = T>, T> {
|
|||
impl<I: Iterator<Item = T> + 'static, T: 'static> Iter<I, T> {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: I) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner, count: 0 })
|
||||
Lives::scoped_userdata(Self { inner, count: 0 })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use std::mem;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use scopeguard::defer;
|
||||
use mlua::{AnyUserData, UserData};
|
||||
use tracing::error;
|
||||
use yazi_plugin::LUA;
|
||||
use yazi_shared::RoCell;
|
||||
|
||||
use crate::Ctx;
|
||||
|
||||
pub(super) static SCOPE: RoCell<&mlua::Scope> = RoCell::new();
|
||||
static TO_DESTROY: RoCell<RefCell<Vec<AnyUserData>>> = RoCell::new_const(RefCell::new(Vec::new()));
|
||||
|
||||
pub(crate) struct Lives;
|
||||
|
||||
|
|
@ -20,14 +20,14 @@ impl Lives {
|
|||
|
||||
pub(crate) fn scope<T>(cx: &Ctx, f: impl FnOnce() -> mlua::Result<T>) -> mlua::Result<T> {
|
||||
let result = LUA.scope(|scope| {
|
||||
defer! { SCOPE.drop(); }
|
||||
SCOPE.init(*unsafe {
|
||||
mem::transmute::<&&mut mlua::Scope<'_, '_>, &&mut mlua::Scope<'static, 'static>>(&scope)
|
||||
scope.add_destructor(|| {
|
||||
for ud in TO_DESTROY.borrow_mut().drain(..) {
|
||||
ud.destroy().expect("failed to destruct scoped userdata");
|
||||
}
|
||||
});
|
||||
LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?;
|
||||
|
||||
let globals = LUA.globals();
|
||||
globals.raw_set(
|
||||
LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?;
|
||||
LUA.globals().raw_set(
|
||||
"cx",
|
||||
LUA.create_table_from([
|
||||
("active", super::Tab::make(cx.manager.active())?),
|
||||
|
|
@ -45,4 +45,14 @@ impl Lives {
|
|||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn scoped_userdata<T>(data: T) -> mlua::Result<AnyUserData>
|
||||
where
|
||||
T: UserData + 'static,
|
||||
{
|
||||
let ud = LUA.create_userdata(data)?;
|
||||
TO_DESTROY.borrow_mut().push(ud.clone());
|
||||
Ok(ud)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Mode {
|
||||
inner: *const yazi_core::tab::Mode,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Mode {
|
|||
impl Mode {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::ops::Deref;
|
|||
use mlua::{AnyUserData, UserData, UserDataFields};
|
||||
use yazi_config::LAYOUT;
|
||||
|
||||
use super::{Folder, SCOPE};
|
||||
use super::{Folder, Lives};
|
||||
|
||||
pub(super) struct Preview {
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
|
|
@ -18,7 +18,7 @@ impl Deref for Preview {
|
|||
impl Preview {
|
||||
#[inline]
|
||||
pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { tab })
|
||||
Lives::scoped_userdata(Self { tab })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{collections::{HashMap, hash_map}, ops::Deref};
|
|||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataMethods, UserDataRefMut};
|
||||
use yazi_plugin::{bindings::Cast, url::Url};
|
||||
|
||||
use super::{Iter, SCOPE};
|
||||
use super::{Iter, Lives};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct Selected {
|
||||
|
|
@ -19,7 +19,7 @@ impl Deref for Selected {
|
|||
impl Selected {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &HashMap<yazi_shared::fs::Url, u64>) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -32,7 +32,6 @@ impl UserData for Selected {
|
|||
|
||||
methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
||||
let iter = lua.create_function(
|
||||
// FIXME: UserDataRef
|
||||
|lua, mut iter: UserDataRefMut<Iter<hash_map::Keys<yazi_shared::fs::Url, u64>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::ops::Deref;
|
|||
use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods};
|
||||
use yazi_plugin::url::UrlRef;
|
||||
|
||||
use super::{Config, Finder, Folder, Mode, Preview, SCOPE, Selected};
|
||||
use super::{Config, Finder, Folder, Lives, Mode, Preview, Selected};
|
||||
|
||||
pub(super) struct Tab {
|
||||
inner: *const yazi_core::tab::Tab,
|
||||
|
|
@ -18,7 +18,7 @@ impl Deref for Tab {
|
|||
impl Tab {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::{SCOPE, Tab};
|
||||
use super::{Lives, Tab};
|
||||
|
||||
pub(super) struct Tabs {
|
||||
inner: *const yazi_core::manager::Tabs,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Tabs {
|
|||
impl Tabs {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::manager::Tabs) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields};
|
||||
|
||||
use super::SCOPE;
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Tasks {
|
||||
inner: *const yazi_core::tasks::Tasks,
|
||||
|
|
@ -17,7 +17,7 @@ impl Deref for Tasks {
|
|||
impl Tasks {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{collections::hash_set, ops::Deref};
|
|||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRefMut};
|
||||
use yazi_plugin::{bindings::Cast, url::Url};
|
||||
|
||||
use super::{Iter, SCOPE};
|
||||
use super::{Iter, Lives};
|
||||
|
||||
pub(super) struct Yanked {
|
||||
inner: *const yazi_core::manager::Yanked,
|
||||
|
|
@ -18,7 +18,7 @@ impl Deref for Yanked {
|
|||
impl Yanked {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::manager::Yanked) -> mlua::Result<AnyUserData> {
|
||||
SCOPE.create_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -35,7 +35,6 @@ impl UserData for Yanked {
|
|||
|
||||
methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
||||
let iter = lua.create_function(
|
||||
// FIXME: UserDataRef
|
||||
|lua, mut iter: UserDataRefMut<Iter<hash_set::Iter<yazi_shared::fs::Url>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ impl<T> RoCell<T> {
|
|||
#[inline]
|
||||
pub const fn new() -> Self { Self(UnsafeCell::new(None)) }
|
||||
|
||||
#[inline]
|
||||
pub const fn new_const(value: T) -> Self { Self(UnsafeCell::new(Some(value))) }
|
||||
|
||||
#[inline]
|
||||
pub fn init(&self, value: T) {
|
||||
debug_assert!(!self.initialized());
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue