Skip to content

Commit bb789b9

Browse files
committed
use default_get instead of map_get
1 parent da7a771 commit bb789b9

File tree

9 files changed

+56
-141
lines changed

9 files changed

+56
-141
lines changed

assets/tests/iter/hashmap_ipairs.lua

Lines changed: 0 additions & 27 deletions
This file was deleted.

assets/tests/iter/hashmap_pairs.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local map = res.string_map
66
local count = 0
77
local found_keys = {}
88

9-
for key, value in map:pairs() do
9+
for key, value in pairs(map) do
1010
count = count + 1
1111
found_keys[key] = value
1212
end

assets/tests/iter/vec_ipairs.lua

Lines changed: 0 additions & 15 deletions
This file was deleted.

assets/tests/iter/vec_pairs.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ local res_type = world.get_type_by_name("TestResourceWithVariousFields")
22
local res = world.get_resource(res_type)
33

44
local iterated_vals = {}
5-
for v in res.vec_usize:pairs() do
5+
for v in pairs(res.vec_usize) do
66
iterated_vals[#iterated_vals + 1] = v
77
end
88

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
local Resource = world.get_type_by_name("TestResourceWithVariousFields")
22
local resource = world.get_resource(Resource)
33

4-
assert(resource.string_map:map_get("foo") == "bar", "Expected bar, got " .. resource.string_map:map_get("foo"))
4+
assert(resource.string_map["foo"] == "bar", "Expected bar, got " .. resource.string_map["foo"])
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
let Resource = world.get_type_by_name.call("TestResourceWithVariousFields");
22
let resource = world.get_resource.call(Resource);
33

4-
assert(resource.string_map.map_get.call("foo") == "bar", "Expected bar, got " + resource.string_map.map_get.call("foo"));
4+
assert(resource.string_map["foo"] == "bar", "Expected bar, got " + resource.string_map["foo"]);

crates/bevy_mod_scripting_bindings/src/function/magic_functions.rs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! All the switchable special functions used by language implementors
22
use super::{FromScriptRef, FunctionCallContext, IntoScriptRef};
3-
use crate::{ReflectReference, ReflectionPathExt, ScriptValue, error::InteropError};
3+
use crate::{error::InteropError, PartialReflectExt, ReflectReference, ReflectionPathExt, ScriptValue};
44
use bevy_mod_scripting_derive::DebugWithTypeInfo;
55
use bevy_mod_scripting_display::OrFakeId;
6-
use bevy_reflect::{ParsedPath, PartialReflect};
6+
use bevy_reflect::{ParsedPath, PartialReflect, ReflectRef};
77

88
/// A list of magic methods, these only have one replacable implementation, and apply to all `ReflectReferences`.
99
/// It's up to the language implementer to call these in the right order (after any type specific overrides).
@@ -51,8 +51,6 @@ impl MagicFunctions {
5151
/// Indexes into the given reference and if the nested type is a reference type, returns a deeper reference, otherwise
5252
/// returns the concrete value.
5353
///
54-
/// Does not support map types at the moment, for maps see `map_get`
55-
///
5654
/// Arguments:
5755
/// * `ctxt`: The function call context.
5856
/// * `reference`: The reference to index into.
@@ -65,13 +63,57 @@ impl MagicFunctions {
6563
mut reference: ReflectReference,
6664
key: ScriptValue,
6765
) -> Result<ScriptValue, InteropError> {
68-
let mut path: ParsedPath = key.try_into()?;
69-
if ctxt.convert_to_0_indexed() {
70-
path.convert_to_0_indexed();
71-
}
72-
reference.index_path(path);
7366
let world = ctxt.world()?;
74-
ReflectReference::into_script_ref(reference, world)
67+
68+
// Check if the reference is a map type
69+
let is_map = reference.with_reflect(world.clone(), |r| {
70+
matches!(r.reflect_ref(), ReflectRef::Map(_))
71+
})?;
72+
73+
if is_map {
74+
// Handle map indexing specially - need to get the key type and convert the script value
75+
let key = <Box<dyn PartialReflect>>::from_script_ref(
76+
reference.key_type_id(world.clone())?.ok_or_else(|| {
77+
InteropError::unsupported_operation(
78+
reference.tail_type_id(world.clone()).unwrap_or_default(),
79+
Some(Box::new(key.clone())),
80+
"Could not get key type id. Are you trying to index into a type that's not a map?".to_owned(),
81+
)
82+
})?,
83+
key,
84+
world.clone(),
85+
)?;
86+
87+
reference.with_reflect(world.clone(), |s| match s.try_map_get(key.as_ref())? {
88+
Some(value) => {
89+
let reference = {
90+
let allocator = world.allocator();
91+
let mut allocator = allocator.write();
92+
let owned_value = <dyn PartialReflect>::from_reflect(value, world.clone())?;
93+
ReflectReference::new_allocated_boxed(owned_value, &mut allocator)
94+
};
95+
ReflectReference::into_script_ref(reference, world)
96+
}
97+
None => {
98+
// Return None option if key doesn't exist
99+
let none_option: Option<()> = None;
100+
let reference = {
101+
let allocator = world.allocator();
102+
let mut allocator = allocator.write();
103+
ReflectReference::new_allocated_boxed(Box::new(none_option), &mut allocator)
104+
};
105+
ReflectReference::into_script_ref(reference, world)
106+
}
107+
})?
108+
} else {
109+
// Handle path-based indexing for non-map types
110+
let mut path: ParsedPath = key.try_into()?;
111+
if ctxt.convert_to_0_indexed() {
112+
path.convert_to_0_indexed();
113+
}
114+
reference.index_path(path);
115+
ReflectReference::into_script_ref(reference, world)
116+
}
75117
}
76118

77119
/// Sets the value under the specified path on the underlying value.

crates/bevy_mod_scripting_functions/src/core.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -605,47 +605,6 @@ impl ReflectReference {
605605
Ok(format!("{reference:#?}"))
606606
}
607607

608-
/// Gets and clones the value under the specified key if the underlying type is a map type.
609-
/// Uses `from_reflect` to create a fully reflected clone that can be used with all operations.
610-
///
611-
/// Arguments:
612-
/// * `ctxt`: The function call context.
613-
/// * `reference`: The reference to index into.
614-
/// * `key`: The key to index with.
615-
/// Returns:
616-
/// * `value`: The value at the key, if the reference is a map.
617-
fn map_get(
618-
ctxt: FunctionCallContext,
619-
reference: ReflectReference,
620-
key: ScriptValue,
621-
) -> Result<Option<ScriptValue>, InteropError> {
622-
profiling::function_scope!("map_get");
623-
let world = ctxt.world()?;
624-
let key = <Box<dyn PartialReflect>>::from_script_ref(
625-
reference.key_type_id(world.clone())?.ok_or_else(|| {
626-
InteropError::unsupported_operation(
627-
reference.tail_type_id(world.clone()).unwrap_or_default(),
628-
Some(Box::new(key.clone())),
629-
"Could not get key type id. Are you trying to index into a type that's not a map?".to_owned(),
630-
)
631-
})?,
632-
key,
633-
world.clone(),
634-
)?;
635-
reference.with_reflect(world.clone(), |s| match s.try_map_get(key.as_ref())? {
636-
Some(value) => {
637-
let reference = {
638-
let allocator = world.allocator();
639-
let mut allocator = allocator.write();
640-
let owned_value = <dyn PartialReflect>::from_reflect(value, world.clone())?;
641-
ReflectReference::new_allocated_boxed(owned_value, &mut allocator)
642-
};
643-
Ok(Some(ReflectReference::into_script_ref(reference, world)?))
644-
}
645-
None => Ok(None),
646-
})?
647-
}
648-
649608
/// Pushes the value into the reference, if the reference is an appropriate container type.
650609
///
651610
/// Arguments:

crates/languages/bevy_mod_scripting_lua/src/bindings/reference.rs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -348,50 +348,6 @@ impl UserData for LuaReflectReference {
348348
}
349349
});
350350

