Skip to content

Commit 2ba0b4e

Browse files
committed
Add back metamethods for math types
1 parent 29b9e6f commit 2ba0b4e

File tree

16 files changed

+2330
-981
lines changed

16 files changed

+2330
-981
lines changed

assets/scripts/bevy_api.lua

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,29 @@ function on_event()
107107

108108
print("============")
109109

110+
print(Vec3.new(0,1,0) + Vec3.new(1,0,0))
111+
print(Vec3.new(0,1,0):any_orthonormal_vector())
112+
print(comp.mat3[1])
113+
print(Vec3.new(0,1,0):any_orthonormal_vector() + comp.mat3[1])
110114
local complex_vec_op = Vec3.new(0,1,0):any_orthonormal_vector() + comp.mat3[1]
111115
print("(0,1,0).any_orthonormal_vector() + mat3.x_axis is: ", complex_vec_op)
112116

113117
local new_mat3 = Mat3.from_cols(Vec3.new(1,0,0),Vec3.new(0,1,0),Vec3.new(0,0,-1))
114118
print("new_mat3 is:", new_mat3)
115119

116-
comp.vec2 = comp.vec2 + comp.vec2
120+
-- comp.vec2 = comp.vec2 + comp.vec2
121+
print("A")
117122
comp.usize = comp.vec2:min_element()
123+
124+
print("B")
118125
comp.f32 = comp.f32 + comp.f32 + comp.vec2:min_element()
126+
print("C")
119127
comp.vec2 = Vec2.new(2,1)
128+
print("D")
120129
comp.quat = Quat.from_xyzw(3,2,1,4)
130+
print("E")
121131
comp.mat3[1] = Vec3.new(69,69,69)
132+
print("F")
122133

123134

124135
world:exit()

crates/bevy_api_gen/templates/function.tera

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,27 @@ r#"
1212
{% endif %}
1313
as_trait="{{ function.from_trait_path }}",
1414
{%- endif -%}
15-
1615
{% if is_op %}
1716
composite="{{ function.ident }}",
1817
{% endif %}
1918

