From dd941e37926ab2e7ae0ee7204929dae997d2e5b7 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Wed, 7 Apr 2021 17:27:15 +0000 Subject: [PATCH] engine: lua renderables --- engine/BUILD | 1 + engine/init.lua | 31 ++--------------- engine/scene.lua | 22 ++++++++++++ engine/src/main.rs | 2 +- engine/src/render/renderable.rs | 4 +-- engine/src/render/resource.rs | 11 ++++-- engine/src/scripting.rs | 60 +++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 engine/scene.lua diff --git a/engine/BUILD b/engine/BUILD index 5f6e1df..61f4621 100644 --- a/engine/BUILD +++ b/engine/BUILD @@ -67,6 +67,7 @@ rust_binary( "//engine/shaders:forward_vert", "//engine/shaders:forward_frag", ":init.lua", + ":scene.lua", ], ) diff --git a/engine/init.lua b/engine/init.lua index 0eea2f7..987d9f1 100644 --- a/engine/init.lua +++ b/engine/init.lua @@ -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") diff --git a/engine/scene.lua b/engine/scene.lua new file mode 100644 index 0000000..6a8facf --- /dev/null +++ b/engine/scene.lua @@ -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() diff --git a/engine/src/main.rs b/engine/src/main.rs index 9698bcb..a9145f5 100644 --- a/engine/src/main.rs +++ b/engine/src/main.rs @@ -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)) diff --git a/engine/src/render/renderable.rs b/engine/src/render/renderable.rs index de49e79..237f769 100644 --- a/engine/src/render/renderable.rs +++ b/engine/src/render/renderable.rs @@ -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, ResourceID)| { - Ok(1337) + res.set("new_mesh", lua.create_function(|_, args: (ResourceID, ResourceID)| { + Ok(Renderable::Mesh(args.0, args.1)) }).unwrap()).unwrap(); res } diff --git a/engine/src/render/resource.rs b/engine/src/render/resource.rs index 92dd80b..9172d5a 100644 --- a/engine/src/render/resource.rs +++ b/engine/src/render/resource.rs @@ -46,14 +46,17 @@ impl Manager { id } - pub fn by_label(&self, label: S) -> Option<&T> { + pub fn by_label(&self, label: S) -> Option> { 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 { phantom: std::marker::PhantomData, } -impl mlua::UserData for ResourceID {} +impl mlua::UserData for ResourceID {} +impl mlua::UserData for ResourceID {} +impl mlua::UserData for ResourceID {} impl Clone for ResourceID { fn clone(&self) -> ResourceID { diff --git a/engine/src/scripting.rs b/engine/src/scripting.rs index ea138c4..6bbdc32 100644 --- a/engine/src/scripting.rs +++ b/engine/src/scripting.rs @@ -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 { + 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 = 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::(); + let rm = rm.get(); + resourcemanager.set("get_mesh", scope.create_function(move |lua, name: String| -> mlua::Result { + match rm.by_label::(&name) { + None => Ok(mlua::Value::Nil), + Some(r) => Ok(r.to_lua(&lua)?), + } + })?)?; + } + { + let rm = world.global::(); + let rm = rm.get(); + resourcemanager.set("get_material", scope.create_function(move |lua, name: String| -> mlua::Result { + match rm.by_label::(&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() }) }