From aadc8e50943c44ebc480d48e865bccd75cb4546e Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sun, 25 Feb 2024 20:53:20 -0500 Subject: [PATCH] scripting: expose all other ActionHandler methods to Lua --- Cargo.lock | 40 ------------ examples/testbed/scripts/test.lua | 20 +++--- lyra-scripting/Cargo.toml | 2 - lyra-scripting/elua | 2 +- lyra-scripting/src/lua/providers/ecs.rs | 1 + lyra-scripting/src/lua/world.rs | 4 +- .../src/lua/wrappers/input_actions.rs | 61 +++++++++++++++---- 7 files changed, 66 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23f32fe..4f54a87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,15 +45,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - [[package]] name = "allocator-api2" version = "0.2.16" @@ -1567,13 +1558,11 @@ dependencies = [ "anyhow", "elua", "itertools 0.12.0", - "lazy_static", "lyra-ecs", "lyra-game", "lyra-reflect", "lyra-resource", "lyra-scripting-derive", - "regex", "thiserror", "tracing", "tracing-subscriber", @@ -2215,35 +2204,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - [[package]] name = "renderdoc-sys" version = "0.7.1" diff --git a/examples/testbed/scripts/test.lua b/examples/testbed/scripts/test.lua index d7b91f7..65a8460 100644 --- a/examples/testbed/scripts/test.lua +++ b/examples/testbed/scripts/test.lua @@ -7,7 +7,7 @@ function on_init() local e = world:spawn(pos, cube) print("spawned entity " .. tostring(e)) - local action_handler_tbl = { + local handler = ActionHandler.new { layouts = { 0 }, actions = { MoveForwardBackward = "Axis", @@ -16,6 +16,7 @@ function on_init() LookLeftRight = "Axis", LookUpDown = "Axis", LookRoll = "Axis", + ObjectsMoveUpDown = "Axis" }, mappings = { { @@ -40,13 +41,15 @@ function on_init() }, LookRoll = { "key:e=-1.0", "key:q=1.0", + }, + ObjectsMoveUpDown = { + "key:u=1.0", "key:j=-1.0" } } } } } - local handler = ActionHandler.new(action_handler_tbl) world:add_resource(handler) end @@ -61,15 +64,16 @@ end ]] function on_update() ---@type number local dt = world:resource(DeltaTime) + local act = world:resource(ActionHandler) + ---@type number + local move_objs = act:get_axis("ObjectsMoveUpDown") world:view(function (t) - t:translate(0, 0.5 * dt, 0) - - return t + if move_objs ~= nil then + t:translate(0, move_objs * 0.35 * dt, 0) + return t + end end, Transform) - - --local input = world:resource(Input) - --input. end --[[ function on_post_update() diff --git a/lyra-scripting/Cargo.toml b/lyra-scripting/Cargo.toml index 3582afd..2782c56 100644 --- a/lyra-scripting/Cargo.toml +++ b/lyra-scripting/Cargo.toml @@ -23,8 +23,6 @@ tracing = "0.1.37" #mlua = { version = "0.9.2", features = ["lua54"], optional = true } # luajit maybe? elua = { path = "./elua", optional = true } itertools = "0.12.0" -regex = "1.10.3" -lazy_static = "1.4.0" [dev-dependencies] diff --git a/lyra-scripting/elua b/lyra-scripting/elua index beea6c3..936ea60 160000 --- a/lyra-scripting/elua +++ b/lyra-scripting/elua @@ -1 +1 @@ -Subproject commit beea6c33fcb2f5bd16f40e1919b61a89b4aaecb6 +Subproject commit 936ea606343dbcf5321b4b988de65daf8769ff3f diff --git a/lyra-scripting/src/lua/providers/ecs.rs b/lyra-scripting/src/lua/providers/ecs.rs index edcb4ae..7982271 100644 --- a/lyra-scripting/src/lua/providers/ecs.rs +++ b/lyra-scripting/src/lua/providers/ecs.rs @@ -12,6 +12,7 @@ impl ScriptApiProvider for LyraEcsApiProvider { fn prepare_world(&mut self, world: &mut lyra_ecs::World) { world.register_lua_convert::(); world.register_lua_wrapper::(); + world.register_lua_wrapper::(); } fn expose_api(&mut self, _: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { diff --git a/lyra-scripting/src/lua/world.rs b/lyra-scripting/src/lua/world.rs index 1e1a03a..1cec468 100644 --- a/lyra-scripting/src/lua/world.rs +++ b/lyra-scripting/src/lua/world.rs @@ -1,7 +1,7 @@ use std::{ptr::NonNull, sync::Arc}; use crate::{ScriptBorrow, ScriptEntity, ScriptWorldPtr}; -use elua::{AnyUserdata, AsLua, Table}; +use elua::AsLua; use lyra_ecs::{query::dynamic::QueryDynamicType, CommandQueue, Commands, DynamicBundle, World}; use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry}; use lyra_resource::ResourceManager; @@ -268,7 +268,7 @@ impl elua::Userdata for ScriptWorldPtr { let reg_type = this .as_ref() .get_type::(reflect.reflect_branch.reflect_type_id()) - .unwrap(); + .expect("Resource is not type registered!"); let proxy = reg_type .get_data::() .expect("Type does not have ReflectLuaProxy as a TypeData"); diff --git a/lyra-scripting/src/lua/wrappers/input_actions.rs b/lyra-scripting/src/lua/wrappers/input_actions.rs index 9325280..ee393ad 100644 --- a/lyra-scripting/src/lua/wrappers/input_actions.rs +++ b/lyra-scripting/src/lua/wrappers/input_actions.rs @@ -1,15 +1,11 @@ -use lyra_game::input::{keycode_from_str, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, LayoutId, MouseAxis, MouseInput}; +use lyra_game::input::{keycode_from_str, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, ActionState, LayoutId, MouseAxis, MouseInput}; +use crate::lyra_engine; -use lazy_static::lazy_static; -use regex::Regex; +use lyra_reflect::Reflect; -use crate::{lua::{FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptBorrow}; +use crate::{lua::{LuaWrapper, FN_NAME_INTERNAL_REFLECT, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptBorrow}; -lazy_static! { - static ref BINDING_INPUT_RE: Regex = Regex::new(r"(\w+):(\w+)(?:=(-?\d+(?:.\d+)?))?").unwrap(); -} - -#[derive(Clone)] +#[derive(Clone, Reflect)] pub struct LuaActionHandler { handler: ActionHandler } @@ -23,7 +19,7 @@ impl elua::Userdata for LuaActionHandler { builder.function("new", |_, table: elua::Table| { let mut handler = ActionHandler::new(); - // create the layouts + // create the layouts and add them to the handler let layouts = table.get::<_, elua::Table>("layouts") .map_err(|_| elua::Error::runtime("missing 'layouts' in ActionHandler table"))?; for layout_id in layouts.sequence_iter::() { @@ -32,6 +28,7 @@ impl elua::Userdata for LuaActionHandler { handler.add_layout(LayoutId(layout_id)); } + // add the actions to the handler let actions = table.get::<_, elua::Table>("actions") .map_err(|_| elua::Error::runtime("missing 'actions' in ActionHandler table"))?; for pair in actions.pairs::() { @@ -47,6 +44,7 @@ impl elua::Userdata for LuaActionHandler { handler.add_action(action_lbl, Action::new(action_type)); } + // find the mappings and start processing them let mappings= table.get::<_, elua::Table>("mappings") .map_err(|_| elua::Error::runtime("missing 'mappings' in ActionHandler table"))?; for (map_id, tbl) in mappings.sequence_iter::().enumerate() { @@ -55,6 +53,8 @@ impl elua::Userdata for LuaActionHandler { let layout_id = tbl.get::<_, u32>("layout")?; let mut mapping = ActionMapping::new(LayoutId(layout_id), ActionMappingId(map_id as u32)); + // find the binds and start processing them + // the keys are used as the action names, and then the value is an array (lua table) let binds_tbl = tbl.get::<_, elua::Table>("binds") .map_err(|_| elua::Error::runtime("missing 'binds' in ActionHandler 'mappings' table"))?; for pair in binds_tbl.pairs::() { @@ -106,10 +106,43 @@ impl elua::Userdata for LuaActionHandler { handler, }) }) + .method("get_axis", |_, this, action: String| { + Ok(this.handler.get_axis_modifier(action)) + }) + .method("is_pressed", |_, this, action: String| { + Ok(this.handler.is_action_pressed(action)) + }) + .method("was_just_pressed", |_, this, action: String| { + Ok(this.handler.was_action_just_pressed(action)) + }) + .method("was_just_released", |_, this, action: String| { + Ok(this.handler.was_action_just_released(action)) + }) + .method("get_just_pressed", |_, this, action: String| { + Ok(this.handler.get_just_pressed_modifier(action)) + }) + .method("get_action_state", |lua, this, action: String| { + let state = this.handler.get_action_state(action); + + let (name, val) = match state { + ActionState::Idle => ("Idle", None), + ActionState::Pressed(v) => ("Pressed", Some(v)), + ActionState::JustPressed(v) => ("JustPressed", Some(v)), + ActionState::JustReleased => ("JustReleased", None), + ActionState::Axis(v) => ("Axis", Some(v)), + ActionState::Other(v) => ("Other", Some(v)), + }; + + let mut multi = elua::ValueVec::new(); + multi.push_val(lua, name)?; + multi.push_val(lua, val)?; + + Ok(elua::Value::Multi(multi)) + }) .method(FN_NAME_INTERNAL_REFLECT, |_, this, ()| { Ok(ScriptBorrow::from_resource::(Some(this.handler.clone()))) }) - .method(FN_NAME_INTERNAL_REFLECT_TYPE, |_, _, ()| { + .function(FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| { Ok(ScriptBorrow::from_resource::(None)) }); @@ -128,6 +161,12 @@ impl<'a> elua::FromLua<'a> for LuaActionHandler { } } +impl LuaWrapper for LuaActionHandler { + fn wrapped_type_id() -> std::any::TypeId { + std::any::TypeId::of::() + } +} + fn process_keyboard_string(key_name: &str) -> Option { let key = keycode_from_str(key_name)?;