Skip to content

Commit 5de0fec

Browse files
properly register the top level types too
1 parent 06c6d00 commit 5de0fec

File tree

8 files changed

+50
-41
lines changed

8 files changed

+50
-41
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ impl CallScriptFunction for DynamicFunction<'_> {
6868
.map_err(InteropError::function_call_error)?;
6969

7070
match return_val.try_into_or_boxed::<ScriptValue>() {
71-
Ok(ScriptValue::Error(e)) => {
72-
Err(InteropError::function_interop_error(self.info(), None, e))
73-
}
71+
Ok(ScriptValue::Error(e)) => Err(InteropError::function_interop_error(self.info(), e)),
7472
Ok(v) => Ok(v),
7573
Err(b) => {
7674
let allocator = world.allocator();

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ use bevy::{
1111
prelude::{AppFunctionRegistry, IntoFunction, World},
1212
reflect::{
1313
func::{DynamicFunction, FunctionInfo},
14-
GetTypeRegistration, PartialReflect, TypeRegistration, TypeRegistry,
14+
FromReflect, GetTypeRegistration, PartialReflect, TypeRegistration, TypeRegistry, Typed,
1515
},
1616
};
1717
use std::collections::HashMap;
1818
use std::sync::Arc;
1919

2020
#[diagnostic::on_unimplemented(
21-
message = "Only functions with all arguments impplementing FromScript and return values supporting IntoScript are supported. use assert_impls_into_script!(MyArg) and assert_impls_from_script!(MyReturnType) to verify yours do.",
21+
message = "Only functions with all arguments impplementing FromScript and return values supporting IntoScript are supported. Registering functions also requires they implement GetInnerTypeDependencies",
2222
note = "If you're trying to return a non-primitive type, you might need to use Val<T> Ref<T> or Mut<T> wrappers"
2323
)]
2424
pub trait ScriptFunction<'env, Marker> {
@@ -54,13 +54,16 @@ macro_rules! self_type_dependency_only {
5454
}
5555

