Skip to content

Commit 06c6d00

Browse files
work out function type dependency registration basics
1 parent cfa9a01 commit 06c6d00

File tree

6 files changed

+91
-30
lines changed

6 files changed

+91
-30
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
error::InteropError,
44
prelude::ScriptValue,
55
};
6-
use bevy::reflect::{FromReflect, GetTypeRegistration};
6+
use bevy::reflect::{FromReflect, GetTypeRegistration, Reflect};
77
use std::{
88
any::TypeId,
99
ffi::OsString,
@@ -139,6 +139,7 @@ impl FromScript for ReflectReference {
139139
///
140140
/// This can be used to retrieve a value out of a [`ScriptValue::Reference`] corresponding to the type `T`.
141141
/// You can also use this to return values from a script function to be allocated directly as a [`ScriptValue::Reference`].
142+
#[derive(Reflect)]
142143
pub struct Val<T>(pub T);
143144

144145
impl<T> Val<T> {

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
bindings::{ReflectReference, WorldGuard},
1111
error::InteropError,
1212
prelude::ScriptValue,
13+
self_type_dependency_only,
1314
};
1415

1516
use super::from::Val;
@@ -24,17 +25,22 @@ impl IntoScript for ScriptValue {
2425
}
2526
}
2627

28+
self_type_dependency_only!(ScriptValue);
29+
2730
impl IntoScript for () {
2831
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
2932
Ok(ScriptValue::Unit)
3033
}
3134
}
3235

36+
self_type_dependency_only!(());
37+
3338
impl IntoScript for bool {
34-
fn into_script(self, world: WorldGuard) -> Result<ScriptValue, InteropError> {
39+
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
3540
Ok(ScriptValue::Bool(self))
3641
}
3742
}
43+
self_type_dependency_only!(bool);
3844