351-
m.add_method("ipairs", |lua, s: &LuaReflectReference, _args: ()| {
352-
profiling::function_scope!("ipairs");
353-
let world = ThreadWorldContainer
354-
.try_get_world()
355-
.map_err(IntoMluaError::to_lua_error)?;
356-
357-
let iter_func = world
358-
.lookup_function([TypeId::of::<ReflectReference>()], "iter")
359-
.map_err(|f| {
360-
InteropError::missing_function(f, TypeId::of::<ReflectReference>().into())
361-
})
362-
.map_err(IntoMluaError::to_lua_error)?;
363-
364-
let result = iter_func
365-
.call(vec![ScriptValue::Reference(s.clone().into())], LUA_CALLER_CONTEXT)
366-
.map_err(IntoMluaError::to_lua_error)?;
367-
368-
match result {
369-
ScriptValue::FunctionMut(func) => {
370-
let mut index = 0i64;
371-
lua.create_function_mut(move |lua, _args: ()| {
372-
let result = func
373-
.call(vec![], LUA_CALLER_CONTEXT)
374-
.map_err(IntoMluaError::to_lua_error)?;
375-
376-
match result {
377-
ScriptValue::Unit => {
378-
// End of iteration
379-
Ok((mlua::Value::Nil, mlua::Value::Nil))
380-
}
381-
_ => {
382-
// Return (index, value) tuple for ipairs
383-
index += 1;
384-
let idx = mlua::Value::Integer(index);
385-
let val = LuaScriptValue(result).into_lua(lua)?;
386-
Ok((idx, val))
387-
}
388-
}
389-
})
390-
}
391-
_ => Err(mlua::Error::RuntimeError("iter function did not return a FunctionMut".to_string()))
392-
}
393-
});
394-
395351
m.add_meta_function(MetaMethod::ToString, |_, self_: LuaReflectReference| {
396352
profiling::function_scope!("MetaMethod::ToString");
397353
let world = ThreadWorldContainer

0 commit comments

Comments
 (0)