Skip to content

Commit 49ddcc4

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/refactor-handler-context-as-system-param
2 parents e7db4d6 + 8b588b4 commit 49ddcc4

File tree

8 files changed

+111
-9
lines changed

8 files changed

+111
-9
lines changed

assets/tests/data/set/set_primitives_works.rhai

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,36 @@ resource.bool = true;
66
resource.int = 42;
77
resource.float = 3.0;
88
resource.vec_usize = [ 1, 2 ];
9+
resource.string_map = #{
10+
foo: "string1",
11+
zoo: "string2"
12+
};
913

1014
assert(resource.string == "Hello, World!", "Expected 'Hello, World!', got " + resource.string);
1115
assert(resource.bool == true, "Expected true, got " + resource.bool);
1216
assert(resource.int == 42, "Expected 42, got " + resource.int);
1317
assert(resource.float == 3.0, "Expected 3.14, got " + resource.float);
1418
assert(resource.vec_usize[0] == 1, "Expected 1, got " + resource.vec_usize[1]);
19+
assert(resource.string_map.len.call() == 2, "Expected 2, got " + resource.string_map.len.call());
20+
// assert(resource.string_map.foo == "string1", "Expected 'string1', got " + resource.string_map.foo);
21+
// assert(resource.string_map.zoo == "string2", "Expected 'string2', got " + resource.string_map.zoo);
1522

1623
resource.string = "Goodbye, World!";
1724
resource.bool = false;
1825
resource.int = 24;
1926
resource.float = 1.0;
2027
resource.vec_usize = [ 3, 4 ];
28+
resource.string_map = #{
29+
foo: "goodbye",
30+
zoo: "world"
31+
};
2132

2233
assert(resource.string == "Goodbye, World!", "Expected 'Goodbye, World!', got " + resource.string);
2334
assert(resource.bool == false, "Expected false, got " + resource.bool);
2435
assert(resource.int == 24, "Expected 24, got " + resource.int);
2536
assert(resource.float == 1.0, "Expected 1.41, got " + resource.float);
2637
assert(resource.vec_usize[0] == 3, "Expected 3, got " + resource.vec_usize[1]);
27-
38+
assert(resource.string_map.len.call() == 2, "Expected 2, got " + resource.string_map.len.call());
39+
// assert(resource.string_map.foo == "goodbye", "Expected 'goodbye', got " + resource.string_map.foo);
40+
// assert(resource.string_map.zoo == "world", "Expected 'world', got " + resource.string_map.zoo);
2841

assets/tests/set/set_primitives_works.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,29 @@ resource.bool = true
66
resource.int = 42
77
resource.float = 3.0
88
resource.vec_usize = { 1, 2 }
9+
resource.string_map = { foo = "hello", zoo = "world" }
910

1011
assert(resource.string == "Hello, World!", "Expected 'Hello, World!', got " .. resource.string)
1112
assert(resource.bool == true, "Expected true, got " .. tostring(resource.bool))
1213
assert(resource.int == 42, "Expected 42, got " .. resource.int)
1314
assert(resource.float == 3.0, "Expected 3.14, got " .. resource.float)
1415
assert(resource.vec_usize[1] == 1, "Expected 1, got " .. resource.vec_usize[1])
16+
assert(resource.string_map:len() == 2, "Expected 2, got " .. resource.string_map:len())
17+
-- assert(resource.string_map["foo"] == "hello", "Expected 'hello', got " .. resource.string_map["foo"])
18+
-- assert(resource.string_map["zoo"] == "world", "Expected 'world', got " .. resource.string_map["zoo"])
1519

1620
resource.string = "Goodbye, World!"
1721
resource.bool = false
1822
resource.int = 24
1923
resource.float = 1.0
2024
resource.vec_usize = { 3, 4 }
25+
resource.string_map = { foo = "goodbye", zoo = "world" }
2126

2227
assert(resource.string == "Goodbye, World!", "Expected 'Goodbye, World!', got " .. resource.string)
2328
assert(resource.bool == false, "Expected false, got " .. tostring(resource.bool))
2429
assert(resource.int == 24, "Expected 24, got " .. resource.int)
2530
assert(resource.float == 1.0, "Expected 1.41, got " .. resource.float)
26-
assert(resource.vec_usize[1] == 3, "Expected 3, got " .. resource.vec_usize[1])
27-
31+
assert(resource.string_map:len() == 2, "Expected 2, got " .. resource.string_map:len())
32+
-- assert(resource.string_map["foo"] == "goodbye", "Expected 'goodbye', got " .. resource.string_map["foo"])
33+
-- assert(resource.string_map["zoo"] == "world", "Expected 'world', got " .. resource.string_map["zoo"])
2834

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,14 @@ where
449449
}
450450
Ok(hashmap)
451451
}
452+
ScriptValue::List(list) => {
453+
let mut hashmap = std::collections::HashMap::new();
454+
for elem in list {
455+
let (key, val) = <(String, V)>::from_script(elem, world.clone())?;
456+
hashmap.insert(key, val);
457+
}
458+
Ok(hashmap)
459+
}
452460
_ => Err(InteropError::value_mismatch(
453461
std::any::TypeId::of::<std::collections::HashMap<String, V>>(),
454462
value,
@@ -499,3 +507,44 @@ where
499507
}
500508
}
501509
}
510+
511+
macro_rules! impl_from_script_tuple {
512+
($($ty:ident),*) => {
513+
#[allow(non_snake_case)]
514+
impl<$($ty: FromScript),*> FromScript for ($($ty,)*)
515+
where
516+
Self: 'static,
517+
$(
518+
for<'w> $ty::This<'w>: Into<$ty>,
519+
)*
520+
{
521+
type This<'w> = Self;
522+
523+
fn from_script(value: ScriptValue, world: WorldGuard<'_>) -> Result<Self, InteropError> {
524+
match value {
525+
ScriptValue::List(list) => {
526+
let expected_arg_count = $crate::bindings::function::script_function::count!( $($ty)* );
527+
if list.len() != expected_arg_count {
528+
return Err(InteropError::length_mismatch(expected_arg_count, list.len()));
529+
}
530+
531+
let mut iter = list.into_iter();
532+
$(
533+
let next_item = iter.next().ok_or_else(|| InteropError::invariant("list has right amount of elements"))?;
534+
let $ty = $ty::from_script(next_item, world.clone())?.into();
535+
)*
536+
537+
538+
Ok(($($ty,)*))
539+
}
540+
_ => Err(InteropError::value_mismatch(
541+
std::any::TypeId::of::<Self>(),
542+
value,
543+
)),
544+
}
545+
}
546+
}
547+
};
548+
}
549+
550+
bevy::utils::all_tuples!(impl_from_script_tuple, 1, 14, T);

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
33
use std::{any::TypeId, ffi::OsString, path::PathBuf};
44