20-
{#
21-
{% if function.has_self and not is_op %}
22-
kind="{% if function.args.0.ty is starting_with("&mut") %}Mutating{% endif %}Method",
23-
{% elif is_op %}
24-
kind="MetaFunction",
25-
{% else %}
26-
kind="Function",
27-
{% endif %}
28-
29-
{%- if function.output.reflection_strategy == "Proxy" -%}
30-
output(proxy),
31-
{%- endif -%}
32-
33-
34-
35-
{% if function.from_trait_path == "std::ops::Neg" %}
36-
metamethod="Unm",
37-
{% elif function.from_trait_path == "std::ops::Mul" %}
38-
metamethod="Mul",
39-
{% elif function.from_trait_path == "std::ops::Add" %}
40-
metamethod="Add",
41-
{% elif function.from_trait_path == "std::ops::Sub" %}
42-
metamethod="Sub",
43-
{% elif function.from_trait_path == "std::ops::Div" %}
44-
metamethod="Div",
45-
{% elif function.from_trait_path == "std::ops::Rem" %}
46-
metamethod="Mod",
47-
{% elif function.from_trait_path == "std::cmp::PartialEq" %}
48-
metamethod="Eq",
19+
{% if function.from_trait_path %}
20+
{% if function.from_trait_path is starting_with("std::ops::Neg") %}
21+
metamethod="Unm",
22+
{% elif function.from_trait_path is starting_with("std::ops::Mul") %}
23+
metamethod="Mul",
24+
{% elif function.from_trait_path is starting_with("std::ops::Add") %}
25+
metamethod="Add",
26+
{% elif function.from_trait_path is starting_with("std::ops::Sub") %}
27+
metamethod="Sub",
28+
{% elif function.from_trait_path is starting_with("std::ops::Div") %}
29+
metamethod="Div",
30+
{% elif function.from_trait_path is starting_with("std::ops::Rem") %}
31+
metamethod="Mod",
32+
{% elif function.from_trait_path is starting_with("std::cmp::PartialEq") %}
33+
metamethod="Eq",
34+
{% endif %}
4935
{% endif %}
50-
#}
5136
)]
5237
{% if function.is_unsafe %}unsafe {% endif -%}fn {{ function.ident }} (
5338
{%- filter separated(delimeter=", ", split_at="---", ignore_first=true) -%}

crates/bevy_api_gen/templates/macros.tera

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ fn index(&mut self, idx: usize, val: {{ num_type }}) -> () {
1313
{% endmacro vector_newindex %}
1414

1515
{% macro matrix_index(col_type, mat_type, bms_core_path) %}
16-
#[lua(metamethod="Index")]
17-
fn index(_self: LuaIdentityProxy<Self>, idx: usize) -> LuaIdentityProxy<{{ col_type | prefix_lua }}> {
18-
let mut curr_ref = _self.0.clone();
19-
let def_ref = {{bms_core_path}}::bindings::DeferredReflection{
20-
get: std::sync::Arc::new(|ref_| Err(bevy::reflect::ReflectPathError::InvalidDowncast)),
21-
get_mut: std::sync::Arc::new(move |ref_| {
22-
if let Some(ret) = ref_.try_as_reflect_mut().map(|ret| ret.downcast_mut::<bevy::math::{{ mat_type }}>()).flatten(){
23-
Ok(ret.col_mut(idx - 1))
24-
} else {
25-
Err(bevy::reflect::ReflectPathError::InvalidDowncast)
26-
}
27-
})
16+
#[lua(metamethod="Index", with_context, no_proxy)]
17+
fn index(_self: Self, idx: usize, lua: &tealr::mlu::mlua::Lua) -> Result<tealr::mlu::mlua::Value, tealr::mlu::mlua::Error> {
18+
let mut curr_ref = _self.0;
19+
20+
let path = match idx {
21+
1 => "x_axis",
22+
2 => "y_axis",
23+
3 => "z_axis",
24+
4 => "w_axis",
25+
_ => "unknown_axis"
2826
};
29-
curr_ref.reflect_path.push({{bms_core_path}}::bindings::ReflectionPathElem::new_deferred(def_ref));
30-
{{ col_type | prefix_lua }}(curr_ref)
27+
28+
let parsed_path = bevy::reflect::ParsedPath::parse_static(path).expect("invariant");
29+
curr_ref.index_path(bevy_mod_scripting_core::bindings::ReflectionPathElem::new_reflection(parsed_path));
30+
crate::bindings::reference::LuaReflectReference(curr_ref).to_lua_proxy(lua)
3131
}
3232
{% endmacro matrix_index %}
3333

crates/bevy_mod_scripting_core/src/bindings/world.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,20 @@ impl<'w> WorldAccessGuard<'w> {
550550
/// Call a function on a type which can be proxied, first by unproxying the input with world access,
551551
/// then calling the function and finally proxying the output with the allocator.
552552
pub fn proxy_call<'i, O: Proxy, T: Unproxy, F: Fn(T::Output<'_>) -> O::Input<'i>>(
553+
&self,
554+
proxied_input: T,
555+
f: F,
556+
) -> ScriptResult<O> {
557+
self.try_proxy_call(proxied_input, |o| Ok::<_, ScriptError>(f(o)))
558+
}
559+
560+
pub fn try_proxy_call<
561+
'i,
562+
O: Proxy,
563+
E: Into<Box<dyn std::error::Error + Send + Sync>>,
564+
T: Unproxy,
565+
F: Fn(T::Output<'_>) -> Result<O::Input<'i>, E>,
566+
>(
553567
&self,
554568
mut proxied_input: T,
555569
f: F,
@@ -567,7 +581,10 @@ impl<'w> WorldAccessGuard<'w> {
567581
}
568582
})?;
569583

570-
let out = f(unproxied_input);
584+
let out = f(unproxied_input).map_err(|e| {
585+
let e: Box<dyn std::error::Error + Send + Sync> = e.into();
586+
ScriptError::new_generic_error(e)
587+
})?;
571588

572589
let proxied_output = self.with_resource(|_, mut allocator: Mut<ReflectAllocator>| {
573590
O::proxy_with_allocator(out, &mut allocator)

crates/bevy_mod_scripting_core/src/error.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,11 @@ impl std::fmt::Display for ScriptError {
131131
if let Some(script) = &self.0.script {
132132
write!(
133133
f,
134-
"Encountered {} error in script `{}`: {}",
134+
"{} in script `{}`: {}",
135135
self.0.kind, script, self.0.reason
136136
)
137137
} else {
138-
write!(
139-
f,
140-
"Encountered {} error in a script: {}",
141-
self.0.kind, self.0.reason
142-
)
138+
write!(f, "{}: {}", self.0.kind, self.0.reason)
143139
}
144140
}
145141
}

crates/bevy_mod_scripting_derive/src/lib.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ fn proxy_wrap_function_def(
152152
};
153153

154154
let func_name = &f.sig.ident;
155-
let (mut original_arg_idents, _) = f
155+
let (mut original_arg_idents, mut original_arg_types) = f
156156
.sig
157157
.inputs
158158
.iter()
@@ -190,6 +190,7 @@ fn proxy_wrap_function_def(
190190

191191
let args_var_to_use = if get_world_callback_access_fn.is_some() {
192192
original_arg_idents.remove(0);
193+
original_arg_types.remove(0);
193194
args_tail_ident
194195
} else {
195196
args_ident
@@ -203,7 +204,7 @@ fn proxy_wrap_function_def(
203204
};
204205

205206
// wrap function body in our unwrapping and wrapping logic, ignore pre-existing body
206-
let mut fn_call = std::panic::catch_unwind(|| {
207+
let mut fn_call = //std::panic::catch_unwind(|| {
207208
match (
208209
&f.default,
209210
&attrs.as_trait,
@@ -212,9 +213,19 @@ fn proxy_wrap_function_def(
212213
(_, _, true) => quote_spanned!(span=>
213214
world.#func_name(#(#original_arg_idents),*)
214215
),
215-
(Some(body), _, _) => quote_spanned!(span=>
216-
(||{ #body })()
217-
),
216+
(Some(body), _, _) => {
217+
if attrs.no_proxy.is_present() {
218+
// in this case the entire thing is just this
219+
quote_spanned!(span=>
220+
{(|#ctxt_arg_ident, (#(#original_arg_idents),*) : (#(#original_arg_types),*)|{ #body })(#ctxt_alias, #args_var_to_use)}
221+
)
222+
} else {
223+
// in this case we are just using this to contain any ? calls and early returns
224+
quote_spanned!(span=>
225+
(|| { #body })()
226+
)
227+
}
228+
},
218229
(_, None, _) => quote_spanned!(span=>
219230
#target_type::#func_name(#(#original_arg_idents),*)
220231
),
@@ -224,9 +235,9 @@ fn proxy_wrap_function_def(
224235
<#target_type as #trait_path>::#func_name(#(#original_arg_idents),*)
225236
)
226237
}
227-
}
228-
})
229-
.unwrap(); // todo: handle the error nicer
238+
};
239+
//})
240+
// .unwrap(); // todo: handle the error nicer
230241

231242
if f.sig.unsafety.is_some() {
232243
fn_call = quote_spanned!(span=>
@@ -236,9 +247,9 @@ fn proxy_wrap_function_def(
236247

237248
if attrs.no_proxy.is_present() {
238249
f.default = Some(parse_quote_spanned! {span=>
239-
{
240-
#fn_call
241-
}
250+
251+
#fn_call
252+
242253
});
243254
} else {
244255
let world = if let Some(world_getter_fn_path) = get_world_callback_access_fn {
@@ -254,11 +265,17 @@ fn proxy_wrap_function_def(
254265
)
255266
};
256267

268+
let proxy_call_name: Ident = if attrs.fallible.is_present() {
269+
format_ident!("try_proxy_call", span = span)
270+
} else {
271+
format_ident!("proxy_call", span = span)
272+
};
273+
257274
f.default = Some(parse_quote_spanned! {span=>
258275
{
259276
#args_split
260277
#world
261-
let out: #out_type = world.proxy_call(#args_var_to_use, |(#(#original_arg_idents),*)| {
278+
let out: #out_type = world.#proxy_call_name(#args_var_to_use, |(#(#original_arg_idents),*)| {
262279
#fn_call
263280
}).map_err(|e| #mlua::Error::external(e))?;
264281
Ok(out)
@@ -315,6 +332,9 @@ struct FunctionAttrs {
315332
/// i.e. will remove that argument from the function signature and use it's name as the context alias
316333
pub with_context: Flag,
317334

335+
/// if true will treat output as a fallible result
336+
pub fallible: Flag,
337+
318338
/// Skips the unproxying & proxying call, useful for functions that don't need to access the world
319339
pub no_proxy: Flag,
320340
}
@@ -377,7 +397,7 @@ pub fn impl_lua_proxy(input: TokenStream) -> TokenStream {
377397
// extract composites first
378398
let mut composites: HashMap<String, Vec<(TraitItemFn, FunctionAttrs)>> = HashMap::new();
379399
meta.functions.0.retain(|f| {
380-
let attrs = FunctionAttrs::from_attributes(&f.attrs).unwrap();
400+
let attrs = FunctionAttrs::from_attributes(&f.attrs).expect("Function attributes must be valid");
381401
if let Some(composite_id) = &attrs.composite {
382402
composites
383403
.entry(composite_id.to_owned())
@@ -423,7 +443,7 @@ pub fn impl_lua_proxy(input: TokenStream) -> TokenStream {
423443
.collect::<Vec<_>>();
424444

425445
let closure_args_types = closures.iter().map(|closure| {
426-
let last = closure.inputs.last().unwrap();
446+
let last = closure.inputs.last().expect("Closure must have at least one argument");
427447
if let syn::Pat::Type(pat_type) = last {
428448
&pat_type.ty
429449
} else {
@@ -448,7 +468,7 @@ pub fn impl_lua_proxy(input: TokenStream) -> TokenStream {
448468
});
449469

450470
let add_function_stmts = meta.functions.0.into_iter().filter_map(|mut f| {
451-
let attrs = FunctionAttrs::from_attributes(&f.attrs).unwrap();
471+
let attrs = FunctionAttrs::from_attributes(&f.attrs).expect("Function attributes must be valid");
452472

453473
if attrs.skip.is_present() {
454474
return None;

crates/languages/bevy_mod_scripting_lua/src/bindings/providers/bevy_core.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,24 @@ use crate::{
2121
bms_lua_path = "crate",
2222
functions[r#"
2323
24+
#[lua(as_trait = "std::clone::Clone")]
25+
fn clone(
26+
_self: LuaReflectRefProxy<bevy::core::prelude::Name>,
27+
) -> LuaReflectValProxy<bevy::core::prelude::Name>;
28+
29+
"#,
30+
r#"
31+
2432
#[lua(
2533
as_trait = "std::cmp::PartialEq::<bevy::core::prelude::Name>",
2634
composite = "eq",
35+
metamethod = "Eq",
2736
)]
2837
fn eq(
2938
_self: LuaReflectRefProxy<bevy::core::prelude::Name>,
3039
other: LuaReflectRefProxy<bevy::core::prelude::Name>,
3140
) -> bool;
3241
33-
"#,
34-
r#"
35-
36-
#[lua(as_trait = "std::clone::Clone")]
37-
fn clone(
38-
_self: LuaReflectRefProxy<bevy::core::prelude::Name>,
39-
) -> LuaReflectValProxy<bevy::core::prelude::Name>;
40-
4142
"#,
4243
r#"
4344
#[lua(metamethod="ToString")]

0 commit comments

Comments
 (0)