5656
macro_rules! recursive_type_dependencies {
57-
($(($path:path where $($bound:ident : $bound_val:path),*)),*) => {
57+
($( ($path:path where $($bound:ident : $($bound_val:path);*),* $(=> with $self_:ident)?) ),* ) => {
5858
$(
59-
impl<$($bound : $bound_val),*> GetInnerTypeDependencies for $path {
59+
impl<$($bound : $($bound_val +)*),*> GetInnerTypeDependencies for $path {
6060
fn register_type_dependencies(registry: &mut TypeRegistry) {
6161
$(
6262
registry.register::<$bound>();
6363
)*
64+
$(
65+
registry.register::<$self_>();
66+
)?
6467
}
6568
}
6669
)*
@@ -75,8 +78,8 @@ recursive_type_dependencies!(
7578
(Ref<'_, T> where T: GetTypeRegistration),
7679
(Mut<'_, T> where T: GetTypeRegistration),
7780
(Result<T, InteropError> where T: GetTypeRegistration),
78-
(Option<T> where T: GetTypeRegistration),
79-
(Vec<T> where T: GetTypeRegistration)
81+
(Option<T> where T: GetTypeRegistration;FromReflect;Typed => with Self),
82+
(Vec<T> where T: GetTypeRegistration;FromReflect;Typed => with Self)
8083
);
8184

8285
recursive_type_dependencies!(
@@ -129,13 +132,19 @@ macro_rules! impl_script_function {
129132
$( let $callback = world.clone(); )?
130133
let world = world.try_read()?;
131134
// TODO: snapshot the accesses and release them after
132-
$( let $param = <$param>::from_script($param, world.clone())?; )*
135+
#[allow(unused_mut,unused_variables)]
136+
let mut current_arg = 0;
137+
$(
138+
current_arg += 1;
139+
let $param = <$param>::from_script($param, world.clone())
140+
.map_err(|e| InteropError::function_arg_conversion_error(current_arg.to_string(), e))?;
141+
)*
133142
let out = self( $( $callback, )? $( $param.into(), )* );
134143
$(
135144
let $out = out?;
136145
let out = $out;
137146
)?
138-
out.into_script(world.clone())
147+
out.into_script(world.clone()).map_err(|e| InteropError::function_arg_conversion_error("return value".to_owned(), e))
139148
})();
140149
let script_value: ScriptValue = res.into();
141150
script_value

crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::reflection_extensions::TypeIdExtensions;
1+
use crate::reflection_extensions::{FakeType, TypeIdExtensions};
22

33
use super::{
44
script_value::ScriptValue, ReflectBase, ReflectBaseType, ReflectReference, WorldGuard,
@@ -364,6 +364,10 @@ impl DisplayWithWorld for ReflectBaseType {
364364

365365
impl DisplayWithWorld for TypeId {
366366
fn display_with_world(&self, world: WorldGuard) -> String {
367+
if *self == TypeId::of::<FakeType>() {
368+
return "Dynamic Type".to_owned();
369+
}
370+
367371
let type_registry = world.type_registry();
368372
let type_registry = type_registry.read();
369373

crates/bevy_mod_scripting_core/src/error.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -345,24 +345,13 @@ impl InteropError {
345345
/// Thrown when an error happens in a function call. The inner error provides details on the error.
346346
pub fn function_interop_error(
347347
function_info: &FunctionInfo,
348-
argument_info: Option<&ArgInfo>,
349348
error: InteropError,
350349
) -> Self {
351350
Self(Arc::new(InteropErrorInner::FunctionInteropError {
352351
function_name: function_info
353352
.name()
354353
.map(|s| s.to_string())
355354
.unwrap_or("<unnamed function>".to_owned()),
356-
argument: argument_info
357-
.map(|a| {
358-
format!(
359-
"{}({}) {}",
360-
a.index(),
361-
a.ownership(),
362-
a.name().unwrap_or("<no_name>")
363-
)
364-
})
365-
.unwrap_or("None".to_owned()),
366355
error,
367356
}))
368357
}
@@ -374,6 +363,13 @@ impl InteropError {
374363
Self(Arc::new(InteropErrorInner::FunctionCallError { inner }))
375364
}
376365

366+
pub fn function_arg_conversion_error(argument: String, error: InteropError) -> Self {
367+
Self(Arc::new(InteropErrorInner::FunctionArgConversionError {
368+
argument,
369+
error
370+
}))
371+
}
372+
377373
pub fn external_error(error: Box<dyn std::error::Error + Send + Sync>) -> Self {
378374
Self(Arc::new(InteropErrorInner::OtherError { error }))
379375
}
@@ -464,9 +460,12 @@ pub enum InteropErrorInner {
464460
},
465461
FunctionInteropError {
466462
function_name: String,
467-
argument: String,
468463
error: InteropError,
469464
},
465+
FunctionArgConversionError {
466+
argument: String,
467+
error: InteropError
468+
},
470469
OtherError {
471470
error: Box<dyn std::error::Error + Send + Sync>,
472471
},
@@ -590,10 +589,16 @@ impl DisplayWithWorld for InteropErrorInner {
590589
InteropErrorInner::MissingWorld => {
591590
"Missing world. The world was not initialized in the script context.".to_owned()
592591
},
593-
InteropErrorInner::FunctionInteropError { function_name, argument, error } => {
592+
InteropErrorInner::FunctionInteropError { function_name, error } => {
594593
format!(
595-
"Error in function: {} argument: {} error: {}",
594+
"Error in function {}: {}",
596595
function_name,
596+
error.display_with_world(world)
597+
)
598+
},
599+
InteropErrorInner::FunctionArgConversionError { argument, error } => {
600+
format!(
601+
"Error converting argument {}: {}",
597602
argument,
598603
error.display_with_world(world)
599604
)

crates/bevy_mod_scripting_core/src/reflection_extensions.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ pub trait TypeIdExtensions {
9898
fn or_fake_id(&self) -> TypeId;
9999
}
100100

101+
pub(crate) struct FakeType;
102+
101103
impl TypeIdExtensions for Option<TypeId> {
102104
fn or_fake_id(&self) -> TypeId {
103-
struct UknownType;
104105
match self {
105106
Some(t) => *t,
106-
None => TypeId::of::<UknownType>(),
107+
None => TypeId::of::<FakeType>(),
107108
}
108109
}
109110
}

crates/bevy_mod_scripting_functions/src/core.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ impl<S: 'static> RegisterScriptFunction for NamespaceBuilder<'_, S> {
4242
F: ScriptFunction<'static, M> + GetFunctionTypeDependencies<M>,
4343
{
4444
{
45-
let registry = self
46-
.world
47-
.get_resource_mut::<AppTypeRegistry>()
48-
.expect("AppTypeRegistry resource not found");
45+
let registry = self.world.get_resource_or_init::<AppTypeRegistry>();
4946
let mut registry = registry.write();
5047
F::register_type_dependencies(&mut registry);
5148
}

crates/bevy_mod_scripting_functions/src/namespaced_register.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,7 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
155155
F: IntoFunction<'static, M> + 'static,
156156
{
157157
{
158-
let registry = self
159-
.world
160-
.get_resource_mut::<AppFunctionRegistry>()
161-
.expect("AppFunctionRegistry resource not found");
158+
let registry = self.world.get_resource_or_init::<AppFunctionRegistry>();
162159
let mut registry = registry.write();
163160
registry.register_namespaced_function::<S, _, F, M>(name, function)?;
164161
}
@@ -171,10 +168,8 @@ impl<'a, S: IntoNamespace> NamespaceBuilder<'a, S> {
171168
F: IntoFunction<'static, M> + 'static,
172169
{
173170
{
174-
let registry = self
175-
.world
176-
.get_resource_mut::<AppFunctionRegistry>()
177-
.expect("AppFunctionRegistry resource not found");
171+
let registry = self.world.get_resource_or_init::<AppFunctionRegistry>();
172+
178173
let mut registry = registry.write();
179174
registry.overwrite_namespaced_function::<S, _, F, M>(name, function);
180175
}

crates/languages/bevy_mod_scripting_lua/tests/data/query/query_returns_all_entities_matching.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ world:add_default_component(entity_c, component_with)
1313
world:add_default_component(entity_b, component_without)
1414

1515
local found_entities = {}
16-
for entity, comp in pairs(world:query(component_with):with(component_with):without(component_without):build()) do
16+
for entity, comp in pairs(world:query({component_with}):with(component_with):without(component_without):build()) do
1717
table.insert(found_entities, entity)
1818
end
1919

0 commit comments

Comments
 (0)