5-
use bevy::reflect::{DynamicEnum, DynamicList, DynamicTuple, DynamicVariant, PartialReflect};
5+
use bevy::reflect::{
6+
DynamicEnum, DynamicList, DynamicMap, DynamicTuple, DynamicVariant, Map, PartialReflect,
7+
};
68

79
use crate::{
810
bindings::{function::from::FromScript, WorldGuard},
@@ -100,6 +102,23 @@ impl FromScriptRef for Box<dyn PartialReflect> {
100102
}
101103
}
102104

105+
if let Some((key_type, val_type)) = type_info.map_inner_types() {
106+
if let ScriptValue::Map(map) = value {
107+
let mut dynamic_map = DynamicMap::default();
108+
for (key, val) in map {
109+
let key = Self::from_script_ref(
110+
key_type,
111+
ScriptValue::String(key.into()),
112+
world.clone(),
113+
)?;
114+
let val = Self::from_script_ref(val_type, val, world.clone())?;
115+
dynamic_map.insert_boxed(key, val);
116+
}
117+
dynamic_map.set_represented_type(Some(type_info));
118+
return Ok(Box::new(dynamic_map));
119+
}
120+
}
121+
103122
match value {
104123
ScriptValue::Reference(reflect_reference) => reflect_reference.to_owned_value(world),
105124
value => Err(InteropError::value_mismatch(target, value)),

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ mod test {
151151
for<'a> T::This<'a>: Into<T>,
152152
{
153153
test_is_valid_arg_and_return::<()>();
154-
test_is_valid_return::<(T,)>();
155-
test_is_valid_return::<(T, T)>();
156-
test_is_valid_return::<(T, T, T, T, T, T, T, T, T, T)>();
154+
test_is_valid_arg_and_return::<(T,)>();
155+
test_is_valid_arg_and_return::<(T, T)>();
156+
test_is_valid_arg_and_return::<(T, T, T, T, T, T, T, T, T, T)>();
157157
}
158158

159159
fn test_option<T>()

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,12 @@ impl ScriptFunctionRegistry {
530530
}
531531

532532
macro_rules! count {
533-
() => (0usize);
534-
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
533+
() => (0usize);
534+
( $x:tt $($xs:tt)* ) => (1usize + $crate::bindings::function::script_function::count!($($xs)*));
535535
}
536536

537+
pub(crate) use count;
538+
537539
macro_rules! impl_script_function {
538540

539541
($( $param:ident ),* ) => {

crates/bevy_mod_scripting_core/src/reflection_extensions.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ impl<T: PartialReflect + ?Sized> PartialReflectExt for T {
419419

420420
/// Extension trait for TypeInfos providing additional functionality for working with type information.
421421
pub trait TypeInfoExtensions {
422+
/// Returns the inner type of the map if the type is a map, otherwise
423+
fn map_inner_types(&self) -> Option<(TypeId, TypeId)>;
422424
/// Returns the inner type of the list if the type is a list, otherwise None.
423425
fn list_inner_type(&self) -> Option<TypeId>;
424426
/// Returns true if the type is a list.
@@ -452,6 +454,11 @@ impl TypeInfoExtensions for TypeInfo {
452454
Some(self.as_list().ok()?.item_ty().id())
453455
}
454456

457+
fn map_inner_types(&self) -> Option<(TypeId, TypeId)> {
458+
let map = self.as_map().ok()?;
459+
Some((map.key_ty().id(), map.value_ty().id()))
460+
}
461+
455462
fn is_type(&self, crate_name: Option<&str>, type_ident: &str) -> bool {
456463
self.type_path_table().ident() == Some(type_ident)
457464
&& self.type_path_table().crate_name() == crate_name

crates/testing_crates/test_utils/src/test_data.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::alloc::Layout;
2+
use std::collections::HashMap;
23

34
use bevy::asset::AssetPlugin;
45
use bevy::diagnostic::DiagnosticsPlugin;
@@ -126,6 +127,7 @@ pub struct TestResourceWithVariousFields {
126127
pub float: f32,
127128
pub bool: bool,
128129
pub vec_usize: Vec<usize>,
130+
pub string_map: HashMap<String, String>,
129131
}
130132

131133
impl TestResourceWithVariousFields {
@@ -137,6 +139,10 @@ impl TestResourceWithVariousFields {
137139
float: 69.0,
138140
bool: true,
139141
vec_usize: vec![1, 2, 3, 4, 5],
142+
string_map: vec![("foo", "bar"), ("zoo", "zed")]
143+
.into_iter()
144+
.map(|(a, b)| (a.to_owned(), b.to_owned()))
145+
.collect(),
140146
}
141147
}
142148
}

0 commit comments

Comments
 (0)