Skip to content

Commit 2959959

Browse files
committed
Finally get a world proxy going for lua ✨
1 parent 1a783f3 commit 2959959

File tree

9 files changed

+479
-72
lines changed

9 files changed

+479
-72
lines changed

.vscode/tasks.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
"type": "promptString",
1313
"description": "The crate location of this unit test",
1414
"default": "bevy_mod_scripting"
15+
},
16+
{
17+
"id": "features",
18+
"type": "promptString",
19+
"description": "The features to enable for this unit test",
20+
"default": ""
1521
}
1622
],
1723
"tasks": [
@@ -22,7 +28,8 @@
2228
"args": [
2329
"build_test_in_package",
2430
"PACKAGE=${input:package}",
25-
"TEST_NAME=${input:test_name}"
31+
"TEST_NAME=${input:test_name}",
32+
"TEST_FEATURES=${input:features}"
2633
]
2734
}
2835
]

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ members = [
9292
"crates/languages/bevy_mod_scripting_rhai_derive",
9393
"crates/languages/bevy_mod_scripting_rune",
9494
"crates/bevy_mod_scripting_common",
95+
"crates/bevy_mod_scripting_derive",
9596
]
9697
resolver = "2"
9798
exclude = ["crates/bevy_api_gen", "crates/macro_tests"]

crates/bevy_mod_scripting_derive/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ proc-macro = true
1919
[dependencies]
2020
paste = "1.0.7"
2121
darling = "0.20.3"
22-
syn = { version = "2.0.38", features = ["full", "fold", "extra-traits"] }
22+
syn = { version = "2.0.38", features = [
23+
"full",
24+
"fold",
25+
"extra-traits",
26+
"visit-mut",
27+
] }
2328
quote = "1.0.8"
2429
proc-macro2 = "1.0"
2530
convert_case = "0.5.0"

crates/languages/bevy_mod_scripting_lua/src/bindings/proxy.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,67 @@ use bevy_mod_scripting_core::{
1010
error::{ScriptError, ScriptResult},
1111
};
1212
use tealr::{
13-
mlu::mlua::{Error, FromLua, IntoLua, Lua, Value},
13+
mlu::mlua::{Error, FromLua, IntoLua, IntoLuaMulti, Lua, Value},
1414
ToTypename,
1515
};
1616

17-
/// Local trait alias for the [`Proxied`] trait.
17+
use super::world::Nil;
18+
19+
/// Think of this as a Local trait alias for the [`Proxy`] trait. Specifies the proxy type for a given type.
1820
pub trait LuaProxied {
1921
type Proxy;
2022
}
2123

24+
/// Proxy which acts exactly like `T` when converting to Lua, but provides a `ToTypename` implementation based on another type `N`.
25+
/// Used internally basically only to support Result types in Lua directly.
26+
/// Will be unnecessary once I get rid of tealr.
27+
pub(crate) struct TypenameProxy<T, N: ToTypename>(T, std::marker::PhantomData<N>);
28+
29+
impl<T, N: ToTypename> TypenameProxy<T, N> {
30+
pub fn new(value: T) -> Self {
31+
Self(value, std::marker::PhantomData)
32+
}
33+
}
34+
35+
impl<T, N: ToTypename> ToTypename for TypenameProxy<T, N> {
36+
fn to_typename() -> tealr::Type {
37+
N::to_typename()
38+
}
39+
}
40+
41+
impl<'a, T: IntoLuaMulti<'a>, N: ToTypename> IntoLua<'a> for TypenameProxy<T, N> {
42+
fn into_lua(self, lua: &'a Lua) -> tealr::mlu::mlua::Result<Value<'a>> {
43+
self.0
44+
.into_lua_multi(lua)
45+
.map(|mut v| v.pop_front().unwrap())
46+
}
47+
}
48+
49+
/// Proxy which converts to lua by throwing the error. Can be used inside a [`Result`] to proxy into a result which will throw the error if it's an [`Err`] when converting to Lua.
50+
pub struct ErrorProxy<E>(E);
51+
52+
impl<'a, E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>> IntoLua<'a>
53+
for ErrorProxy<E>
54+
{
55+
fn into_lua(self, _: &'a Lua) -> tealr::mlu::mlua::prelude::LuaResult<Value<'a>> {
56+
Err(Error::external(self.0))
57+
}
58+
}
59+
60+
/// This should never really need to be used, but it's here so we can use the type in Lua.
61+
impl<E> ToTypename for ErrorProxy<E> {
62+
fn to_typename() -> tealr::Type {
63+
tealr::Type::new_single("Error", tealr::KindOfType::External)
64+
}
65+
}
66+
67+
impl<E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>> Proxy for ErrorProxy<E> {
68+
type Input<'i> = E;
69+
fn proxy<'i>(value: Self::Input<'i>) -> ScriptResult<Self> {
70+
Ok(Self(value))
71+
}
72+
}
73+
2274
/// Convenience for proxying a type into lua via itself without implementing [`Proxy`] on it.
2375
/// Converts to Lua via T's implementation of IntoLua directly
2476
pub struct LuaIdentityProxy<T>(pub Option<T>);

crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ impl LuaProxied for ReflectReference {
177177
type Proxy = LuaReflectReference;
178178
}
179179

