Improve Lua ECS #30
|
@ -90,37 +90,15 @@ function on_update()
|
||||||
end
|
end
|
||||||
end, Transform) ]]
|
end, Transform) ]]
|
||||||
|
|
||||||
---@type number
|
local view = View.new(Transform, WorldTransform, Res(DeltaTime))
|
||||||
local dt = world:resource(DeltaTime)
|
|
||||||
|
|
||||||
local view = View.new(Transform, WorldTransform)
|
|
||||||
local res = world:view_query(view)
|
local res = world:view_query(view)
|
||||||
|
|
||||||
for entity, transform, world_tran in res:iter() do
|
for entity, transform, world_tran, dt in res:iter() do
|
||||||
print("Entity is at: " .. tostring(world_tran))
|
print("Entity is at: " .. tostring(world_tran))
|
||||||
|
|
||||||
transform:translate(0, 0.15 * dt, 0)
|
transform:translate(0, 0.15 * dt, 0)
|
||||||
entity:update(transform)
|
entity:update(transform)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ world:view(
|
|
||||||
---@param t Transform
|
|
||||||
function (t)
|
|
||||||
t:translate(0, 0.15 * dt, 0)
|
|
||||||
return t
|
|
||||||
end, Transform
|
|
||||||
) ]]
|
|
||||||
|
|
||||||
--[[ world:view(
|
|
||||||
---@param c Camera
|
|
||||||
function (c)
|
|
||||||
c.transform:translate(0, 0.15 * dt, 0)
|
|
||||||
|
|
||||||
print("Moving camera to: " .. tostring(c.transform))
|
|
||||||
|
|
||||||
return c
|
|
||||||
end, Camera
|
|
||||||
) ]]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ function on_post_update()
|
--[[ function on_post_update()
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---Create a Resource Query
|
||||||
|
---@param resource table|userdata
|
||||||
|
---@return ResQuery
|
||||||
|
function Res(resource)
|
||||||
|
return ResQuery.new(resource)
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
mod view;
|
||||||
|
pub use view::*;
|
||||||
|
|
||||||
|
pub mod query;
|
|
@ -0,0 +1,26 @@
|
||||||
|
mod res;
|
||||||
|
use mlua::ObjectLike;
|
||||||
|
pub use res::*;
|
||||||
|
|
||||||
|
use crate::{lua::{LuaComponent, FN_NAME_INTERNAL_ECS_QUERY_RESULT}, ScriptWorldPtr};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LuaQuery {
|
||||||
|
query: LuaComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LuaQuery {
|
||||||
|
pub fn new(query: LuaComponent) -> Self {
|
||||||
|
Self {
|
||||||
|
query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the result of the query
|
||||||
|
///
|
||||||
|
/// > WARNING: ensure that the world pointer is not locked. If its locked when you call this,
|
||||||
|
/// you WILL cause a deadlock.
|
||||||
|
pub fn get_query_result(&self, world: ScriptWorldPtr) -> mlua::Result<mlua::Value> {
|
||||||
|
self.query.call_method(FN_NAME_INTERNAL_ECS_QUERY_RESULT, world)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
use lyra_reflect::{ReflectWorldExt, RegisteredType};
|
||||||
|
use mlua::IntoLua;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
lua::{LuaComponent, ReflectLuaProxy, WorldError, FN_NAME_INTERNAL_ECS_QUERY_RESULT},
|
||||||
|
ScriptWorldPtr,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LuaResQuery {
|
||||||
|
ty: LuaComponent,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl mlua::FromLua for LuaResQuery {
|
||||||
|
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: "ResQuery".into(),
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
.and_then(|ud| ud.borrow::<Self>())
|
||||||
|
.map(|ud| ud.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl mlua::UserData for LuaResQuery {
|
||||||
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||||
|
methods.add_function("new", |_, comp: LuaComponent| {
|
||||||
|
Ok(Self {
|
||||||
|
ty: comp
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method(FN_NAME_INTERNAL_ECS_QUERY_RESULT, |lua, this, world: ScriptWorldPtr| {
|
||||||
|
let mut world = world.write();
|
||||||
|
let reflect = this.ty.reflect_type()?;
|
||||||
|
|
||||||
|
let res = reflect.reflect_branch.as_resource_unchecked();
|
||||||
|
if let Some(res_ptr) = res.reflect_ptr(&mut world) {
|
||||||
|
let reg_type = world
|
||||||
|
.get_type::<RegisteredType>(reflect.reflect_branch.reflect_type_id())
|
||||||
|
.expect("Resource is not type registered!");
|
||||||
|
let proxy = reg_type
|
||||||
|
.get_data::<ReflectLuaProxy>()
|
||||||
|
.expect("Type does not have ReflectLuaProxy as a TypeData");
|
||||||
|
|
||||||
|
(proxy.fn_as_lua)(lua, res_ptr.cast()).and_then(|ud| ud.into_lua(lua))
|
||||||
|
} else {
|
||||||
|
// if the resource is not found in the world, return nil
|
||||||
|
Ok(mlua::Value::Nil)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
use std::{cell::RefCell, ptr::NonNull, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, ptr::NonNull, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use lyra_ecs::{query::dynamic::{DynamicViewState, QueryDynamicType}, Entity};
|
use lyra_ecs::{query::dynamic::{DynamicViewState, QueryDynamicType}, Entity};
|
||||||
|
use lyra_reflect::List;
|
||||||
use mlua::{FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
|
use mlua::{FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{lua::{WorldError, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptBorrow, ScriptWorldPtr};
|
use crate::{lua::{LuaComponent, LuaEntityRef, ReflectedIteratorOwned, TypeLookup, WorldError, FN_NAME_INTERNAL_ECS_QUERY_RESULT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptBorrow, ScriptWorldPtr};
|
||||||
|
|
||||||
use super::{LuaEntityRef, ReflectedIteratorOwned, TypeLookup};
|
use super::query::LuaQuery;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum ViewQueryItem {
|
enum ViewQueryItem {
|
||||||
|
@ -37,6 +38,34 @@ impl ViewQueryItem {
|
||||||
matches!(self, ViewQueryItem::Function(_))
|
matches!(self, ViewQueryItem::Function(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the QueryItem has a function of `name`.
|
||||||
|
///
|
||||||
|
/// Returns `false` if self is a function.
|
||||||
|
pub fn has_function(&self, name: &str) -> mlua::Result<bool> {
|
||||||
|
match self {
|
||||||
|
Self::UserData(ud) => {
|
||||||
|
ud.get::<mlua::Value>(name).map(|v| !v.is_nil())
|
||||||
|
},
|
||||||
|
Self::Table(t) => {
|
||||||
|
t.contains_key(name)
|
||||||
|
},
|
||||||
|
Self::Function(_) => Ok(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_query(&self) -> mlua::Result<bool> {
|
||||||
|
self.has_function(FN_NAME_INTERNAL_ECS_QUERY_RESULT)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clone self into a [`LuaComponent`].
|
||||||
|
pub fn as_component(&self) -> Option<LuaComponent> {
|
||||||
|
match self.clone() {
|
||||||
|
ViewQueryItem::UserData(ud) => Some(LuaComponent::UserData(ud)),
|
||||||
|
ViewQueryItem::Table(t) => Some(LuaComponent::Table(t)),
|
||||||
|
ViewQueryItem::Function(_) => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* pub fn get_lookup(&self) -> Option<Res<TypeLookup>> {
|
/* pub fn get_lookup(&self) -> Option<Res<TypeLookup>> {
|
||||||
match self {
|
match self {
|
||||||
|
|
||||||
|
@ -77,7 +106,9 @@ impl mlua::UserData for View {
|
||||||
pub struct ViewResult {
|
pub struct ViewResult {
|
||||||
world: ScriptWorldPtr,
|
world: ScriptWorldPtr,
|
||||||
items: Vec<ViewQueryItem>,
|
items: Vec<ViewQueryItem>,
|
||||||
query_iter: Arc<atomic_refcell::AtomicRefCell<ReflectedIteratorOwned>>,
|
reflect_iter: Arc<atomic_refcell::AtomicRefCell<ReflectedIteratorOwned>>,
|
||||||
|
/// The queries and the index they would be inserted in the result.
|
||||||
|
queries: Vec<(LuaQuery, u32)>,
|
||||||
reg_key: Arc<atomic_refcell::AtomicRefCell<Option<mlua::RegistryKey>>>,
|
reg_key: Arc<atomic_refcell::AtomicRefCell<Option<mlua::RegistryKey>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +119,15 @@ impl ViewResult {
|
||||||
let items = view.items.clone();
|
let items = view.items.clone();
|
||||||
let w = world.read();
|
let w = world.read();
|
||||||
let mut view = DynamicViewState::new();
|
let mut view = DynamicViewState::new();
|
||||||
|
let mut queries = vec![];
|
||||||
|
|
||||||
for (idx, comp) in items.iter().enumerate() {
|
for (idx, comp) in items.iter().enumerate() {
|
||||||
|
if comp.is_query()? {
|
||||||
|
// Unwrap is safe since `is_query` ensures that the component is convertible.
|
||||||
|
queries.push((LuaQuery::new(comp.as_component().unwrap()), idx as u32));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
match comp {
|
match comp {
|
||||||
ViewQueryItem::Table(t) => {
|
ViewQueryItem::Table(t) => {
|
||||||
let name: String = t.get(mlua::MetaMethod::Type.name())?;
|
let name: String = t.get(mlua::MetaMethod::Type.name())?;
|
||||||
|
@ -141,13 +179,14 @@ impl ViewResult {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
world,
|
world,
|
||||||
items,
|
items,
|
||||||
query_iter: Arc::new(atomic_refcell::AtomicRefCell::new(reflected_iter)),
|
reflect_iter: Arc::new(atomic_refcell::AtomicRefCell::new(reflected_iter)),
|
||||||
|
queries,
|
||||||
reg_key: Arc::new(atomic_refcell::AtomicRefCell::new(None)),
|
reg_key: Arc::new(atomic_refcell::AtomicRefCell::new(None)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next(&mut self, lua: &mlua::Lua) -> Result<Option<(Entity, mlua::MultiValue)>, mlua::Error> {
|
fn next(&mut self, lua: &mlua::Lua) -> Result<Option<(Entity, mlua::MultiValue)>, mlua::Error> {
|
||||||
let mut query_iter = self.query_iter.borrow_mut();
|
let mut query_iter = self.reflect_iter.borrow_mut();
|
||||||
if let Some(row) = query_iter.next_lua(lua) {
|
if let Some(row) = query_iter.next_lua(lua) {
|
||||||
let r = row
|
let r = row
|
||||||
.row
|
.row
|
||||||
|
@ -196,12 +235,38 @@ impl mlua::UserData for ViewResult {
|
||||||
|
|
||||||
if let Some(key) = key_mut.as_ref() {
|
if let Some(key) = key_mut.as_ref() {
|
||||||
let mut this = lua.registry_value::<Self>(&key)?;
|
let mut this = lua.registry_value::<Self>(&key)?;
|
||||||
let v = this.next(lua)?;
|
|
||||||
|
|
||||||
match v {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
query_vals.push((qres, *i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !query_allows {
|
||||||
|
return mlua::Value::Nil.into_lua_multi(lua);
|
||||||
|
}
|
||||||
|
|
||||||
|
match this.next(lua)? {
|
||||||
Some((en, mut vals)) => {
|
Some((en, mut vals)) => {
|
||||||
let lua_en = LuaEntityRef::new(this.world, en)
|
let lua_en = LuaEntityRef::new(this.world, en)
|
||||||
.into_lua(lua)?;
|
.into_lua(lua)?;
|
||||||
|
|
||||||
|
// insert query values to the result row
|
||||||
|
for (qval, qi) in query_vals {
|
||||||
|
vals.insert(qi as _, qval);
|
||||||
|
}
|
||||||
|
|
||||||
vals.push_front(lua_en);
|
vals.push_front(lua_en);
|
||||||
Ok(vals)
|
Ok(vals)
|
||||||
},
|
},
|
|
@ -2,11 +2,11 @@ use std::{any::TypeId, sync::Arc};
|
||||||
|
|
||||||
use lyra_ecs::{Entity, World};
|
use lyra_ecs::{Entity, World};
|
||||||
use lyra_reflect::TypeRegistry;
|
use lyra_reflect::TypeRegistry;
|
||||||
use mlua::IntoLua;
|
use mlua::{IntoLua, ObjectLike};
|
||||||
|
|
||||||
use crate::ScriptWorldPtr;
|
use crate::{ScriptBorrow, ScriptWorldPtr};
|
||||||
|
|
||||||
use super::{reflect_user_data, ReflectLuaProxy, TypeLookup};
|
use super::{reflect_user_data, Error, ReflectLuaProxy, TypeLookup, FN_NAME_INTERNAL_REFLECT_TYPE};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum LuaComponent {
|
pub enum LuaComponent {
|
||||||
|
@ -55,6 +55,46 @@ impl LuaComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Call the internal reflect type function and return the result.
|
||||||
|
///
|
||||||
|
/// This calls the [`FN_NAME_INTERNAL_REFLECT_TYPE`] function on the Component.
|
||||||
|
pub fn reflect_type(&self) -> Result<ScriptBorrow, Error> {
|
||||||
|
self.call_function(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
||||||
|
.map_err(|_| Error::Reflect)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call a Lua function on the Component.
|
||||||
|
///
|
||||||
|
/// This is a helper function so you don't have to match on the component.
|
||||||
|
pub fn call_function<R: mlua::FromLuaMulti>(&self, name: &str, args: impl mlua::IntoLuaMulti) -> mlua::Result<R> {
|
||||||
|
match self {
|
||||||
|
LuaComponent::UserData(ud) => ud.call_function(name, args),
|
||||||
|
LuaComponent::Table(t) => t.call_function(name, args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call a Lua method on the Component.
|
||||||
|
///
|
||||||
|
/// This is a helper function so you don't have to match on the component.
|
||||||
|
pub fn call_method<R: mlua::FromLuaMulti>(&self, name: &str, args: impl mlua::IntoLuaMulti) -> mlua::Result<R> {
|
||||||
|
match self {
|
||||||
|
LuaComponent::UserData(ud) => ud.call_method(name, args),
|
||||||
|
LuaComponent::Table(t) => t.call_method(name, args),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the Component has a function of `name`.
|
||||||
|
pub fn has_function(&self, name: &str) -> mlua::Result<bool> {
|
||||||
|
match self {
|
||||||
|
LuaComponent::UserData(ud) => {
|
||||||
|
ud.get::<mlua::Value>(name).map(|v| !v.is_nil())
|
||||||
|
},
|
||||||
|
LuaComponent::Table(t) => {
|
||||||
|
t.contains_key(name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference to an Entity for Lua
|
/// Reference to an Entity for Lua
|
||||||
|
|
|
@ -18,8 +18,7 @@ pub mod wrappers;
|
||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
pub use proxy::*;
|
pub use proxy::*;
|
||||||
|
|
||||||
mod view;
|
pub mod ecs;
|
||||||
pub use view::*;
|
|
||||||
|
|
||||||
mod entity_ref;
|
mod entity_ref;
|
||||||
pub use entity_ref::*;
|
pub use entity_ref::*;
|
||||||
|
@ -48,7 +47,9 @@ pub enum Error {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Mlua(#[from] mlua::Error),
|
Mlua(#[from] mlua::Error),
|
||||||
#[error("unimplemented: {0}")]
|
#[error("unimplemented: {0}")]
|
||||||
Unimplemented(String)
|
Unimplemented(String),
|
||||||
|
#[error("Error calling internal reflection type")]
|
||||||
|
Reflect,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* impl Into<mlua::Error> for Error {
|
/* impl Into<mlua::Error> for Error {
|
||||||
|
@ -92,6 +93,16 @@ pub const FN_NAME_INTERNAL_REFLECT_TYPE: &str = "__lyra_internal_reflect_type";
|
||||||
/// method to return data**.
|
/// method to return data**.
|
||||||
pub const FN_NAME_INTERNAL_REFLECT: &str = "__lyra_internal_reflect";
|
pub const FN_NAME_INTERNAL_REFLECT: &str = "__lyra_internal_reflect";
|
||||||
|
|
||||||
|
/// Name of a Lua function to retrieve the query result from a Userdata, or Table.
|
||||||
|
///
|
||||||
|
/// This function must return a Lua value and take in a single argument: [`ScriptWorldPtr`].
|
||||||
|
/// If `nil` is returned, the query in a [`View`](crate::lua::ecs::View) will not provide any
|
||||||
|
/// results.\
|
||||||
|
/// If it returns a boolean, the result will act as a filter, and the value will not be in
|
||||||
|
/// the result.\
|
||||||
|
/// Any other value will be included in the result.
|
||||||
|
pub const FN_NAME_INTERNAL_ECS_QUERY_RESULT: &str = "__lyra_internal_ecs_query_result";
|
||||||
|
|
||||||
/// Name of a Lua function implemented for Userdata types that can be made into components.
|
/// Name of a Lua function implemented for Userdata types that can be made into components.
|
||||||
///
|
///
|
||||||
/// This is used for types that can be converted into components. When implementing this function,
|
/// This is used for types that can be converted into components. When implementing this function,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use lyra_ecs::ResourceObject;
|
use lyra_ecs::ResourceObject;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
use crate::{lua::{wrappers::*, LuaContext, LuaWrapper, RegisterLuaType, View, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptApiProvider, ScriptBorrow, ScriptData, ScriptDynamicBundle, ScriptWorldPtr};
|
use crate::{lua::{ecs::{query::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:
|
//fn register_lua_proxy::<T:
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
||||||
// load enums
|
// load enums
|
||||||
let bytes = include_str!("../../../scripts/lua/enums.lua");
|
let bytes = include_str!("../../../scripts/lua/enums.lua");
|
||||||
ctx.load(bytes).exec().unwrap();
|
ctx.load(bytes).exec().unwrap();
|
||||||
|
let bytes = include_str!("../../../scripts/lua/ecs.lua");
|
||||||
|
ctx.load(bytes).exec().unwrap();
|
||||||
|
|
||||||
let globals = ctx.globals();
|
let globals = ctx.globals();
|
||||||
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
||||||
|
@ -43,6 +45,7 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
||||||
globals.set("ActionHandler", ctx.create_proxy::<LuaActionHandler>()?)?;
|
globals.set("ActionHandler", ctx.create_proxy::<LuaActionHandler>()?)?;
|
||||||
globals.set("Window", ctx.create_proxy::<LuaWindow>()?)?;
|
globals.set("Window", ctx.create_proxy::<LuaWindow>()?)?;
|
||||||
globals.set("View", ctx.create_proxy::<View>()?)?;
|
globals.set("View", ctx.create_proxy::<View>()?)?;
|
||||||
|
globals.set("ResQuery", ctx.create_proxy::<LuaResQuery>()?)?;
|
||||||
|
|
||||||
expose_comp_table_wrapper::<LuaCamera>(&ctx, &globals, "Camera")?;
|
expose_comp_table_wrapper::<LuaCamera>(&ctx, &globals, "Camera")?;
|
||||||
expose_comp_table_wrapper::<LuaFreeFlyCamera>(&ctx, &globals, "FreeFlyCamera")?;
|
expose_comp_table_wrapper::<LuaFreeFlyCamera>(&ctx, &globals, "FreeFlyCamera")?;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use lyra_resource::ResourceManager;
|
||||||
use mlua::{IntoLua, ObjectLike};
|
use mlua::{IntoLua, ObjectLike};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
reflect_user_data, wrappers::{LuaResHandleToComponent, LuaWrappedEventProxy}, Error, ReflectLuaProxy, ReflectedIterator, TypeLookup, View, ViewResult, FN_NAME_INTERNAL_AS_COMPONENT, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE
|
reflect_user_data, wrappers::{LuaResHandleToComponent, LuaWrappedEventProxy}, Error, ReflectLuaProxy, ReflectedIterator, TypeLookup, ecs::{View, ViewResult}, FN_NAME_INTERNAL_AS_COMPONENT, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
impl mlua::FromLua for ScriptEntity {
|
impl mlua::FromLua for ScriptEntity {
|
||||||
|
|
Loading…
Reference in New Issue