unref LuaRefs when they are dropped
This commit is contained in:
parent
fcc33d4607
commit
a3dbe82613
|
@ -7,7 +7,7 @@ use mlua_sys as lua;
|
|||
#[derive(Clone)]
|
||||
pub struct Function<'a> {
|
||||
state: &'a State,
|
||||
lref: LuaRef,
|
||||
lref: LuaRef<'a>,
|
||||
pub(crate) error_handler: Option<Arc<Function<'a>>>,
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ impl<'a> PushToLuaStack<'a> for Function<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Function<'a> {
|
||||
pub fn from_ref(state: &'a State, lref: LuaRef) -> Self {
|
||||
pub fn from_ref(state: &'a State, lref: LuaRef<'a>) -> Self {
|
||||
Self {
|
||||
state,
|
||||
lref,
|
||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -143,34 +143,48 @@ fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// A LuaRef is a a handle to something in Lua.
|
||||
///
|
||||
/// These are created with `luaL_ref`, they can be created from anything on the top of the stack
|
||||
/// with [`LuaRef::from_stack`]. The references are automatically freed with `luaL_unref` when
|
||||
/// the inner Arc detects a single strong count.
|
||||
#[derive(Clone)]
|
||||
pub struct LuaRef(Arc<i32>);
|
||||
pub struct LuaRef<'a>(Arc<i32>, &'a State);
|
||||
|
||||
impl From<i32> for LuaRef {
|
||||
fn from(value: i32) -> Self {
|
||||
Self(Arc::new(value))
|
||||
impl<'a> Drop for LuaRef<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let s = self.1.state_ptr();
|
||||
|
||||
if Arc::strong_count(&self.0) == 1 {
|
||||
lua::luaL_unref(s, lua::LUA_REGISTRYINDEX, *self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaRef {
|
||||
impl<'a> LuaRef<'a> {
|
||||
pub fn new(lua_ref: i32, state: &'a State) -> Self {
|
||||
Self(Arc::new(lua_ref), state)
|
||||
}
|
||||
|
||||
/// Creates a reference to what is at the top of the stack.
|
||||
pub unsafe fn from_stack(state: &State) -> Result<Self> {
|
||||
pub unsafe fn from_stack(state: &'a State) -> Result<Self> {
|
||||
let s = state.state_ptr();
|
||||
|
||||
let r = lua::luaL_ref(s, lua::LUA_REGISTRYINDEX);
|
||||
if r == lua::LUA_REFNIL {
|
||||
Err(Error::Nil)
|
||||
} else {
|
||||
Ok(LuaRef::from(r))
|
||||
Ok(LuaRef::new(r, state))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PushToLuaStack<'a> for LuaRef {
|
||||
impl<'a> PushToLuaStack<'a> for LuaRef<'a> {
|
||||
unsafe fn push_to_lua_stack(&self, state: &State) -> Result<()> {
|
||||
let s = state.state_ptr();
|
||||
|
||||
unsafe {
|
||||
state.ensure_stack(1)?;
|
||||
let top = lua::lua_gettop(s);
|
||||
let ty = lua::lua_rawgeti(s, lua::LUA_REGISTRYINDEX, *self.0 as i64);
|
||||
|
@ -179,7 +193,6 @@ impl<'a> PushToLuaStack<'a> for LuaRef {
|
|||
if ty == lua::LUA_TNIL || ty == lua::LUA_TNONE || top == new_top {
|
||||
return Err(Error::Nil);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -88,8 +88,8 @@ struct ClosureData<'a> {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ExtraSpace {
|
||||
userdata_metatables: HashMap<TypeId, LuaRef>,
|
||||
struct ExtraSpace<'a> {
|
||||
userdata_metatables: HashMap<TypeId, LuaRef<'a>>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{ensure_type, FromLuaStack, LuaRef, PushToLuaStack, Result, StackGuar
|
|||
#[derive(Clone)]
|
||||
pub struct Table<'a> {
|
||||
state: &'a State,
|
||||
pub(crate) lref: LuaRef,
|
||||
pub(crate) lref: LuaRef<'a>,
|
||||
/// a boolean indicating if this Table is a Metatable
|
||||
mt_marker: bool,
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl<'a> Table<'a> {
|
|||
}
|
||||
|
||||
/// Construct a table with a lua reference to one.
|
||||
pub fn with_ref(state: &'a State, lua_ref: LuaRef, is_metatable: bool) -> Result<Self> {
|
||||
pub fn with_ref(state: &'a State, lua_ref: LuaRef<'a>, is_metatable: bool) -> Result<Self> {
|
||||
let s = state.state_ptr();
|
||||
|
||||
unsafe {
|
||||
|
|
|
@ -255,12 +255,12 @@ pub trait Userdata: Sized {
|
|||
/// A handle to some userdata on the stack
|
||||
#[derive(Clone)]
|
||||
pub struct AnyUserdata<'a> {
|
||||
pub(crate) lref: LuaRef,
|
||||
pub(crate) lref: LuaRef<'a>,
|
||||
state: &'a State,
|
||||
}
|
||||
|
||||
impl<'a> AnyUserdata<'a> {
|
||||
pub fn from_ref(state: &'a State, lref: LuaRef) -> Self {
|
||||
pub fn from_ref(state: &'a State, lref: LuaRef<'a>) -> Self {
|
||||
Self {
|
||||
lref,
|
||||
state,
|
||||
|
|
Loading…
Reference in New Issue