Fix #19: Lua crashes when spawning entities in optimized builds #27

Merged
SeanOMik merged 4 commits from fix/scripting-switch-to-mlua into main 2024-09-30 01:39:40 +00:00
6 changed files with 27 additions and 27 deletions
Showing only changes of commit ef2b0bf326 - Show all commits

View File

@ -51,12 +51,12 @@ function on_update()
end, Transform) ]]
---@type number
--[[ local dt = world:resource(DeltaTime)
local dt = world:resource(DeltaTime)
world:view(function (t)
t:translate(0, 0.15 * dt, 0)
return t
end, Transform) ]]
end, Transform)
end
--[[ 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
pub unsafe fn get_resource_ptr<T: ResourceObject>(&self) -> Option<NonNull<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 {

View File

@ -224,7 +224,7 @@ impl MetaMethod {
// this is the body of the else statement
{
// 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") {
return Err(mlua::Error::BadArgument {
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),

View File

@ -6,8 +6,6 @@ use lyra_reflect::TypeRegistry;
#[cfg(feature = "lua")]
use super::ReflectLuaProxy;
use crate::ScriptWorldPtr;
#[cfg(feature = "lua")]
pub struct ReflectedItem {
//pub proxy: &'a ReflectLuaProxy,
@ -21,23 +19,23 @@ pub struct ReflectedRow {
pub row: Vec<ReflectedItem>,
}
pub struct ReflectedIterator {
pub world: ScriptWorldPtr,
pub struct ReflectedIterator<'a> {
pub world: &'a lyra_ecs::World,
pub dyn_view: DynamicViewStateIter,
pub reflected_components: Option<NonNull<TypeRegistry>>
}
impl ReflectedIterator {
impl<'a> ReflectedIterator<'a> {
#[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;
let world = self.world.read();
let n = self.dyn_view.next(&world);
//let world = self.world.read();
let n = self.dyn_view.next(&self.world);
if let Some((en, row)) = n {
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()));
}

View File

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

View File

@ -155,13 +155,21 @@ impl mlua::UserData for ScriptWorldPtr {
let iter = view.into_iter();
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),
reflected_components: None,
};
let mut current = world.current_tick();
let mut has_ticked = false;
let current = world.current_tick();
// 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) {
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 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) {
let lua_typeid = match &comp {
@ -202,7 +205,6 @@ impl mlua::UserData for ScriptWorldPtr {
};
// update the component tick
let mut world = this.write();
let arch = world.entity_archetype_mut(row.entity).unwrap();
let idx = arch.entity_indexes().get(&row.entity).unwrap().clone();
let c = arch.get_column_mut(lua_typeid).unwrap();
@ -246,9 +248,6 @@ impl mlua::UserData for ScriptWorldPtr {
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 res = reflect.reflect_branch.as_resource_unchecked();