Improve Lua ECS #30
|
@ -1,4 +1,4 @@
|
|||
use std::{ptr::NonNull, ops::Deref};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use lyra_ecs::{query::dynamic::DynamicViewStateIter, Entity};
|
||||
use lyra_reflect::TypeRegistry;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
mod res;
|
||||
use mlua::ObjectLike;
|
||||
pub use res::*;
|
||||
|
||||
use crate::{lua::{LuaComponent, FN_NAME_INTERNAL_ECS_QUERY_RESULT}, ScriptWorldPtr};
|
||||
|
|
|
@ -2,7 +2,7 @@ use lyra_reflect::{ReflectWorldExt, RegisteredType};
|
|||
use mlua::IntoLua;
|
||||
|
||||
use crate::{
|
||||
lua::{LuaComponent, ReflectLuaProxy, WorldError, FN_NAME_INTERNAL_ECS_QUERY_RESULT},
|
||||
lua::{LuaComponent, ReflectLuaProxy, FN_NAME_INTERNAL_ECS_QUERY_RESULT},
|
||||
ScriptWorldPtr,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::{cell::RefCell, ptr::NonNull, rc::Rc, sync::Arc};
|
||||
use std::{ptr::NonNull, sync::Arc};
|
||||
|
||||
use lyra_ecs::{query::dynamic::{DynamicViewState, QueryDynamicType}, Entity};
|
||||
use lyra_reflect::List;
|
||||
use mlua::{FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
|
||||
use tracing::debug;
|
||||
use mlua::{IntoLua, IntoLuaMulti, ObjectLike};
|
||||
|
||||
use crate::{lua::{LuaComponent, LuaEntityRef, ReflectedIteratorOwned, TypeLookup, WorldError, FN_NAME_INTERNAL_ECS_QUERY_RESULT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptBorrow, ScriptWorldPtr};
|
||||
|
||||
|
@ -105,7 +103,6 @@ impl mlua::UserData for View {
|
|||
#[derive(Clone)]
|
||||
pub struct ViewResult {
|
||||
world: ScriptWorldPtr,
|
||||
items: Vec<ViewQueryItem>,
|
||||
reflect_iter: Arc<atomic_refcell::AtomicRefCell<ReflectedIteratorOwned>>,
|
||||
/// The queries and the index they would be inserted in the result.
|
||||
queries: Vec<(LuaQuery, u32)>,
|
||||
|
@ -178,14 +175,14 @@ impl ViewResult {
|
|||
|
||||
Ok(Self {
|
||||
world,
|
||||
items,
|
||||
reflect_iter: Arc::new(atomic_refcell::AtomicRefCell::new(reflected_iter)),
|
||||
queries,
|
||||
reg_key: Arc::new(atomic_refcell::AtomicRefCell::new(None)),
|
||||
})
|
||||
}
|
||||
|
||||
fn next(&mut self, lua: &mlua::Lua) -> Result<Option<(Entity, mlua::MultiValue)>, mlua::Error> {
|
||||
/// Get the next row of components
|
||||
fn next_components(&mut self, lua: &mlua::Lua) -> Result<Option<(Entity, mlua::MultiValue)>, mlua::Error> {
|
||||
let mut query_iter = self.reflect_iter.borrow_mut();
|
||||
if let Some(row) = query_iter.next_lua(lua) {
|
||||
let r = row
|
||||
|
@ -194,7 +191,7 @@ impl ViewResult {
|
|||
.into_iter()
|
||||
.map(|r| (r.comp_val, r.comp_ptr.cast::<()>()))
|
||||
.collect::<Vec<_>>();
|
||||
let (values, ptrs) =
|
||||
let (values, _) =
|
||||
itertools::multiunzip::<(Vec<mlua::Value>, Vec<NonNull<()>>), _>(r);
|
||||
let mult_val = mlua::MultiValue::from_iter(values.into_iter());
|
||||
Ok(Some((row.entity, mult_val)))
|
||||
|
@ -202,6 +199,32 @@ impl ViewResult {
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the query results
|
||||
fn get_query_results(&self) -> mlua::Result<Option<Vec<(mlua::Value, u32)>>> {
|
||||
let mut query_vals = vec![];
|
||||
let mut query_allows = true;
|
||||
for (query, i) in &self.queries {
|
||||
let qres = query.get_query_result(self.world.clone())?;
|
||||
if let Some(val) = qres.as_boolean() {
|
||||
if val {
|
||||
query_allows = false;
|
||||
break;
|
||||
}
|
||||
} else if qres.is_nil() {
|
||||
query_allows = false;
|
||||
break;
|
||||
}
|
||||
|
||||
query_vals.push((qres, *i));
|
||||
}
|
||||
|
||||
if !query_allows {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(query_vals))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::FromLua for ViewResult {
|
||||
|
@ -221,8 +244,23 @@ impl mlua::FromLua for ViewResult {
|
|||
impl mlua::UserData for ViewResult {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_method_mut("next", |lua, this, ()| {
|
||||
match this.next(lua)? {
|
||||
Some((_, val)) => Ok(val),
|
||||
let query_vals = match this.get_query_results()? {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return mlua::Value::Nil.into_lua_multi(lua);
|
||||
}
|
||||
};
|
||||
|
||||
match this.next_components(lua)? {
|
||||
Some((en, mut vals)) => {
|
||||
// insert query values to the result row
|
||||
for (qval, qi) in query_vals {
|
||||
vals.insert(qi as _, qval);
|
||||
}
|
||||
|
||||
vals.push_front(LuaEntityRef::new(this.world.clone(), en).into_lua(lua)?);
|
||||
Ok(vals)
|
||||
},
|
||||
None => mlua::Value::Nil.into_lua_multi(lua)
|
||||
}
|
||||
});
|
||||
|
@ -236,28 +274,14 @@ impl mlua::UserData for ViewResult {
|
|||
if let Some(key) = key_mut.as_ref() {
|
||||
let mut this = lua.registry_value::<Self>(&key)?;
|
||||
|
||||
let mut query_vals = vec![];
|
||||
let mut query_allows = true;
|
||||
for (query, i) in &this.queries {
|
||||
let qres = query.get_query_result(this.world.clone())?;
|
||||
if let Some(val) = qres.as_boolean() {
|
||||
if val {
|
||||
query_allows = false;
|
||||
break;
|
||||
}
|
||||
} else if qres.is_nil() {
|
||||
query_allows = false;
|
||||
break;
|
||||
let query_vals = match this.get_query_results()? {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return mlua::Value::Nil.into_lua_multi(lua);
|
||||
}
|
||||
};
|
||||
|
||||
query_vals.push((qres, *i));
|
||||
}
|
||||
|
||||
if !query_allows {
|
||||
return mlua::Value::Nil.into_lua_multi(lua);
|
||||
}
|
||||
|
||||
match this.next(lua)? {
|
||||
match this.next_components(lua)? {
|
||||
Some((en, mut vals)) => {
|
||||
let lua_en = LuaEntityRef::new(this.world, en)
|
||||
.into_lua(lua)?;
|
||||
|
|
|
@ -15,7 +15,7 @@ pub enum LuaComponent {
|
|||
}
|
||||
|
||||
impl mlua::FromLua for LuaComponent {
|
||||
fn from_lua(value: mlua::Value, lua: &mlua::Lua) -> mlua::Result<Self> {
|
||||
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
|
||||
let tyname = value.type_name();
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(Self::UserData(ud)),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{any::TypeId, collections::HashMap, ptr::NonNull};
|
||||
|
||||
use mlua::{ObjectLike, IntoLua};
|
||||
use mlua::ObjectLike;
|
||||
use lyra_ecs::{ComponentInfo, DynamicBundle};
|
||||
use lyra_reflect::Reflect;
|
||||
|
||||
|
|
Loading…
Reference in New Issue