3945
macro_rules! impl_into_with_downcast {
4046
($variant:tt as $cast:ty [$($ty:ty),*]) => {
@@ -51,6 +57,9 @@ macro_rules! impl_into_with_downcast {
5157

5258
impl_into_with_downcast!(Integer as i64 [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize]);
5359
impl_into_with_downcast!(Float as f64 [f32, f64]);
60+
self_type_dependency_only!(
61+
i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize, f32, f64
62+
);
5463

5564
macro_rules! impl_into_stringlike {
5665
($id:ident,[ $(($ty:ty => $conversion:expr)),*]) => {
@@ -76,12 +85,16 @@ impl_into_stringlike!(
7685
]
7786
);
7887

88+
self_type_dependency_only!(String, char, PathBuf, OsString);
89+
7990
impl IntoScript for &'static str {
8091
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
8192
Ok(ScriptValue::String(Cow::Borrowed(self)))
8293
}
8394
}
8495

96+
self_type_dependency_only!(&'static str);
97+
8598
impl IntoScript for ReflectReference {
8699
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
87100
Ok(ScriptValue::Reference(self))

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

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use bevy::{
1414
GetTypeRegistration, PartialReflect, TypeRegistration, TypeRegistry,
1515
},
1616
};
17+
use std::collections::HashMap;
1718
use std::sync::Arc;
1819

1920
#[diagnostic::on_unimplemented(
@@ -28,25 +29,59 @@ pub trait GetInnerTypeDependencies {
2829
fn register_type_dependencies(registry: &mut TypeRegistry);
2930
}
3031

31-
impl<T: GetTypeRegistration> GetInnerTypeDependencies for T {
32-
fn register_type_dependencies(registry: &mut TypeRegistry) {
33-
registry.register::<T>();
34-
}
32+
#[macro_export]
33+
macro_rules! no_type_dependencies {
34+
($($path:path),*) => {
35+
$(
36+
impl GetInnerTypeDependencies for $path {
37+
fn register_type_dependencies(_registry: &mut TypeRegistry) {}
38+
}
39+
)*
40+
};
41+
}
42+
43+
#[macro_export]
44+
macro_rules! self_type_dependency_only {
45+
($($path:ty),*) => {
46+
$(
47+
impl $crate::bindings::function::script_function::GetInnerTypeDependencies for $path {
48+
fn register_type_dependencies(registry: &mut bevy::reflect::TypeRegistry) {
49+
registry.register::<$path>();
50+
}
51+
}
52+
)*
53+
};
3554
}
3655

3756
macro_rules! recursive_type_dependencies {
38-
($(T: $path:path),*) => {
57+
($(($path:path where $($bound:ident : $bound_val:path),*)),*) => {
3958
$(
40-
impl<T: GetInnerTypeDependencies> GetInnerTypeDependencies for $path {
59+
impl<$($bound : $bound_val),*> GetInnerTypeDependencies for $path {
4160
fn register_type_dependencies(registry: &mut TypeRegistry) {
42-
T::register_type_dependencies(registry);
61+
$(
62+
registry.register::<$bound>();
63+
)*
4364
}
4465
}
4566
)*
4667
};
4768
}
4869

49-
recursive_type_dependencies!(T: Val<T>, T: Ref<'_, T>, T: Mut<'_, T>);
70+
no_type_dependencies!(ReflectReference, InteropError);
71+
self_type_dependency_only!(WorldCallbackAccess);
72+
73+
recursive_type_dependencies!(
74+
(Val<T> where T: GetTypeRegistration),
75+
(Ref<'_, T> where T: GetTypeRegistration),
76+
(Mut<'_, T> where T: GetTypeRegistration),
77+
(Result<T, InteropError> where T: GetTypeRegistration),
78+
(Option<T> where T: GetTypeRegistration),
79+
(Vec<T> where T: GetTypeRegistration)
80+
);
81+
82+
recursive_type_dependencies!(
83+
(HashMap<K,V> where K: GetTypeRegistration, V: GetTypeRegistration)
84+
);
5085

5186
pub trait GetFunctionTypeDependencies<Marker> {
5287
fn register_type_dependencies(registry: &mut TypeRegistry);

crates/bevy_mod_scripting_core/src/bindings/reference.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use bevy::{
2020
change_detection::MutUntyped, component::ComponentId, entity::Entity,
2121
world::unsafe_world_cell::UnsafeWorldCell,
2222
},
23-
prelude::{Component, Resource},
23+
prelude::{Component, ReflectDefault, Resource},
2424
ptr::Ptr,
2525
reflect::{
2626
func::{args::ArgInfo, ArgValue},
@@ -34,15 +34,29 @@ use std::{any::TypeId, fmt::Debug, sync::Arc};
3434
/// An accessor to a `dyn PartialReflect` struct, stores a base ID of the type and a reflection path
3535
/// safe to build but to reflect on the value inside you need to ensure aliasing rules are upheld
3636
#[derive(Debug, Clone, PartialEq, Eq, Reflect)]
37-
#[reflect(opaque)]
37+
#[reflect(Default)]
3838
pub struct ReflectReference {
39+
#[reflect(ignore)]
3940
pub base: ReflectBaseType,
4041
// TODO: experiment with Fixed capacity vec, boxed array etc, compromise between heap allocation and runtime cost
4142
// needs benchmarks first though
4243
/// The path from the top level type to the actual value we want to access
44+
#[reflect(ignore)]
4345
pub reflect_path: ParsedPath,
4446
}
4547

48+
impl Default for ReflectReference {
49+
fn default() -> Self {
50+
Self {
51+
base: ReflectBaseType {
52+
type_id: TypeId::of::<WorldCallbackAccess>(),
53+
base_id: ReflectBase::World,
54+
},
55+
reflect_path: ParsedPath(vec![]),
56+
}
57+
}
58+
}
59+
4660
/// Specifies where we should source the type id from when reflecting a ReflectReference
4761
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4862
pub enum TypeIdSource {

crates/bevy_mod_scripting_core/src/error.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,7 @@ impl From<InteropError> for mlua::Error {
183183
}
184184

185185
#[derive(Debug, Clone, PartialEq, Reflect)]
186-
#[reflect(opaque)]
187-
pub struct InteropError(Arc<InteropErrorInner>);
186+
pub struct InteropError(#[reflect(ignore)] Arc<InteropErrorInner>);
188187

189188
impl std::error::Error for InteropError {}
190189

@@ -609,3 +608,10 @@ impl DisplayWithWorld for InteropErrorInner {
609608
}
610609
}
611610
}
611+
612+
/// Purely for purposes of the automatic [`GetTypeRegistration`] impl.
613+
impl Default for InteropErrorInner {
614+
fn default() -> Self {
615+
InteropErrorInner::StaleWorldAccess
616+
}
617+
}

crates/bevy_mod_scripting_functions/src/core.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,16 @@ impl<S: 'static> RegisterScriptFunction for NamespaceBuilder<'_, S> {
5757

5858
impl Plugin for CoreFunctionsPlugin {
5959
fn build(&self, app: &mut App) {
60-
let function_registry = app
61-
.world_mut()
62-
.get_resource_or_init::<AppFunctionRegistry>();
60+
let world = app.world_mut();
61+
register_world_functions(world).expect("Failed to register world functions");
6362

64-
let mut function_registry = function_registry.write();
65-
66-
register_world_functions(&mut function_registry)
67-
.expect("Failed to register world functions");
68-
69-
register_reflect_reference_functions(&mut function_registry)
63+
register_reflect_reference_functions(world)
7064
.expect("Failed to register reflect reference functions");
7165

72-
register_script_type_registration_functions(&mut function_registry)
66+
register_script_type_registration_functions(world)
7367
.expect("Failed to register script type registration functions");
7468

75-
register_script_query_builder_functions(&mut function_registry)
69+
register_script_query_builder_functions(world)
7670
.expect("Failed to register script query builder functions");
7771
}
7872
}
@@ -189,9 +183,7 @@ fn register_world_functions(reg: &mut World) -> Result<(), FunctionRegistrationE
189183
Ok(())
190184
}
191185

192-
fn register_reflect_reference_functions(
193-
reg: &mut FunctionRegistry,
194-
) -> Result<(), FunctionRegistrationError> {
186+
fn register_reflect_reference_functions(reg: &mut World) -> Result<(), FunctionRegistrationError> {
195187
NamespaceBuilder::<ReflectReference>::new(reg)
196188
.overwrite_script_function(
197189
"display_ref",
@@ -285,7 +277,7 @@ fn register_reflect_reference_functions(
285277
}
286278

287279
fn register_script_type_registration_functions(
288-
registry: &mut FunctionRegistry,
280+
registry: &mut World,
289281
) -> Result<(), FunctionRegistrationError> {
290282
NamespaceBuilder::<ScriptTypeRegistration>::new(registry)
291283
.overwrite_script_function("type_name", |s: Ref<ScriptTypeRegistration>| s.type_name())
@@ -302,7 +294,7 @@ fn register_script_type_registration_functions(
302294
}
303295

304296
fn register_script_query_builder_functions(
305-
registry: &mut FunctionRegistry,
297+
registry: &mut World,
306298
) -> Result<(), FunctionRegistrationError> {
307299
NamespaceBuilder::<ScriptQueryBuilder>::new(registry)
308300
.overwrite_script_function(

0 commit comments

Comments
 (0)