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