mlua icon indicating copy to clipboard operation
mlua copied to clipboard

`__gc` metamethod might be useful

Open attila-lin opened this issue 4 years ago • 3 comments

Hi!

I created a userdata just a handler with a field index, which the real value store in Lua.

I want to delete the real value when the userdata is gced. But I can't find a way to do it just with imple the Drop trait.

Any idea?

attila-lin avatar Aug 02 '21 12:08 attila-lin

Could you provide a code example?

__gc is reserved for internal use (for Drop especially) but you should be able to do cleanup by implementing drop().

If you want in particular to execute arbitrary Lua code on drop (== __gc) you can add Lua instance to your userdata.

    struct MyUserdata {
        lua: Rc<Lua>,
    }

    impl LuaUserData for MyUserdata {}

    impl Drop for MyUserdata {
        fn drop(&mut self) {
            let _ = self.lua.load("print(\"userdata dropped\")").exec();
        }
    }

khvzak avatar Aug 02 '21 21:08 khvzak

struct MyUserdataHander {
    idx: u64
}

struct MyUserdata;

impl UserData for MyUserdata {
    methods.add_function("Some", |lua, value: Value| {
        let router_ud = lua.globals().get::<_, AnyUserData>("OptionRouterUD")?;
                let idx = OptionalRouter::register(lua, (router_ud, Some(value)))?;
                Ok(MyUserdataHander { idx })
    });
}

I thought about the Rc of Lua in the userdata, but I will have to struggle Rc<&lua> lifetime because the add_function provides the &Lua.

attila-lin avatar Aug 03 '21 01:08 attila-lin

Probably the easiest option would be passing Rc<Lua> to MyUserdata to create MyUserdataHander then.

Alternalively you can store temporary values in Registry and create via Lua::create_registry_value. RegistryKey has Drop implemented to remove data from the Registry on drop (but you still need to call Lua:: expire_registry_values)

I maybe implement a better way how to attach custom destructors to UserData with executing arbitrary Lua code. Need to think about it.

khvzak avatar Aug 03 '21 09:08 khvzak