engine: lua renderables
parent
8c045ff1f1
commit
dd941e3792
|
@ -67,6 +67,7 @@ rust_binary(
|
|||
"//engine/shaders:forward_vert",
|
||||
"//engine/shaders:forward_frag",
|
||||
":init.lua",
|
||||
":scene.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")
|
||||
|
|
|
@ -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()
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue