engine: lua renderables

master
q3k 2021-04-07 17:27:15 +00:00
parent 8c045ff1f1
commit dd941e3792
7 changed files with 96 additions and 35 deletions

View File

@ -67,6 +67,7 @@ rust_binary(
"//engine/shaders:forward_vert",
"//engine/shaders:forward_frag",
":init.lua",
":scene.lua",
],
)

View File

@ -1,9 +1,4 @@
print("Hello, Lua!")
for k,v in pairs(components) do
print("Lua Component", k, v)
end
local sent = {}
sent = {}
sent.register = function (cfg)
if cfg.name == nil then
error("sent.register: needs name")
@ -39,26 +34,4 @@ sent.register = function (cfg)
end
end
local Test = {}
function Test:init(val)
self.val = val
end
function Test:tick()
print("tick! " .. tostring(self.val))
print("components " .. tostring(self.components))
end
sent.register({
name = "Test",
cls = Test,
components = {
components.Transform.new(0, 0, 0),
},
})
local t1 = Test.new(123)
t1:tick()
local t2 = Test.new(234)
t2:tick()
require("//engine/scene.lua")

22
engine/scene.lua Normal file
View File

@ -0,0 +1,22 @@
local rm = resourcemanager
local cube_mesh = rm.get_mesh("cube")
local cube_material = rm.get_material("test-128px")
local Test = {}
function Test:init()
end
function Test:tick()
end
sent.register({
name = "Test",
cls = Test,
components = {
components.Transform.new(0, 0, 0),
components.Renderable.new_mesh(cube_mesh, cube_material),
},
})
Test.new()

View File

@ -114,7 +114,7 @@ impl Main {
for x in -20..20 {
for y in -20..20 {
for z in -20..20 {
for z in -20..-10 {
world.new_entity()
.with(Transform::at((x as f32)*4.0, (y as f32)*4.0, (z as f32)*4.0))
.with(Renderable::Mesh(mesh, material))

View File

@ -132,8 +132,8 @@ struct RenderableBindings;
impl ComponentLuaBindings for RenderableBindings {
fn globals<'a>(&self, lua: &'a mlua::Lua) -> mlua::Table<'a> {
let res = lua.create_table().unwrap();
res.set("new_mesh", lua.create_function(|_, args: (ResourceID<Mesh>, ResourceID<Light>)| {
Ok(1337)
res.set("new_mesh", lua.create_function(|_, args: (ResourceID<Mesh>, ResourceID<Material>)| {
Ok(Renderable::Mesh(args.0, args.1))
}).unwrap()).unwrap();
res
}

View File

@ -46,14 +46,17 @@ impl Manager {
id
}
pub fn by_label<T: Resource, S: ToString>(&self, label: S) -> Option<&T> {
pub fn by_label<T: Resource, S: ToString>(&self, label: S) -> Option<ResourceID<T>> {
let label = label.to_string();
let numeric = self.label_to_numeric.get(&label)?.clone();
let rid = ResourceID {
numeric,
phantom: std::marker::PhantomData,
};
T::map(self).get(&rid)
if let None = T::map(self).get(&rid) {
return None
}
Some(rid)
}
}
@ -81,7 +84,9 @@ pub struct ResourceID<T: Resource> {
phantom: std::marker::PhantomData<T>,
}
impl <T: Resource> mlua::UserData for ResourceID<T> {}
impl mlua::UserData for ResourceID<Light> {}
impl mlua::UserData for ResourceID<Mesh> {}
impl mlua::UserData for ResourceID<Material> {}
impl <T: Resource> Clone for ResourceID<T> {
fn clone(&self) -> ResourceID<T> {

View File

@ -1,7 +1,12 @@
use std::collections::BTreeMap;
use std::sync::{Arc, Mutex, atomic};
use std::io::Read;
use crate::render;
use crate::util;
use mlua::prelude::LuaError::RuntimeError;
use mlua::ToLua;
fn debug_str(v: &mlua::Value) -> String {
match v {
@ -99,6 +104,23 @@ impl WorldContext {
lua.globals().set("sent", lua.create_table().unwrap()).unwrap();
let loaders = lua.create_table().unwrap();
loaders.set(1, lua.create_function(move |lua, name: String| -> mlua::Result<mlua::Value> {
log::debug!("require({})", name);
let path = name.clone();
match util::file::resource(path.clone()) {
Err(e) => Ok(format!("util::file::resource({}) failed: {:?}", path, e).to_lua(&lua)?),
Ok(mut reader) => {
let mut data: Vec<u8> = Vec::new();
match reader.read_to_end(&mut data) {
Err(e) => Ok(format!("util::file::reasource read failed: {:?}", e).to_lua(&lua)?),
Ok(_) => lua.load(&data).set_name(&path)?.into_function()?.to_lua(&lua),
}
},
}
}).unwrap()).unwrap();
lua.globals().get::<_, mlua::Table>("package").unwrap().set("loaders", loaders).unwrap();
Self {
lua,
classes,
@ -128,6 +150,43 @@ impl WorldContext {
Ok(())
}
/// Registers resourcemanager global in Lua, scoped to scope.
// TODO(q3k): make this generic for all ECS globals.
fn scope_resourcemanager<'a, 'lua, 'scope>(
&self,
scope: &mlua::Scope<'lua, 'scope>,
world: &'a ecs::World,
) -> mlua::Result<()>
where
'a: 'scope
{
let globals = self.lua.globals();
let resourcemanager = self.lua.create_table()?;
globals.set("resourcemanager", resourcemanager.clone());
{
let rm = world.global::<render::resource::Manager>();
let rm = rm.get();
resourcemanager.set("get_mesh", scope.create_function(move |lua, name: String| -> mlua::Result<mlua::Value> {
match rm.by_label::<render::Mesh, _>(&name) {
None => Ok(mlua::Value::Nil),
Some(r) => Ok(r.to_lua(&lua)?),
}
})?)?;
}
{
let rm = world.global::<render::resource::Manager>();
let rm = rm.get();
resourcemanager.set("get_material", scope.create_function(move |lua, name: String| -> mlua::Result<mlua::Value> {
match rm.by_label::<render::Material, _>(&name) {
None => Ok(mlua::Value::Nil),
Some(r) => Ok(r.to_lua(&lua)?),
}
})?)?;
}
Ok(())
}
fn scope_sent<'a, 'lua, 'scope>(
&self,
scope: &mlua::Scope<'lua, 'scope>,
@ -239,6 +298,7 @@ impl WorldContext {
self.lua.scope(|scope| {
self.global_set_components(world)?;
self.scope_sent(scope, world)?;
self.scope_resourcemanager(scope, world)?;
self.lua.load(&val).exec()
})
}