1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use super::*;

pub fn metatable(ctx: Context) -> Table {
    let metatable = Table::new(&ctx);
    metatable
        .set(
            ctx,
            "__tostring",
            Callback::from_fn(&ctx, |ctx, _fuel, mut stack| {
                stack.push_front(
                    piccolo::String::from_static(&ctx, "World { resources, components, assets }")
                        .into(),
                );
                Ok(CallbackReturn::Return)
            }),
        )
        .unwrap();

    metatable
        .set(ctx, "__newindex", ctx.singletons().get(ctx, no_newindex))
        .unwrap();
    metatable
        .set(
            ctx,
            "__index",
            Callback::from_fn(&ctx, move |ctx, _fuel, mut stack| {
                let (world, key): (&WorldRef, lua::String) = stack.consume(ctx)?;

                let singletons = ctx.singletons();
                let resources_metatable = singletons.get(ctx, super::resources::metatable);
                let components_metatable = singletons.get(ctx, super::components::metatable);
                let assets_metatable = singletons.get(ctx, super::assets::metatable);

                match key.as_bytes() {
                    b"resources" => {
                        let resources = UserData::new_static(&ctx, world.clone());
                        resources.set_metatable(&ctx, Some(resources_metatable));
                        stack.push_front(resources.into());
                    }
                    b"components" => {
                        let components = UserData::new_static(&ctx, world.clone());
                        components.set_metatable(&ctx, Some(components_metatable));
                        stack.push_front(components.into());
                    }
                    b"assets" => {
                        let assets = UserData::new_static(&ctx, world.clone());
                        assets.set_metatable(&ctx, Some(assets_metatable));
                        stack.push_front(assets.into());
                    }
                    _ => (),
                }

                Ok(CallbackReturn::Return)
            }),
        )
        .unwrap();

    metatable
}