Improve Lua ECS #30

Merged
SeanOMik merged 15 commits from feat/improve-lua-ecs-29 into main 2024-10-30 03:22:50 +00:00
5 changed files with 69 additions and 6 deletions
Showing only changes of commit 42112c2cf1 - Show all commits

View File

@ -26,11 +26,22 @@ function Has(val)
return HasQuery.new(val)
end
---Create a `NotQuery` filter that will allow results if
---Create a `NotQuery` filter that will allow results if the query returns nothing or
---filter denies.
---
---@see NotQuery
---@param val function|table|userdata
---@return NotQuery
function Not(val)
return NotQuery.new(val)
end
---Create a `OrQuery` filter that will allow results if any of the queries return something.
---The queries are evaluated in the order they were provided.
---
---@see OrQuery
---@param ... function|table|userdata
---@return OrQuery
function Not(...)
return OrQuery.new(...)
end

View File

@ -10,6 +10,9 @@ pub use has::*;
mod not;
pub use not::*;
mod or;
pub use or::*;
use lyra_ecs::Entity;
use crate::{

View File

@ -36,10 +36,10 @@ impl mlua::UserData for LuaNotQuery {
match res {
LuaQueryResult::None => Ok(LuaQueryResult::FilterPass),
super::LuaQueryResult::AlwaysNone => Ok(LuaQueryResult::FilterPass),
super::LuaQueryResult::FilterPass => Ok(LuaQueryResult::FilterDeny),
super::LuaQueryResult::FilterDeny => Ok(LuaQueryResult::FilterPass),
super::LuaQueryResult::Some(_) => Ok(LuaQueryResult::FilterDeny),
LuaQueryResult::AlwaysNone => Ok(LuaQueryResult::FilterPass),
LuaQueryResult::FilterPass => Ok(LuaQueryResult::FilterDeny),
LuaQueryResult::FilterDeny => Ok(LuaQueryResult::FilterPass),
LuaQueryResult::Some(_) => Ok(LuaQueryResult::FilterDeny),
}
},
);

View File

@ -0,0 +1,48 @@
use crate::{lua::FN_NAME_INTERNAL_ECS_QUERY_RESULT, ScriptEntity, ScriptWorldPtr};
use super::{LuaQuery, LuaQueryResult};
#[derive(Clone)]
pub struct LuaOrQuery(Vec<LuaQuery>);
impl mlua::FromLua for LuaOrQuery {
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
let tyname = value.type_name();
value
.as_userdata()
.ok_or(mlua::Error::FromLuaConversionError {
from: tyname,
to: "OrQuery".into(),
message: None,
})
.and_then(|ud| ud.borrow::<Self>())
.map(|ud| ud.clone())
}
}
impl mlua::UserData for LuaOrQuery {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
methods.add_function("new", |_, qs: mlua::Variadic<LuaQuery>| {
Ok(Self(qs.to_vec()))
});
methods.add_method(
FN_NAME_INTERNAL_ECS_QUERY_RESULT,
|_, this, (world, en): (ScriptWorldPtr, ScriptEntity)| {
for q in &this.0 {
let res = q.get_query_result(world.clone(), en.0)?;
match res {
LuaQueryResult::None
| LuaQueryResult::AlwaysNone
| LuaQueryResult::FilterDeny => {}
LuaQueryResult::FilterPass => return Ok(LuaQueryResult::FilterPass),
LuaQueryResult::Some(v) => return Ok(LuaQueryResult::Some(v)),
}
}
Ok(LuaQueryResult::FilterDeny)
},
);
}
}

View File

@ -1,7 +1,7 @@
use lyra_ecs::ResourceObject;
use lyra_reflect::Reflect;
use crate::{lua::{ecs::{query::{LuaChangedQuery, LuaHasQuery, LuaNotQuery, LuaResQuery}, View}, wrappers::*, LuaContext, LuaWrapper, RegisterLuaType, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptApiProvider, ScriptBorrow, ScriptData, ScriptDynamicBundle, ScriptWorldPtr};
use crate::{lua::{ecs::{query::{LuaChangedQuery, LuaHasQuery, LuaNotQuery, LuaOrQuery, LuaResQuery}, View}, wrappers::*, LuaContext, LuaWrapper, RegisterLuaType, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptApiProvider, ScriptBorrow, ScriptData, ScriptDynamicBundle, ScriptWorldPtr};
//fn register_lua_proxy::<T:
@ -49,6 +49,7 @@ impl ScriptApiProvider for LyraEcsApiProvider {
globals.set("ChangedQuery", ctx.create_proxy::<LuaChangedQuery>()?)?;
globals.set("HasQuery", ctx.create_proxy::<LuaHasQuery>()?)?;
globals.set("NotQuery", ctx.create_proxy::<LuaNotQuery>()?)?;
globals.set("OrQuery", ctx.create_proxy::<LuaOrQuery>()?)?;
expose_comp_table_wrapper::<LuaCamera>(&ctx, &globals, "Camera")?;
expose_comp_table_wrapper::<LuaFreeFlyCamera>(&ctx, &globals, "FreeFlyCamera")?;