180+
impl From<LuaReflectReference> for ReflectReference {
181+
fn from(value: LuaReflectReference) -> Self {
182+
value.0
183+
}
184+
}
185+
186+
impl From<ReflectReference> for LuaReflectReference {
187+
fn from(value: ReflectReference) -> Self {
188+
Self(value)
189+
}
190+
}
191+
180192
impl TealData for LuaReflectReference {
181193
fn add_methods<'lua, T: tealr::mlu::TealDataMethods<'lua, Self>>(m: &mut T) {
182194
m.add_meta_function(
Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
1-
use tealr::{
2-
mlu::{mlua::IntoLua, TealData},
3-
ToTypename,
4-
};
1+
// use tealr::{
2+
// mlu::{mlua::IntoLua, TealData},
3+
// ToTypename,
4+
// };
55

6-
pub struct LuaResult<T, E>(Result<T, E>);
6+
// pub struct LuaResult<T, E>(Result<T, E>);
77

8-
impl<T, E> TealData for LuaResult<T, E>
9-
where
10-
T: ToTypename + for<'l> IntoLua<'l>,
11-
E: ToTypename + for<'l> IntoLua<'l>,
12-
{
13-
fn add_methods<'lua, M: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut M) {
14-
methods.add_method("is_ok", |_, this, _: ()| Ok(this.0.is_ok()));
15-
methods.add_method("is_err", |_, this, _: ()| Ok(this.0.is_err()));
16-
methods.add_function("unwrap", |_, this: LuaResult<T, E>| match this.0 {
17-
Ok(value) => Ok(value),
18-
Err(_) => Err(tealr::mlu::mlua::Error::RuntimeError(
19-
"called `LuaResult::unwrap()` on an `Err` value".to_string(),
20-
)),
21-
});
22-
methods.add_method("unwrap_err", |_, this, _: ()| match &this.0 {
23-
Ok(_) => Err(tealr::mlu::mlua::Error::RuntimeError(
24-
"called `LuaResult::unwrap_err()` on an `Ok` value".to_string(),
25-
)),
26-
Err(value) => Ok(value),
27-
});
28-
}
8+
// impl<T, E> TealData for LuaResult<T, E>
9+
// where
10+
// T: ToTypename + for<'l> IntoLua<'l>,
11+
// E: ToTypename + for<'l> IntoLua<'l>,
12+
// {
13+
// fn add_methods<'lua, M: tealr::mlu::TealDataMethods<'lua, Self>>(methods: &mut M) {
14+
// methods.add_method("is_ok", |_, this, _: ()| Ok(this.0.is_ok()));
15+
// methods.add_method("is_err", |_, this, _: ()| Ok(this.0.is_err()));
16+
// methods.add_function("unwrap", |_, this: LuaResult<T, E>| match this.0 {
17+
// Ok(value) => Ok(value),
18+
// Err(_) => Err(tealr::mlu::mlua::Error::RuntimeError(
19+
// "called `LuaResult::unwrap()` on an `Err` value".to_string(),
20+
// )),
21+
// });
22+
// methods.add_method("unwrap_err", |_, this, _: ()| match &this.0 {
23+
// Ok(_) => Err(tealr::mlu::mlua::Error::RuntimeError(
24+
// "called `LuaResult::unwrap_err()` on an `Ok` value".to_string(),
25+
// )),
26+
// Err(value) => Ok(value),
27+
// });
28+
// }
2929

30-
fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(_fields: &mut F) {}
31-
}
30+
// fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(_fields: &mut F) {}
31+
// }
3232

33-
impl<T: ToTypename, E: ToTypename> ToTypename for LuaResult<T, E> {
34-
fn to_typename() -> tealr::Type {
35-
let t = std::any::type_name::<T>();
36-
let e = std::any::type_name::<E>();
37-
tealr::Type::new_single(format!("LuaResult<{t},{e}>"), tealr::KindOfType::External)
38-
}
39-
}
33+
// impl<T: ToTypename, E: ToTypename> ToTypename for LuaResult<T, E> {
34+
// fn to_typename() -> tealr::Type {
35+
// let t = std::any::type_name::<T>();
36+
// let e = std::any::type_name::<E>();
37+
// tealr::Type::new_single(format!("LuaResult<{t},{e}>"), tealr::KindOfType::External)
38+
// }
39+
// }

crates/languages/bevy_mod_scripting_lua/src/bindings/type_registration.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,28 @@ pub struct LuaTypeRegistration(pub ScriptTypeRegistration);
1414

1515
impl_userdata_from_lua!(LuaTypeRegistration);
1616

17-
impl TealData for LuaTypeRegistration {}
17+
impl TealData for LuaTypeRegistration {
18+
fn add_fields<'lua, F: tealr::mlu::TealDataFields<'lua, Self>>(fields: &mut F) {
19+
fields.document("The [short name](https://docs.rs/bevy/latest/bevy/reflect/struct.TypeRegistration.html#method.get_short_name) of a type");
20+
fields.add_field_method_get("short_name", |_, s| Ok(s.0.short_name().to_owned()));
21+
22+
fields.document("The full name of the type");
23+
fields.add_field_method_get("type_name", |_, s| Ok(s.0.type_name()));
24+
}
25+
}
1826

1927
impl From<ScriptTypeRegistration> for LuaTypeRegistration {
2028
fn from(value: ScriptTypeRegistration) -> Self {
2129
Self(value)
2230
}
2331
}
2432

33+
impl From<&LuaTypeRegistration> for ScriptTypeRegistration {
34+
fn from(value: &LuaTypeRegistration) -> Self {
35+
todo!()
36+
}
37+
}
38+
2539
impl LuaProxied for ScriptTypeRegistration {
2640
type Proxy = LuaTypeRegistration;
2741
}

0 commit comments

Comments
 (0)