From 96235522137e6da84f2b396114c4e3e5b204bbd3 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Fri, 15 Apr 2022 19:58:45 -0500 Subject: [PATCH] Little cleanup work --- main.lua | 2 - src/device.rs | 3 +- src/gameobject.rs | 6 +-- src/main.rs | 2 +- src/scripting.rs | 120 +------------------------------------------ src/scripting/lua.rs | 98 +++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 127 deletions(-) create mode 100644 src/scripting/lua.rs diff --git a/main.lua b/main.lua index 1b79be3..c6a3ff3 100644 --- a/main.lua +++ b/main.lua @@ -2,8 +2,6 @@ print("Hello from a lua script!") function init() print("Hello from \"init\"") - couch.debug("init") - couch.say_hello("dane", "Hi!") end function update(delta) diff --git a/src/device.rs b/src/device.rs index 3c251f7..1909889 100644 --- a/src/device.rs +++ b/src/device.rs @@ -28,6 +28,5 @@ impl DeviceManager { } fn update(&mut self, key: Key, state: ElementState) { self.key_map.insert(key, state); - } - + } } diff --git a/src/gameobject.rs b/src/gameobject.rs index 890cc16..5a3bb3d 100644 --- a/src/gameobject.rs +++ b/src/gameobject.rs @@ -18,11 +18,11 @@ pub trait Childbearing { // TODO remove this } impl Node { - pub fn find_node(&mut self, name: &str) -> Option { + pub fn find_node(&self, name: &str) -> Option { self.children .iter() .find(|node| node.borrow().name == name) - .map(|node| Rc::clone(node)) + .map(Rc::clone) } } @@ -36,8 +36,6 @@ macro_rules! impl_childbearing { } } - - impl Node { pub fn new(name: String, gameobject: GameObject) -> Self { Node { diff --git a/src/main.rs b/src/main.rs index c702c46..a79567c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,7 +85,7 @@ fn main() { }; target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0); - let mut root = root.borrow_mut(); + let root = root.borrow(); let cube = root.find_node("cube").unwrap(); let mut cube = cube.borrow_mut(); diff --git a/src/scripting.rs b/src/scripting.rs index 256eef9..1eda5a5 100644 --- a/src/scripting.rs +++ b/src/scripting.rs @@ -1,123 +1,7 @@ -use crate::gameobject::{ Node, Transform }; - -extern crate mlua; -use mlua::Lua as LuaContext; -use mlua::Error::RuntimeError as LuaError; -use mlua::chunk; - -use std::rc::Rc; -use std::cell::RefCell; +mod lua; +pub use lua::Lua; 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) { - 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.get_transform() { - Ok(transform) => Ok(transform), - Err(msg) => Err(LuaError(msg)), - } - }); - methods.add_method_mut("set_transform", |_, this, transform: Transform| { - match this.gameobject.set_transform(transform) { - Ok(()) => Ok(()), - Err(msg) => Err(LuaError(msg)), - } - }); - } -} - -impl<'lua> mlua::ToLua<'lua> for Transform { - fn to_lua(self, ctx: &'lua LuaContext) -> mlua::Result> { - let table = ctx.create_table().unwrap(); - table.set("position", <[f32; 3]>::from(self.position))?; - table.set("rotation", <[f32; 3]>::from(self.rotation))?; - table.set("scale", <[f32; 3]>::from(self.scale))?; - mlua::Result::Ok(mlua::Value::Table(table)) - } -} - -impl<'lua> mlua::FromLua<'lua> for Transform { - fn from_lua(lua_value: mlua::Value<'lua>, _: &'lua LuaContext) -> mlua::Result { - match lua_value { - mlua::Value::Table(table) => { - let position: [f32; 3] = table.get("position")?; - let rotation: [f32; 3] = table.get("rotation")?; - let scale: [f32; 3] = table.get("scale")?; - Ok(Transform { - position: glm::Vec3::from(position), - rotation: glm::Vec3::from(rotation), - scale: glm::Vec3::from(scale), - }) - } - _ => Err(LuaError("Could not convert to Transform".to_string())), - } - } -} - -impl Lua { - pub fn new(root: Rc>) -> 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(()) - } -} diff --git a/src/scripting/lua.rs b/src/scripting/lua.rs new file mode 100644 index 0000000..726fa84 --- /dev/null +++ b/src/scripting/lua.rs @@ -0,0 +1,98 @@ +use super::*; + +use crate::gameobject::{ Node, Transform }; + +extern crate mlua; +use mlua::Lua as LuaContext; +use mlua::Error::RuntimeError as LuaError; +use mlua::chunk; + +use std::rc::Rc; +use std::cell::RefCell; + +pub struct Lua { + ctx: LuaContext, +} + +impl mlua::UserData for Node { + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + 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.get_transform() { + Ok(transform) => Ok(transform), + Err(msg) => Err(LuaError(msg)), + } + }); + methods.add_method_mut("set_transform", |_, this, transform: Transform| { + match this.gameobject.set_transform(transform) { + Ok(()) => Ok(()), + Err(msg) => Err(LuaError(msg)), + } + }); + } +} + +impl<'lua> mlua::ToLua<'lua> for Transform { + fn to_lua(self, ctx: &'lua LuaContext) -> mlua::Result> { + let table = ctx.create_table().unwrap(); + table.set("position", <[f32; 3]>::from(self.position))?; + table.set("rotation", <[f32; 3]>::from(self.rotation))?; + table.set("scale", <[f32; 3]>::from(self.scale))?; + mlua::Result::Ok(mlua::Value::Table(table)) + } +} + +impl<'lua> mlua::FromLua<'lua> for Transform { + fn from_lua(lua_value: mlua::Value<'lua>, _: &'lua LuaContext) -> mlua::Result { + match lua_value { + mlua::Value::Table(table) => { + let position: [f32; 3] = table.get("position")?; + let rotation: [f32; 3] = table.get("rotation")?; + let scale: [f32; 3] = table.get("scale")?; + Ok(Transform { + position: glm::Vec3::from(position), + rotation: glm::Vec3::from(rotation), + scale: glm::Vec3::from(scale), + }) + } + _ => Err(LuaError("Could not convert to Transform".to_string())), + } + } +} + +impl Lua { + pub fn new(root: Rc>) -> 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(); + // 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(); + } +}