93 lines
2.2 KiB
Rust
93 lines
2.2 KiB
Rust
use crate::gameobject::{ Node, Transform, Spatial };
|
|
|
|
extern crate mlua;
|
|
use mlua::Lua as LuaContext;
|
|
use mlua::chunk;
|
|
|
|
use std::rc::Rc;
|
|
use std::cell::RefCell;
|
|
|
|
pub trait ScriptLang {
|
|
fn init(&mut self);
|
|
fn update(&mut self, delta: f32);
|
|
}
|
|
|
|
pub struct Lua {
|
|
ctx: LuaContext,
|
|
}
|
|
|
|
impl mlua::UserData for Node {
|
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
use crate::gameobject::GameObject::*;
|
|
methods.add_method_mut("find_node", |_, this, name: String| {
|
|
let child = this.find_node(&name);
|
|
match child {
|
|
Some(child) => Ok(child),
|
|
None => Err(mlua::Error::RuntimeError("Could not find child".to_string())),
|
|
}
|
|
});
|
|
methods.add_method("get_transform", |_, this, _: ()| {
|
|
match &this.gameobject {
|
|
Mesh(mesh) => Ok(mesh.get_transform()),
|
|
Camera(camera) => Ok(camera.get_transform()),
|
|
_ => Err(mlua::Error::RuntimeError("Node does not implement get_transform".to_string()))
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
impl mlua::UserData for Transform {}
|
|
|
|
impl Lua {
|
|
pub fn new(root: Rc<RefCell<Node>>) -> Self {
|
|
// Create a lua context, load std libraries
|
|
let ctx = LuaContext::new();
|
|
// Create the ``couch'' api
|
|
let couch = ctx.create_table().unwrap();
|
|
couch.set("root", ctx.create_userdata(root).unwrap()).unwrap();
|
|
couch.set("debug", ctx.create_function(debug).unwrap()).unwrap();
|
|
couch.set("say_hello", ctx.create_function(say_hello).unwrap()).unwrap();
|
|
// Hook in to globals
|
|
ctx.globals().set("couch", couch).unwrap();
|
|
let path = std::path::Path::new("main.lua");
|
|
let buf = std::fs::read(&path).expect("Could not find main.lua");
|
|
ctx.load(&buf).exec().unwrap();
|
|
|
|
Lua {
|
|
ctx,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ScriptLang for Lua {
|
|
fn init(&mut self) {
|
|
self.ctx.load(&"init()").exec().ok();
|
|
}
|
|
|
|
fn update(&mut self, delta: f32) {
|
|
self.ctx.load(chunk! {
|
|
update($delta)
|
|
}).exec().ok();
|
|
}
|
|
}
|
|
|
|
macro_rules! luafuncs {
|
|
($($name:ident($($arg:ident: $type: ty),*) $body:block),*) => {
|
|
$(
|
|
fn $name(_: &LuaContext, ($($arg),*,): ($($type),*,)) -> Result<(), mlua::Error> $body
|
|
)*
|
|
};
|
|
}
|
|
|
|
|
|
luafuncs!{
|
|
debug(msg: String) {
|
|
println!("Couch Debug Message: {}", msg);
|
|
Ok(())
|
|
},
|
|
say_hello(name: String, msg: String) {
|
|
println!("Couch says {} to {}", msg, name);
|
|
Ok(())
|
|
}
|
|
}
|