Skip to content

Commit 0f46de6

Browse files
committed
make overloading work for subtraction
1 parent 4f20f12 commit 0f46de6

File tree

4 files changed

+105
-9
lines changed

4 files changed

+105
-9
lines changed

crates/bevy_mod_scripting_core/src/bindings/function/script_function.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ impl DynamicScriptFunction {
139139
pub fn name(&self) -> &Cow<'static, str> {
140140
&self.name
141141
}
142+
143+
pub fn with_name<N: Into<Cow<'static, str>>>(self, name: N) -> Self {
144+
Self {
145+
name: name.into(),
146+
func: self.func,
147+
}
148+
}
142149
}
143150

144151
impl std::fmt::Debug for DynamicScriptFunction {
@@ -201,7 +208,7 @@ impl ScriptFunctionRegistry {
201208
let name = name.into().clone();
202209

203210
if !self.contains(&name) {
204-
let func = func.into_dynamic_script_function();
211+
let func = func.into_dynamic_script_function().with_name(name.clone());
205212
self.functions.insert(name, func);
206213
return;
207214
}

crates/bevy_mod_scripting_functions/src/namespaced_register.rs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use std::{any::TypeId, borrow::Cow, marker::PhantomData};
22

33
use bevy::{
4-
prelude::{AppFunctionRegistry, IntoFunction, World},
4+
prelude::{AppFunctionRegistry, AppTypeRegistry, IntoFunction, World},
55
reflect::func::{DynamicFunction, FunctionRegistrationError, FunctionRegistry},
66
};
77
use bevy_mod_scripting_core::bindings::function::script_function::{
8-
AppScriptFunctionRegistry, DynamicScriptFunction, ScriptFunction, ScriptFunctionRegistry,
8+
AppScriptFunctionRegistry, DynamicScriptFunction, GetFunctionTypeDependencies, ScriptFunction,
9+
ScriptFunctionRegistry,
910
};
1011

1112
pub trait RegisterNamespacedFunction {
@@ -17,6 +18,13 @@ pub trait RegisterNamespacedFunction {
1718
}
1819

1920
pub trait GetNamespacedFunction {
21+
fn iter_overloads_namespaced<N>(
22+
&self,
23+
name: N,
24+
namespace: Namespace,
25+
) -> impl Iterator<Item = &DynamicScriptFunction>
26+
where
27+
N: Into<Cow<'static, str>>;
2028
fn get_namespaced_function<N>(
2129
&self,
2230
name: N,
@@ -78,6 +86,19 @@ impl RegisterNamespacedFunction for ScriptFunctionRegistry {
7886
}
7987

8088
impl GetNamespacedFunction for ScriptFunctionRegistry {
89+
fn iter_overloads_namespaced<N>(
90+
&self,
91+
name: N,
92+
namespace: Namespace,
93+
) -> impl Iterator<Item = &DynamicScriptFunction>
94+
where
95+
N: Into<Cow<'static, str>>,
96+
{
97+
let cow: Cow<'static, str> = name.into();
98+
let function_name = namespace.function_name(cow);
99+
self.iter_overloads(function_name)
100+
}
101+
81102
fn get_namespaced_function<N>(
82103
&self,
83104
name: N,
@@ -117,14 +138,21 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
117138
pub fn register<N, F, M>(&mut self, name: N, function: F) -> &mut Self
118139
where
119140
N: Into<Cow<'static, str>>,
120-
F: ScriptFunction<'static, M>,
141+
F: ScriptFunction<'static, M> + GetFunctionTypeDependencies<M>,
121142
{
122143
{
123-
let mut registry = self
124-
.world
125-
.get_resource_or_init::<AppScriptFunctionRegistry>();
126-
let mut registry = registry.write();
127-
registry.register_namespaced_function::<S, _, F, M>(name, function);
144+
{
145+
let mut registry = self
146+
.world
147+
.get_resource_or_init::<AppScriptFunctionRegistry>();
148+
let mut registry = registry.write();
149+
registry.register_namespaced_function::<S, _, F, M>(name, function);
150+
}
151+
{
152+
let mut type_registry = self.world.get_resource_or_init::<AppTypeRegistry>();
153+
let mut type_registry = type_registry.write();
154+
F::register_type_dependencies(&mut type_registry);
155+
}
128156
}
129157
self
130158
}

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ fn lookup_dynamic_function_typed<T: 'static + ?Sized>(
113113
lookup_dynamic_function(lua, key, type_id)
114114
}
115115

116+
fn iter_dynamic_function_overloads(
117+
lua: &Lua,
118+
key: &str,
119+
type_id: TypeId,
120+
) -> impl Iterator<Item = DynamicScriptFunction> {
121+
let registry = lua
122+
.get_world()
123+
.with_resource(|registry: &AppScriptFunctionRegistry| registry.clone());
124+
let registry = registry.read();
125+
126+
registry
127+
.iter_overloads_namespaced(key.to_string(), Namespace::OnType(type_id))
128+
.cloned()
129+
.collect::<Vec<_>>()
130+
.into_iter()
131+
}
132+
116133
impl UserData for LuaReflectReference {
117134
fn add_methods<T: UserDataMethods<Self>>(m: &mut T) {
118135
m.add_meta_function(
@@ -167,6 +184,37 @@ impl UserData for LuaReflectReference {
167184
},
168185
);
169186

187+
m.add_meta_function(
188+
MetaMethod::Sub,
189+
|lua, (self_, other): (LuaReflectReference, LuaScriptValue)| {
190+
let world = lua.get_world();
191+
let self_: ReflectReference = self_.into();
192+
let other: ScriptValue = other.into();
193+
194+
let target_type_id = self_.tail_type_id(world.clone())?.or_fake_id();
195+
196+
let overloads = iter_dynamic_function_overloads(lua, "sub", target_type_id);
197+
let mut last_error = None;
198+
let call_args = vec![ScriptValue::Reference(self_), other];
199+
for overload in overloads {
200+
match overload.call_script_function(
201+
call_args.clone(),
202+
world.clone(),
203+
lua_caller_context(),
204+
) {
205+
Ok(out) => return LuaScriptValue::from(out).into_lua(lua),
206+
Err(e) => last_error = Some(e),
207+
}
208+
}
209+
210+
Err(last_error
211+
.unwrap_or_else(|| {
212+
InteropError::missing_function(target_type_id, "sub".to_string()).into()
213+
})
214+
.into())
215+
},
216+
);
217+
170218
// #[cfg(any(
171219
// feature = "lua54",
172220
// feature = "lua53",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
local a = Vec3.new(1.0, 2.0, 3.0)
4+
local b = Vec3.new(4.0, 5.0, 6.0)
5+
6+
7+
assert((a - 1).x == 0.0, "Subtraction did not work")
8+
assert((a - 1).y == 1.0, "Subtraction did not work")
9+
assert((a - 1).z == 2.0, "Subtraction did not work")
10+
11+
assert((a - b).x == -3.0, "Subtraction did not work")
12+
assert((a - b).y == -3.0, "Subtraction did not work")
13+
assert((a - b).z == -3.0, "Subtraction did not work")

0 commit comments

Comments
 (0)