Skip to content

Commit 98319a2

Browse files
committed
get bindings compiling, add more impls
1 parent f8f778c commit 98319a2

File tree

5 files changed

+81
-8
lines changed

5 files changed

+81
-8
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,28 @@ where
360360
}
361361
}
362362
}
363+
364+
impl<T: FromScript + 'static, const N: usize> FromScript for [T; N]
365+
where
366+
for<'w> T::This<'w>: Into<T>,
367+
{
368+
type This<'w> = Self;
369+
370+
fn from_script(value: ScriptValue, world: WorldGuard) -> Result<Self, InteropError> {
371+
match value {
372+
ScriptValue::List(list) if list.len() == N => {
373+
let converted_list = list
374+
.into_iter()
375+
.map(|item| T::from_script(item, world.clone()).map(Into::into))
376+
.collect::<Result<Vec<T>, _>>()?
377+
.try_into()
378+
.map_err(|list: Vec<T>| InteropError::length_mismatch(N, list.len()))?;
379+
Ok(converted_list)
380+
}
381+
_ => Err(InteropError::value_mismatch(
382+
std::any::TypeId::of::<[T; N]>(),
383+
value,
384+
)),
385+
}
386+
}
387+
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,32 @@ impl<T: IntoScript> IntoScript for Vec<T> {
132132
}
133133
}
134134

135+
impl<T: IntoScript, const N: usize> IntoScript for [T; N] {
136+
fn into_script(self, world: WorldGuard) -> Result<ScriptValue, InteropError> {
137+
let mut values = Vec::with_capacity(N);
138+
for val in self {
139+
values.push(val.into_script(world.clone())?);
140+
}
141+
Ok(ScriptValue::List(values))
142+
}
143+
}
144+
135145
impl IntoScript for InteropError {
136146
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
137147
Ok(ScriptValue::Error(self))
138148
}
139149
}
150+
151+
macro_rules! impl_into_script_tuple {
152+
($( $ty:ident ),* ) => {
153+
#[allow(non_snake_case)]
154+
impl<$($ty: IntoScript),*> IntoScript for ($($ty,)*) {
155+
fn into_script(self, world: WorldGuard) -> Result<ScriptValue, InteropError> {
156+
let ($($ty,)*) = self;
157+
Ok(ScriptValue::List(vec![$($ty.into_script(world.clone())?),*]))
158+
}
159+
}
160+
}
161+
}
162+
163+
bevy::utils::all_tuples!(impl_into_script_tuple, 1, 14, T);

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

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use bevy::{
1515
},
1616
};
1717
use std::collections::HashMap;
18+
use std::hash::Hash;
1819
use std::sync::Arc;
1920

2021
#[diagnostic::on_unimplemented(
@@ -25,6 +26,7 @@ pub trait ScriptFunction<'env, Marker> {
2526
fn into_dynamic_function(self) -> DynamicFunction<'static>;
2627
}
2728

29+
/// Functionally identical to [`GetTypeRegistration`] but without the 'static bound
2830
pub trait GetInnerTypeDependencies {
2931
fn register_type_dependencies(registry: &mut TypeRegistry);
3032
}
@@ -54,9 +56,9 @@ macro_rules! self_type_dependency_only {
5456
}
5557

5658
macro_rules! recursive_type_dependencies {
57-
($( ($path:path where $($bound:ident : $($bound_val:path);*),* $(=> with $self_:ident)?) ),* ) => {
59+
($( ($path:ty where $($bound:ident : $($bound_val:path);*),* $(,,const $const:ident : $const_ty:ty)? $(=> with $self_:ident)?) ),* ) => {
5860
$(
59-
impl<$($bound : $($bound_val +)*),*> GetInnerTypeDependencies for $path {
61+
impl<$($bound : $($bound_val +)*),* , $(const $const : $const_ty )?> GetInnerTypeDependencies for $path {
6062
fn register_type_dependencies(registry: &mut TypeRegistry) {
6163
$(
6264
registry.register::<$bound>();
@@ -70,6 +72,18 @@ macro_rules! recursive_type_dependencies {
7072
};
7173
}
7274

75+
macro_rules! register_tuple_dependencies {
76+
($($ty:ident),*) => {
77+
impl<$($ty: GetTypeRegistration + Typed),*> GetInnerTypeDependencies for ($($ty,)*) {
78+
fn register_type_dependencies(registry: &mut TypeRegistry) {
79+
$(
80+
registry.register::<$ty>();
81+
)*
82+
}
83+
}
84+
};
85+
}
86+
7387
no_type_dependencies!(ReflectReference, InteropError);
7488
self_type_dependency_only!(WorldCallbackAccess);
7589

@@ -78,14 +92,13 @@ recursive_type_dependencies!(
7892
(Ref<'_, T> where T: GetTypeRegistration),
7993
(Mut<'_, T> where T: GetTypeRegistration),
8094
(Result<T, InteropError> where T: GetTypeRegistration),
95+
([T; N] where T: GetTypeRegistration;Typed,, const N: usize => with Self),
8196
(Option<T> where T: GetTypeRegistration;FromReflect;Typed => with Self),
82-
(Vec<T> where T: GetTypeRegistration;FromReflect;Typed => with Self)
83-
);
84-
85-
recursive_type_dependencies!(
86-
(HashMap<K,V> where K: GetTypeRegistration, V: GetTypeRegistration)
97+
(Vec<T> where T: GetTypeRegistration;FromReflect;Typed => with Self),
98+
(HashMap<K,V> where K: GetTypeRegistration;FromReflect;Typed;Hash;Eq, V: GetTypeRegistration;FromReflect;Typed => with Self)
8799
);
88100

101+
bevy::utils::all_tuples!(register_tuple_dependencies, 1, 14, T);
89102
pub trait GetFunctionTypeDependencies<Marker> {
90103
fn register_type_dependencies(registry: &mut TypeRegistry);
91104
}

crates/bevy_mod_scripting_core/src/error.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,10 @@ impl InteropError {
369369
error
370370
}))
371371
}
372-
372+
pub fn length_mismatch(expected: usize, got: usize) -> Self {
373+
Self(Arc::new(InteropErrorInner::LengthMismatch { expected, got }))
374+
}
375+
373376
pub fn external_error(error: Box<dyn std::error::Error + Send + Sync>) -> Self {
374377
Self(Arc::new(InteropErrorInner::OtherError { error }))
375378
}
@@ -429,6 +432,10 @@ pub enum InteropErrorInner {
429432
expected: TypeId,
430433
got: ScriptValue,
431434
},
435+
LengthMismatch {
436+
expected: usize,
437+
got: usize,
438+
},
432439
CouldNotDowncast {
433440
from: ReflectReference,
434441
to: TypeId,
@@ -610,6 +617,9 @@ impl DisplayWithWorld for InteropErrorInner {
610617
format!("Unfinished conversion in context of: {}. A better conversion exists but caller didn't handle the case.", context)
611618
},
612619
InteropErrorInner::OtherError { error } => error.to_string(),
620+
InteropErrorInner::LengthMismatch { expected, got } => {
621+
format!("Array/List Length mismatch, expected: {}, got: {}", expected, got)
622+
},
613623
}
614624
}
615625
}

crates/bevy_mod_scripting_functions/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ bevy = { workspace = true, features = [
2121
"reflect_functions",
2222
] }
2323
uuid = "*"
24+
smol_str = "*"
2425
bevy_mod_scripting_core = { workspace = true, optional = true }

0 commit comments

Comments
 (0)