Fix #19: Lua crashes when spawning entities in optimized builds #27
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue