ecs,scripting: fix invalid resources being passed to lua
CI / build (pull_request) Failing after 3m35s Details

The issue was World::get_resource_ptr, it was returning a pointer to the AtomicRefCell instead of the actual resource data
This commit is contained in:
SeanOMik 2024-09-29 14:35:24 -04:00
parent fa22a0310c
commit ef2b0bf326
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
6 changed files with 27 additions and 27 deletions

View File

@ -51,12 +51,12 @@ function on_update()
end, Transform) ]] end, Transform) ]]
---@type number ---@type number
--[[ local dt = world:resource(DeltaTime) local dt = world:resource(DeltaTime)
world:view(function (t) world:view(function (t)
t:translate(0, 0.15 * dt, 0) t:translate(0, 0.15 * dt, 0)
return t return t
end, Transform) ]] end, Transform)
end end
--[[ function on_post_update() --[[ function on_post_update()

View File

@ -509,7 +509,11 @@ impl World {
/// Attempts to find a resource in the world and returns a NonNull pointer to it /// Attempts to find a resource in the world and returns a NonNull pointer to it
pub unsafe fn get_resource_ptr<T: ResourceObject>(&self) -> Option<NonNull<T>> { pub unsafe fn get_resource_ptr<T: ResourceObject>(&self) -> Option<NonNull<T>> {
self.resources.get(&TypeId::of::<T>()) self.resources.get(&TypeId::of::<T>())
.map(|d| unsafe { NonNull::new_unchecked(d.data.as_ptr() as *mut T) }) .map(|d| unsafe {
let data = d.data.borrow();
let ptr = NonNull::from(&data.res);
NonNull::new_unchecked(ptr.as_ptr() as *mut T)
})
} }
pub fn archetype_count(&self) -> usize { pub fn archetype_count(&self) -> usize {

View File

@ -224,7 +224,7 @@ impl MetaMethod {
// this is the body of the else statement // this is the body of the else statement
{ {
// try to get the name of the userdata for the error message // try to get the name of the userdata for the error message
if let Ok(mt) = ud.get_metatable() { if let Ok(mt) = ud.metatable() {
if let Ok(name) = mt.get::<String>("__name") { if let Ok(name) = mt.get::<String>("__name") {
return Err(mlua::Error::BadArgument { return Err(mlua::Error::BadArgument {
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)), to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),

View File

@ -6,8 +6,6 @@ use lyra_reflect::TypeRegistry;
#[cfg(feature = "lua")] #[cfg(feature = "lua")]
use super::ReflectLuaProxy; use super::ReflectLuaProxy;
use crate::ScriptWorldPtr;
#[cfg(feature = "lua")] #[cfg(feature = "lua")]
pub struct ReflectedItem { pub struct ReflectedItem {
//pub proxy: &'a ReflectLuaProxy, //pub proxy: &'a ReflectLuaProxy,
@ -21,23 +19,23 @@ pub struct ReflectedRow {
pub row: Vec<ReflectedItem>, pub row: Vec<ReflectedItem>,
} }
pub struct ReflectedIterator { pub struct ReflectedIterator<'a> {
pub world: ScriptWorldPtr, pub world: &'a lyra_ecs::World,
pub dyn_view: DynamicViewStateIter, pub dyn_view: DynamicViewStateIter,
pub reflected_components: Option<NonNull<TypeRegistry>> pub reflected_components: Option<NonNull<TypeRegistry>>
} }
impl ReflectedIterator { impl<'a> ReflectedIterator<'a> {
#[cfg(feature = "lua")] #[cfg(feature = "lua")]
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<ReflectedRow> { pub fn next_lua(&mut self, lua: &mlua::Lua) -> Option<ReflectedRow> {
use mlua::IntoLua; use mlua::IntoLua;
let world = self.world.read(); //let world = self.world.read();
let n = self.dyn_view.next(&world); let n = self.dyn_view.next(&self.world);
if let Some((en, row)) = n { if let Some((en, row)) = n {
if self.reflected_components.is_none() { if self.reflected_components.is_none() {
self.reflected_components = world.get_resource::<TypeRegistry>() self.reflected_components = self.world.get_resource::<TypeRegistry>()
.map(|r| NonNull::from(r.deref())); .map(|r| NonNull::from(r.deref()));
} }

View File

@ -36,8 +36,7 @@ where
this: &dyn Reflect, this: &dyn Reflect,
) -> mlua::Result<mlua::Value> { ) -> mlua::Result<mlua::Value> {
let this = this.as_any().downcast_ref::<T>().unwrap(); let this = this.as_any().downcast_ref::<T>().unwrap();
lua.create_userdata(this.clone()) this.clone().into_lua(lua)
.and_then(|ud| ud.into_lua(lua))
} }
fn apply( fn apply(

View File

@ -155,13 +155,21 @@ impl mlua::UserData for ScriptWorldPtr {
let iter = view.into_iter(); let iter = view.into_iter();
let mut reflected_iter = ReflectedIterator { let mut reflected_iter = ReflectedIterator {
world: this.clone(), // SAFETY: bypassing the borrow checker here to get a pointer of the world
// is required since we mutably borrow below. Its safe to do so since
// only the entity ticks are updated. They are accessing different things
// from the world.
world: unsafe { NonNull::from(&*world).as_ref() },
dyn_view: DynamicViewStateIter::from(iter), dyn_view: DynamicViewStateIter::from(iter),
reflected_components: None, reflected_components: None,
}; };
let mut current = world.current_tick(); let current = world.current_tick();
let mut has_ticked = false;
// drop read lock and acquire the write lock.
// dropping must be done to avoid mutex deadlock
drop(world);
let mut world = this.write();
while let Some(row) = reflected_iter.next_lua(lua) { while let Some(row) = reflected_iter.next_lua(lua) {
let r = row.row.into_iter() let r = row.row.into_iter()
@ -175,11 +183,6 @@ impl mlua::UserData for ScriptWorldPtr {
// if values were returned, find the type in the type registry, and apply the new values // if values were returned, find the type in the type registry, and apply the new values
if res.len() <= ptrs.len() { if res.len() <= ptrs.len() {
// we only want to tick one time per system
if !has_ticked {
current = world.tick();
has_ticked = true;
}
for (comp, ptr) in res.into_iter().zip(ptrs) { for (comp, ptr) in res.into_iter().zip(ptrs) {
let lua_typeid = match &comp { let lua_typeid = match &comp {
@ -202,7 +205,6 @@ impl mlua::UserData for ScriptWorldPtr {
}; };
// update the component tick // update the component tick
let mut world = this.write();
let arch = world.entity_archetype_mut(row.entity).unwrap(); let arch = world.entity_archetype_mut(row.entity).unwrap();
let idx = arch.entity_indexes().get(&row.entity).unwrap().clone(); let idx = arch.entity_indexes().get(&row.entity).unwrap().clone();
let c = arch.get_column_mut(lua_typeid).unwrap(); let c = arch.get_column_mut(lua_typeid).unwrap();
@ -246,9 +248,6 @@ impl mlua::UserData for ScriptWorldPtr {
panic!("how"); panic!("how");
} }
}; };
/* let reflect = ty
.execute_function::<ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
.expect("Type does not implement 'reflect_type' properly"); */
let mut world = this.write(); let mut world = this.write();
let res = reflect.reflect_branch.as_resource_unchecked(); let res = reflect.reflect_branch.as_resource_unchecked();