rhaiscript / rhai

Rhai - An embedded scripting language for Rust.
https://crates.io/crates/rhai
Apache License 2.0
3.63k stars 174 forks source link

Issue with `CustomType` getters #857

Closed mkeeter closed 3 months ago

mkeeter commented 3 months ago

Using #[derive(CustomType)], the resulting object doesn't appear to have getters.

use rhai::{CustomType, TypeBuilder};

#[derive(Clone, CustomType)]
struct Axes {
    x: u32,
    y: u32,
    z: u32,
}

fn axes(_ctx: rhai::NativeCallContext) -> Axes {
    Axes { x: 1, y: 2, z: 3 }
}

fn main() {
    let mut engine = rhai::Engine::new();

    engine.register_type::<Axes>();
    engine.register_fn("axes", axes);

    engine
        .run("let ax = axes(); print(ax); print(ax.x)")
        .unwrap()
}
rhai_test::Axes
thread 'main' panicked at src/main.rs:31:10:
called `Result::unwrap()` on an `Err` value: ErrorDotExpr("Unknown property 'x' - a getter is not registered for type 'rhai_test::Axes'", 1:38)

I see the same issue if I manually implement CustomType, so I don't think it's the macro's fault:

impl CustomType for Axes {
    fn build(mut builder: TypeBuilder<Self>) {
        builder.with_name("Axes");
        builder.with_get("x", |obj: &mut Self| obj.x);
        builder.with_get("y", |obj: &mut Self| obj.y);
        builder.with_get("z", |obj: &mut Self| obj.z);
    }
}

However, it does work if I implement the getters as part of the register_type call:

    engine
        .register_type::<Axes>()
        .register_get("x", |a: &mut Axes| a.x)
        .register_get("y", |a: &mut Axes| a.y)
        .register_get("z", |a: &mut Axes| a.z);

Am I holding CustomType wrong, or is there an issue here?

schungx commented 3 months ago

I think you need:

engine.build_type::<Axes>();
mkeeter commented 3 months ago

That works, thanks!