Skip to content

Commit 623b64d

Browse files
committed
re-design the type dependency trait better
1 parent f62f4ee commit 623b64d

File tree

5 files changed

+187
-115
lines changed

5 files changed

+187
-115
lines changed

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use std::{borrow::Cow, collections::HashMap, ffi::OsString, path::PathBuf};
44
use bevy::reflect::Reflect;
55

6-
use crate::{bindings::{ReflectReference, ScriptValue, WorldGuard}, error::InteropError, private::self_type_dependency_only};
7-
use super::{DynamicScriptFunction, DynamicScriptFunctionMut, Val};
6+
use crate::{bindings::{ReflectReference, ScriptValue, WorldGuard}, error::InteropError};
7+
use super::{DynamicScriptFunction, DynamicScriptFunctionMut, Union, Val};
88

99
/// Converts a value into a [`ScriptValue`].
1010
pub trait IntoScript {
@@ -26,14 +26,13 @@ impl IntoScript for ScriptValue {
2626
}
2727
}
2828

29-
self_type_dependency_only!(ScriptValue);
3029

3130
impl IntoScript for () {
3231
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
3332
Ok(ScriptValue::Unit)
3433
}
3534
}
36-
self_type_dependency_only!(());
35+
3736

3837
impl IntoScript for DynamicScriptFunctionMut {
3938
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
@@ -47,14 +46,12 @@ impl IntoScript for DynamicScriptFunction {
4746
}
4847
}
4948

50-
self_type_dependency_only!(DynamicScriptFunctionMut, DynamicScriptFunction);
5149

5250
impl IntoScript for bool {
5351
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
5452
Ok(ScriptValue::Bool(self))
5553
}
5654
}
57-
self_type_dependency_only!(bool);
5855

