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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use super::*;

pub fn metatable(ctx: Context) -> Table {
    let metatable = Table::new(&ctx);
    metatable
        .set(ctx, "__newindex", ctx.singletons().get(ctx, no_newindex))
        .unwrap();
    metatable
        .set(
            ctx,
            "__tostring",
            Callback::from_fn(&ctx, |ctx, _fuel, mut stack| {
                stack.push_front(piccolo::String::from_static(&ctx, "Assets { root, get }").into());
                Ok(CallbackReturn::Return)
            }),
        )
        .unwrap();

    let get_callback = ctx.registry().stash(
        &ctx,
        Callback::from_fn(&ctx, move |ctx, _fuel, mut stack| {
            let (world, ecsref): (&WorldRef, &EcsRef) = stack.consume(ctx)?;

            let b = ecsref.borrow();
            let handle = b.schema_ref()?.try_cast::<UntypedHandle>()?;

            let assetref = world
                .with(|world| EcsRef {
                    data: EcsRefData::Asset(AssetRef {
                        server: (*world.resources.get::<AssetServer>().unwrap()).clone(),
                        handle: *handle,
                    }),
                    path: default(),
                })
                .into_value(ctx);
            stack.push_front(assetref);

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

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

                if let Value::String(key) = key {
                    #[allow(clippy::single_match)]
                    match key.as_bytes() {
                        b"root" => {
                            world.with(|world| {
                                let asset_server = world.resources.get::<AssetServer>().unwrap();
                                let root = asset_server.core().root;
                                let assetref = EcsRef {
                                    data: EcsRefData::Asset(AssetRef {
                                        server: (*asset_server).clone(),
                                        handle: root,
                                    }),
                                    path: default(),
                                }
                                .into_value(ctx);
                                stack.push_front(assetref);
                            });
                        }
                        b"get" => {
                            stack.push_front(ctx.registry().fetch(&get_callback).into());
                        }
                        _ => (),
                    }
                }

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

    metatable
}