mlua icon indicating copy to clipboard operation
mlua copied to clipboard

Push mutable reference to variable to script

Open konceptosociala opened this issue 2 years ago • 1 comments

I can capture rust variable with chunk! macro like

let name = "Rustacean";
lua.load(chunk! {
    print("hello, " .. $name)
}).exec()

But what if I have external script inside a file script.lua, is it able to capture rust mutable reference to Lua?

konceptosociala avatar Jul 25 '23 17:07 konceptosociala

My proximate solution is like

main.rs:

use std::{path::Path, fmt::Display};

use mlua::{Lua, UserData};

#[derive(Clone)]
struct MyStruct(i32);

impl Display for MyStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl UserData for MyStruct {
    fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
        fields.add_field_method_get("val", |_, this| {
            Ok(this.0)
        });
    }

    fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
        methods.add_method_mut("add", |_, this, value: i32| {
            this.0 += value;
            Ok(())
        });
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let lua = Lua::new();
    let mut my_struct = MyStruct(12);

    for _ in 0..5 {
        lua.globals().set("MyStruct", my_struct)?;
        lua.load(Path::new("script.lua")).exec()?;
        my_struct = lua.globals().get::<&str, MyStruct>("MyStruct")?;
    }

    Ok(())
}

script.lua:

local my_struct = MyStruct;

print("Old value: ", my_struct.val)
my_struct:add(15)
print("New value: ", my_struct.val)

Output:

Old value: 	12
New value: 	27
Old value: 	27
New value: 	42
Old value: 	42
New value: 	57
Old value: 	57
New value: 	72
Old value: 	72
New value: 	87

konceptosociala avatar Jul 25 '23 21:07 konceptosociala