5956
macro_rules! impl_into_with_downcast {
6057
($variant:tt as $cast:ty [$($ty:ty),*]) => {
@@ -71,9 +68,7 @@ macro_rules! impl_into_with_downcast {
7168

7269
impl_into_with_downcast!(Integer as i64 [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize]);
7370
impl_into_with_downcast!(Float as f64 [f32, f64]);
74-
self_type_dependency_only!(
75-
i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize, f32, f64
76-
);
71+
7772

7873
macro_rules! impl_into_stringlike {
7974
($id:ident,[ $(($ty:ty => $conversion:expr)),*]) => {
@@ -99,15 +94,14 @@ impl_into_stringlike!(
9994
]
10095
);
10196

102-
self_type_dependency_only!(String, char, PathBuf, OsString);
10397

10498
impl IntoScript for &'static str {
10599
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
106100
Ok(ScriptValue::String(Cow::Borrowed(self)))
107101
}
108102
}
109103

110-
self_type_dependency_only!(&'static str);
104+
111105

112106
impl IntoScript for ReflectReference {
113107
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {

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

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@ mod test {
1717
use bevy::reflect::{FromReflect, GetTypeRegistration, Reflect, Typed};
1818
use bevy_mod_scripting_derive::script_bindings;
1919

20-
use crate::{
21-
bindings::{
20+
use crate::bindings::{
2221
function::{
2322
from::{Ref, Union, Val},
2423
namespace::IntoNamespace,
2524
script_function::AppScriptFunctionRegistry,
2625
}, script_value::ScriptValue
27-
},
28-
docgen::typed_through::TypedThrough,
29-
};
26+
};
3027

3128
use super::arg_meta::{ScriptArgument, ScriptReturn, TypedScriptArgument, TypedScriptReturn};
3229

@@ -139,7 +136,7 @@ mod test {
139136
fn test_union<T>()
140137
where
141138
T: TypedScriptArgument + TypedScriptReturn,
142-
T: GetTypeRegistration,
139+
T::Underlying: FromReflect + Typed + GetTypeRegistration,
143140
for<'a> T::This<'a>: Into<T>,
144141
{
145142
test_is_valid_arg_and_return::<Union<T, T>>();
@@ -148,17 +145,17 @@ mod test {
148145

149146
fn test_array<T, const N: usize>()
150147
where
151-
T: ScriptArgument + ScriptReturn,
152-
T: GetTypeRegistration + FromReflect + TypedThrough + Typed,
148+
T: TypedScriptArgument + TypedScriptReturn + 'static,
149+
T::Underlying: FromReflect + Typed + GetTypeRegistration,
153150
for<'a> T::This<'a>: Into<T>,
154151
{
155152
test_is_valid_arg_and_return::<[T; N]>();
156153
}
157154

158155
fn test_tuple<T>()
159156
where
160-
T: ScriptArgument + ScriptReturn,
161-
T: GetTypeRegistration + FromReflect + TypedThrough + Typed,
157+
T: TypedScriptArgument + TypedScriptReturn + 'static,
158+
T::Underlying: FromReflect + Typed + GetTypeRegistration,
162159
for<'a> T::This<'a>: Into<T>,
163160
{
164161
test_is_valid_arg_and_return::<()>();
@@ -169,26 +166,26 @@ mod test {
169166

170167
fn test_option<T>()
171168
where
172-
T: ScriptArgument + ScriptReturn,
173-
T: GetTypeRegistration + FromReflect + Typed + TypedThrough,
169+
T: TypedScriptArgument + TypedScriptReturn,
170+
T::Underlying: FromReflect + Typed + GetTypeRegistration,
174171
for<'a> T::This<'a>: Into<T>,
175172
{
176173
test_is_valid_arg_and_return::<Option<T>>();
177174
}
178175

179176
fn test_vec<T>()
180177
where
181-
T: ScriptArgument + ScriptReturn,
182-
T: GetTypeRegistration + FromReflect + Typed + TypedThrough,
178+
T: TypedScriptArgument + TypedScriptReturn + 'static,
179+
T::Underlying: FromReflect + Typed + GetTypeRegistration,
183180
for<'a> T::This<'a>: Into<T>,
184181
{
185182
test_is_valid_arg_and_return::<Vec<T>>();
186183
}
187184

188185
fn test_hashmap<V>()
189186
where
190-
V: ScriptArgument + ScriptReturn,
191-
V: GetTypeRegistration + FromReflect + Typed + TypedThrough,
187+
V: TypedScriptArgument + TypedScriptReturn + 'static,
188+
V::Underlying: FromReflect + Typed + GetTypeRegistration + Eq,
192189
for<'a> V::This<'a>: Into<V>,
193190
{
194191
test_is_valid_arg_and_return::<std::collections::HashMap<String, V>>();

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

Lines changed: 122 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
//! This module contains the [`GetTypeDependencies`] trait and its implementations for various types.
22
33
use super::{
4-
from::{Mut, Ref, Union, Val},
5-
script_function::FunctionCallContext,
4+
from::{Union, Val}, script_function::FunctionCallContext, DynamicScriptFunction, DynamicScriptFunctionMut, Mut, Ref
65
};
7-
use crate::{
8-
bindings::{ReflectReference, WorldGuard},
9-
error::InteropError, private::{no_type_dependencies, self_type_dependency_only},
10-
};
11-
use bevy::reflect::{FromReflect, GetTypeRegistration, TypeRegistration, TypeRegistry, Typed};
12-
use bevy_mod_scripting_derive::{impl_get_type_dependencies, GetTypeDependencies};
13-
use std::{collections::HashMap, hash::Hash};
6+
use crate::{bindings::{ReflectReference, ScriptValue}, error::InteropError};
7+
use bevy::reflect::{FromReflect, GetTypeRegistration, TypeRegistry, Typed};
8+
use bevy_mod_scripting_derive::impl_get_type_dependencies;
9+
use std::{collections::HashMap, ffi::OsString, hash::Hash, path::PathBuf};
1410

1511
/// Functionally identical to [`GetTypeRegistration`] but without the 'static bound
1612
pub trait GetTypeDependencies {
@@ -23,90 +19,153 @@ pub trait GetTypeDependencies {
2319
}
2420

2521

26-
macro_rules! register_tuple_dependencies {
27-
($($ty:ident),*) => {
28-
impl<$($ty: GetTypeRegistration + Typed),*> GetTypeDependencies for ($($ty,)*) {
29-
fn register_type_dependencies(registry: &mut TypeRegistry) {
30-
$(
31-
registry.register::<$ty>();
32-
)*
33-
}
34-
}
22+
macro_rules! impl_get_type_dependencies_primitives {
23+
($($ty:ty),*) => {
24+
$(
25+
impl_get_type_dependencies!(
26+
#[derive(GetTypeDependencies)]
27+
#[get_type_dependencies(bms_core_path="crate")]
28+
struct $ty {}
29+
);
30+
)*
3531
};
3632
}
3733

34+
impl_get_type_dependencies_primitives!(
35+
String, char, PathBuf, OsString,
36+
i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isize, f32, f64, bool,
37+
DynamicScriptFunctionMut, DynamicScriptFunction,
38+
ScriptValue, InteropError
39+
);
3840

39-
impl GetTypeDependencies for InteropError {
40-
type Underlying = Self;
41+
impl GetTypeDependencies for &'static str {
42+
type Underlying = &'static str;
43+
fn register_type_dependencies(registry: &mut TypeRegistry) {
44+
registry.register::<&'static str>();
45+
}
46+
}
4147

48+
impl GetTypeDependencies for () {
49+
type Underlying = ();
4250
fn register_type_dependencies(registry: &mut TypeRegistry) {
43-
todo!()
51+
registry.register::<()>();
4452
}
4553
}
4654

55+
impl_get_type_dependencies!(
56+
#[derive(GetTypeDependencies)]
57+
#[get_type_dependencies(bms_core_path="crate")]
58+
struct HashMap<K,V> where
59+
K::Underlying: FromReflect + Eq + Hash + Typed,
60+
V::Underlying: FromReflect + Typed,
61+
{}
62+
);
4763

64+
impl_get_type_dependencies!(
65+
#[derive(GetTypeDependencies)]
66+
#[get_type_dependencies(bms_core_path="crate")]
67+
struct Result<T, E> where
68+
T::Underlying: FromReflect + Typed,
69+
E::Underlying: FromReflect + Typed,
70+
{}
71+
);
4872

4973
impl_get_type_dependencies!(
5074
#[derive(GetTypeDependencies)]
51-
#[get_type_dependencies(bms_core_path=crate)]
52-
struct HashMap<K,V> {
53-
54-
}
75+
#[get_type_dependencies(bms_core_path="crate")]
76+
struct Option<T> where
77+
T::Underlying: FromReflect + Typed,
78+
{}
5579
);
5680

81+
impl_get_type_dependencies!(
82+
#[derive(GetTypeDependencies)]
83+
#[get_type_dependencies(bms_core_path="crate")]
84+
struct Vec<T> where
85+
T::Underlying: FromReflect + Typed,
86+
{}
87+
);
5788

58-
no_type_dependencies!(InteropError);
59-
no_type_dependencies!(WorldGuard<'static>);
60-
self_type_dependency_only!(FunctionCallContext, ReflectReference);
6189

62-
recursive_type_dependencies!(
63-
(Val<T> where T: GetTypeRegistration),
64-
(Ref<'_, T> where T: GetTypeRegistration),
65-
(Mut<'_, T> where T: GetTypeRegistration),
66-
// (Result<T, InteropError> where T: GetTypeRegistration),
67-
([T; N] where T: GetTypeRegistration;Typed,, const N: usize => with Self),
68-
// (Option<T> where T: GetTypeRegistration;FromReflect;Typed => with Self),
69-
(Vec<T> where T: GetTypeRegistration;FromReflect;Typed => with Self)
70-
// (HashMap<K,V> where K: GetTypeRegistration;FromReflect;Typed;Hash;Eq, V: GetTypeRegistration;FromReflect;Typed => with Self)
90+
impl_get_type_dependencies!(
91+
#[derive(GetTypeDependencies)]
92+
#[get_type_dependencies(bms_core_path="crate", underlying="Result<T1::Underlying,T2::Underlying>")]
93+
struct Union<T1, T2> where
94+
T1::Underlying: FromReflect + Typed,
95+
T2::Underlying: FromReflect + Typed,
96+
{}
7197
);
7298

99+
// the below 3 types are "leaf" types, i.e. they cannot contain nested type dependencies
100+
impl <T: GetTypeRegistration> GetTypeDependencies for Val<T> {
101+
type Underlying = T;
73102

74-
impl <K> GetTypeDependencies for Option<K>
75-
where
76-
K: GetTypeDependencies
77-
{
78103
fn register_type_dependencies(registry: &mut TypeRegistry) {
79-
K::register_type_dependencies(registry);
104+
registry.register::<T>();
80105
}
81106
}
82107

83-
impl <Uk, Uv, K, V> GetTypeDependencies<HashMap<Uk,Uv>> for HashMap<K, V>
84-
where
85-
K: GetTypeDependencies<Uk>,
86-
V: GetTypeDependencies<Uv>,
87-
Uk: GetTypeRegistration + FromReflect + Eq + Hash + Typed,
88-
Uv: GetTypeRegistration + FromReflect + Eq + Hash + Typed,
89-
{
108+
impl <T: GetTypeRegistration> GetTypeDependencies for Ref<'_, T> {
109+
type Underlying = T;
110+
90111
fn register_type_dependencies(registry: &mut TypeRegistry) {
91-
K::register_type_dependencies(registry);
92-
V::register_type_dependencies(registry);
93-
TypeRegistration::of::<HashMap<Uk,Uv>>();
112+
registry.register::<T>();
94113
}
95114
}
96115

97-
impl <T: GetTypeDependencies> GetTypeDependencies for Result<T, InteropError> {
116+
impl <T: GetTypeRegistration> GetTypeDependencies for Mut<'_, T> {
117+
type Underlying = T;
118+
98119
fn register_type_dependencies(registry: &mut TypeRegistry) {
99-
T::register_type_dependencies(registry);
120+
registry.register::<T>();
100121
}
101122
}
102123

103-
impl<T1: GetTypeDependencies, T2: GetTypeDependencies> GetTypeDependencies for Union<T1, T2> {
124+
impl_get_type_dependencies!(
125+
#[derive(GetTypeDependencies)]
126+
#[get_type_dependencies(bms_core_path="crate")]
127+
struct ReflectReference where
128+
{}
129+
);
130+
131+
impl_get_type_dependencies!(
132+
#[derive(GetTypeDependencies)]
133+
#[get_type_dependencies(bms_core_path="crate")]
134+
struct FunctionCallContext where
135+
{}
136+
);
137+
138+
139+
impl <T, const N: usize> GetTypeDependencies for [T; N] where
140+
T: GetTypeDependencies,
141+
T::Underlying: FromReflect + Typed,
142+
{
143+
type Underlying = [T::Underlying; N];
104144
fn register_type_dependencies(registry: &mut TypeRegistry) {
105-
T1::register_type_dependencies(registry);
106-
T2::register_type_dependencies(registry);
145+
T::register_type_dependencies(registry);
107146
}
108147
}
109148

149+
macro_rules! register_tuple_dependencies {
150+
($($param:ident),*) => {
151+
impl <$($param),*> $crate::bindings::GetTypeDependencies for ($($param,)*) where
152+
$(
153+
$param: GetTypeDependencies,
154+
<$param>::Underlying: FromReflect + Typed + GetTypeRegistration,
155+
)*
156+
{
157+
type Underlying = ($(<$param as GetTypeDependencies>::Underlying,)*);
158+
fn register_type_dependencies(registry: &mut TypeRegistry) {
159+
$(
160+
registry.register::<<$param>::Underlying>();
161+
<$param>::register_type_dependencies(registry);
162+
)*
163+
}
164+
}
165+
};
166+
}
167+
168+
110169
bevy::utils::all_tuples!(register_tuple_dependencies, 1, 14, T);
111170

112171
/// A trait collecting type dependency information for a whole function. Used to register everything used by a function with the type registry
@@ -117,8 +176,12 @@ pub trait GetFunctionTypeDependencies<Marker> {
117176

118177
macro_rules! impl_script_function_type_dependencies{
119178
($( $param:ident ),* ) => {
120-
impl<F, $( $param: GetTypeDependencies ,)* O: GetTypeDependencies> GetFunctionTypeDependencies<fn($($param),*) -> O> for F
121-
where F: Fn( $( $param ),* ) -> O
179+
impl<F, $( $param,)* O > GetFunctionTypeDependencies<fn($($param),*) -> O> for F where
180+
O: GetTypeDependencies,
181+
F: Fn( $( $param ),* ) -> O,
182+
$(
183+
$param: GetTypeDependencies,
184+
)*
122185
{
123186
fn register_type_dependencies(registry: &mut TypeRegistry) {
124187
$(

0 commit comments

Comments
 (0)