Compare commits
No commits in common. "5521d4a65931fc65fc6c6e2e60b73a007cf2e404" and "388f686917812b215a9fe8896d3e8e70a599ce00" have entirely different histories.
5521d4a659
...
388f686917
16 changed files with 59 additions and 572 deletions
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -45,15 +45,6 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "1.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
|
@ -1567,13 +1558,11 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"elua",
|
"elua",
|
||||||
"itertools 0.12.0",
|
"itertools 0.12.0",
|
||||||
"lazy_static",
|
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
"lyra-game",
|
"lyra-game",
|
||||||
"lyra-reflect",
|
"lyra-reflect",
|
||||||
"lyra-resource",
|
"lyra-resource",
|
||||||
"lyra-scripting-derive",
|
"lyra-scripting-derive",
|
||||||
"regex",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
@ -2215,35 +2204,6 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"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]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
|
|
@ -6,48 +6,6 @@ function on_init()
|
||||||
|
|
||||||
local e = world:spawn(pos, cube)
|
local e = world:spawn(pos, cube)
|
||||||
print("spawned entity " .. tostring(e))
|
print("spawned entity " .. tostring(e))
|
||||||
|
|
||||||
local action_handler_tbl = {
|
|
||||||
layouts = { 0 },
|
|
||||||
actions = {
|
|
||||||
MoveForwardBackward = "Axis",
|
|
||||||
MoveLeftRight = "Axis",
|
|
||||||
MoveUpDown = "Axis",
|
|
||||||
LookLeftRight = "Axis",
|
|
||||||
LookUpDown = "Axis",
|
|
||||||
LookRoll = "Axis",
|
|
||||||
},
|
|
||||||
mappings = {
|
|
||||||
{
|
|
||||||
layout = 0,
|
|
||||||
binds = {
|
|
||||||
MoveForwardBackward = {
|
|
||||||
"key:w=1.0", "key:s=-1.0"
|
|
||||||
},
|
|
||||||
MoveLeftRight = {
|
|
||||||
"key:a=-1.0", "key:d=1.0"
|
|
||||||
},
|
|
||||||
MoveUpDown = {
|
|
||||||
"key:c=1.0", "key:z=-1.0"
|
|
||||||
},
|
|
||||||
LookLeftRight = {
|
|
||||||
"key:left=-1.0", "key:right=1.0",
|
|
||||||
"mouse:axis:x"
|
|
||||||
},
|
|
||||||
LookUpDown = {
|
|
||||||
"key:up=-1.0", "key:down=1.0",
|
|
||||||
"mouse:axis:y",
|
|
||||||
},
|
|
||||||
LookRoll = {
|
|
||||||
"key:e=-1.0", "key:q=1.0",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
local handler = ActionHandler.new(action_handler_tbl)
|
|
||||||
world:add_resource(handler)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ function on_first()
|
--[[ function on_first()
|
||||||
|
@ -67,9 +25,6 @@ function on_update()
|
||||||
|
|
||||||
return t
|
return t
|
||||||
end, Transform)
|
end, Transform)
|
||||||
|
|
||||||
--local input = world:resource(Input)
|
|
||||||
--input.
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ function on_post_update()
|
--[[ function on_post_update()
|
||||||
|
|
|
@ -240,7 +240,7 @@ async fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let action_handler_plugin = |game: &mut Game| {
|
let action_handler_plugin = |game: &mut Game| {
|
||||||
/* let action_handler = ActionHandler::builder()
|
let action_handler = ActionHandler::new()
|
||||||
.add_layout(LayoutId::from(0))
|
.add_layout(LayoutId::from(0))
|
||||||
|
|
||||||
.add_action(CommonActionLabel::MoveForwardBackward, Action::new(ActionKind::Axis))
|
.add_action(CommonActionLabel::MoveForwardBackward, Action::new(ActionKind::Axis))
|
||||||
|
@ -250,7 +250,7 @@ async fn main() {
|
||||||
.add_action(CommonActionLabel::LookUpDown, Action::new(ActionKind::Axis))
|
.add_action(CommonActionLabel::LookUpDown, Action::new(ActionKind::Axis))
|
||||||
.add_action(CommonActionLabel::LookRoll, Action::new(ActionKind::Axis))
|
.add_action(CommonActionLabel::LookRoll, Action::new(ActionKind::Axis))
|
||||||
|
|
||||||
.add_mapping(ActionMapping::builder(LayoutId::from(0), ActionMappingId::from(0))
|
.add_mapping(ActionMapping::new(LayoutId::from(0), ActionMappingId::from(0))
|
||||||
.bind(CommonActionLabel::MoveForwardBackward, &[
|
.bind(CommonActionLabel::MoveForwardBackward, &[
|
||||||
ActionSource::Keyboard(KeyCode::W).into_binding_modifier(1.0),
|
ActionSource::Keyboard(KeyCode::W).into_binding_modifier(1.0),
|
||||||
ActionSource::Keyboard(KeyCode::S).into_binding_modifier(-1.0)
|
ActionSource::Keyboard(KeyCode::S).into_binding_modifier(-1.0)
|
||||||
|
@ -282,9 +282,22 @@ async fn main() {
|
||||||
.finish()
|
.finish()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* #[allow(unused_variables)]
|
||||||
|
let test_system = |world: &mut World| -> anyhow::Result<()> {
|
||||||
|
let handler = world.get_resource::<ActionHandler>();
|
||||||
|
|
||||||
|
if let Some(alpha) = handler.get_axis_modifier("look_rotate") {
|
||||||
|
debug!("'look_rotate': {alpha}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}; */
|
||||||
|
|
||||||
let world = game.world_mut();
|
let world = game.world_mut();
|
||||||
world.add_resource(action_handler);
|
world.add_resource(action_handler);
|
||||||
game.with_plugin(InputActionPlugin); */
|
world.spawn((Vec3::new(0.5, 0.1, 3.0),));
|
||||||
|
game.with_plugin(InputActionPlugin);
|
||||||
|
//game.with_system("input_test", test_system, &[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let script_test_plugin = |game: &mut Game| {
|
let script_test_plugin = |game: &mut Game| {
|
||||||
|
@ -309,6 +322,6 @@ async fn main() {
|
||||||
.with_plugin(script_test_plugin)
|
.with_plugin(script_test_plugin)
|
||||||
//.with_plugin(fps_plugin)
|
//.with_plugin(fps_plugin)
|
||||||
.with_plugin(jiggle_plugin)
|
.with_plugin(jiggle_plugin)
|
||||||
//.with_plugin(FreeFlyCameraPlugin)
|
.with_plugin(FreeFlyCameraPlugin)
|
||||||
.run().await;
|
.run().await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,8 +255,7 @@ impl World {
|
||||||
/// Will panic if the resource is not in the world. See [`try_get_resource`] for
|
/// Will panic if the resource is not in the world. See [`try_get_resource`] for
|
||||||
/// a function that returns an option.
|
/// a function that returns an option.
|
||||||
pub fn get_resource<T: 'static>(&self) -> Ref<T> {
|
pub fn get_resource<T: 'static>(&self) -> Ref<T> {
|
||||||
self.resources.get(&TypeId::of::<T>())
|
self.resources.get(&TypeId::of::<T>()).unwrap()
|
||||||
.expect(&format!("World is missing resource of type '{}'", std::any::type_name::<T>()))
|
|
||||||
.get()
|
.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,8 +277,7 @@ impl World {
|
||||||
/// Will panic if the resource is not in the world. See [`try_get_resource_mut`] for
|
/// Will panic if the resource is not in the world. See [`try_get_resource_mut`] for
|
||||||
/// a function that returns an option.
|
/// a function that returns an option.
|
||||||
pub fn get_resource_mut<T: 'static>(&self) -> RefMut<T> {
|
pub fn get_resource_mut<T: 'static>(&self) -> RefMut<T> {
|
||||||
self.resources.get(&TypeId::of::<T>())
|
self.resources.get(&TypeId::of::<T>()).unwrap()
|
||||||
.expect(&format!("World is missing resource of type '{}'", std::any::type_name::<T>()))
|
|
||||||
.get_mut()
|
.get_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std::{collections::HashMap, ops::Deref, hash::{Hash, DefaultHasher, Hasher},
|
||||||
|
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use lyra_ecs::world::World;
|
use lyra_ecs::world::World;
|
||||||
use lyra_reflect::Reflect;
|
|
||||||
|
|
||||||
use crate::{plugin::Plugin, game::GameStages, EventQueue};
|
use crate::{plugin::Plugin, game::GameStages, EventQueue};
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ impl Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct LayoutId(pub u32);
|
pub struct LayoutId(u32);
|
||||||
|
|
||||||
impl From<u32> for LayoutId {
|
impl From<u32> for LayoutId {
|
||||||
fn from(value: u32) -> Self {
|
fn from(value: u32) -> Self {
|
||||||
|
@ -241,7 +240,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct ActionMappingId(pub u32);
|
pub struct ActionMappingId(u32);
|
||||||
|
|
||||||
impl From<u32> for ActionMappingId {
|
impl From<u32> for ActionMappingId {
|
||||||
fn from(value: u32) -> Self {
|
fn from(value: u32) -> Self {
|
||||||
|
@ -265,10 +264,6 @@ impl ActionMapping {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn builder(layout: LayoutId, id: ActionMappingId) -> ActionMappingBuilder {
|
|
||||||
ActionMappingBuilder::new(ActionMapping::new(layout, id))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a binding for the action.
|
/// Creates a binding for the action.
|
||||||
///
|
///
|
||||||
/// If the action is not in this layout, this will panic!
|
/// If the action is not in this layout, this will panic!
|
||||||
|
@ -276,7 +271,7 @@ impl ActionMapping {
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
/// * `action` - The label corresponding to the action in this Layout.
|
/// * `action` - The label corresponding to the action in this Layout.
|
||||||
/// * `bind` - The Binding to add to the Action.
|
/// * `bind` - The Binding to add to the Action.
|
||||||
pub fn bind<L>(&mut self, action: L, bindings: &[Binding]) -> &mut Self
|
pub fn bind<L>(mut self, action: L, bindings: &[Binding]) -> Self
|
||||||
where
|
where
|
||||||
L: ActionLabel
|
L: ActionLabel
|
||||||
{
|
{
|
||||||
|
@ -288,48 +283,32 @@ impl ActionMapping {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates multiple binding for the action.
|
||||||
|
///
|
||||||
|
/// If the action is not in this layout, this will panic!
|
||||||
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// * `action_label` - The label corresponding to the action in this Layout.
|
||||||
|
/// * `bindings` - The list of Bindings to add to the Action.
|
||||||
|
/* pub fn add_bindings(&mut self, action_label: String, bindings: &[Binding]) -> &mut Self {
|
||||||
|
let mut bindings = bindings.to_vec();
|
||||||
|
let action_binds = self.action_binds.entry(action_label)
|
||||||
|
.or_insert_with(Vec::new);
|
||||||
|
action_binds.append(&mut bindings);
|
||||||
|
|
||||||
|
self
|
||||||
|
} */
|
||||||
|
|
||||||
pub fn finish(self) -> Self {
|
pub fn finish(self) -> Self {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActionMappingBuilder {
|
#[derive(Clone, Default)]
|
||||||
mapping: ActionMapping,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActionMappingBuilder {
|
|
||||||
fn new(mapping: ActionMapping) -> Self {
|
|
||||||
Self {
|
|
||||||
mapping,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bind<L>(mut self, action: L, bindings: &[Binding]) -> Self
|
|
||||||
where
|
|
||||||
L: ActionLabel
|
|
||||||
{
|
|
||||||
let mut bindings = bindings.to_vec();
|
|
||||||
|
|
||||||
let action_binds = self.mapping.action_binds.entry(action.label_hash()).or_default();
|
|
||||||
action_binds.append(&mut bindings);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn finish(self) -> ActionMapping {
|
|
||||||
self.mapping
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Reflect)]
|
|
||||||
pub struct ActionHandler {
|
pub struct ActionHandler {
|
||||||
#[reflect(skip)] // TODO: dont just skip all these
|
|
||||||
pub actions: HashMap<u64, Action>,
|
pub actions: HashMap<u64, Action>,
|
||||||
#[reflect(skip)]
|
|
||||||
pub layouts: HashMap<LayoutId, Layout>,
|
pub layouts: HashMap<LayoutId, Layout>,
|
||||||
#[reflect(skip)]
|
|
||||||
pub current_layout: LayoutId,
|
pub current_layout: LayoutId,
|
||||||
#[reflect(skip)]
|
|
||||||
pub current_mapping: ActionMappingId,
|
pub current_mapping: ActionMappingId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,31 +317,26 @@ impl ActionHandler {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn builder() -> ActionHandlerBuilder {
|
pub fn add_layout(mut self, id: LayoutId) -> Self {
|
||||||
ActionHandlerBuilder::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_layout(&mut self, id: LayoutId) {
|
|
||||||
self.layouts.insert(id, Layout::new());
|
self.layouts.insert(id, Layout::new());
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action<L>(&self, label: L) -> Option<&Action>
|
pub fn add_action<L>(mut self, label: L, action: Action) -> Self
|
||||||
where
|
|
||||||
L: ActionLabel
|
|
||||||
{
|
|
||||||
self.actions.get(&label.label_hash())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_action<L>(&mut self, label: L, action: Action)
|
|
||||||
where
|
where
|
||||||
L: ActionLabel
|
L: ActionLabel
|
||||||
{
|
{
|
||||||
self.actions.insert(label.label_hash(), action);
|
self.actions.insert(label.label_hash(), action);
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_mapping(&mut self, mapping: ActionMapping) {
|
pub fn add_mapping(mut self, mapping: ActionMapping) -> Self {
|
||||||
let layout = self.layouts.get_mut(&mapping.layout).unwrap();
|
let layout = self.layouts.get_mut(&mapping.layout).unwrap();
|
||||||
layout.add_mapping(mapping);
|
layout.add_mapping(mapping);
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the action is pressed (or was just pressed).
|
/// Returns true if the action is pressed (or was just pressed).
|
||||||
|
@ -469,43 +443,6 @@ impl ActionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ActionHandlerBuilder {
|
|
||||||
handler: ActionHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActionHandlerBuilder {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_layout(mut self, id: LayoutId) -> Self {
|
|
||||||
self.handler.layouts.insert(id, Layout::new());
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_action<L>(mut self, label: L, action: Action) -> Self
|
|
||||||
where
|
|
||||||
L: ActionLabel
|
|
||||||
{
|
|
||||||
self.handler.actions.insert(label.label_hash(), action);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_mapping(mut self, mapping: ActionMapping) -> Self {
|
|
||||||
let layout = self.handler.layouts.get_mut(&mapping.layout).unwrap();
|
|
||||||
layout.add_mapping(mapping);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn finish(self) -> ActionHandler {
|
|
||||||
self.handler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn actions_system(world: &mut World) -> anyhow::Result<()> {
|
fn actions_system(world: &mut World) -> anyhow::Result<()> {
|
||||||
let keys = world.try_get_resource::<InputButtons<KeyCode>>()
|
let keys = world.try_get_resource::<InputButtons<KeyCode>>()
|
||||||
.map(|r| r.deref().clone());
|
.map(|r| r.deref().clone());
|
||||||
|
|
|
@ -12,181 +12,3 @@ pub use buttons::*;
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub use action::*;
|
pub use action::*;
|
||||||
|
|
||||||
pub type KeyCode = winit::event::VirtualKeyCode;
|
|
||||||
|
|
||||||
/// Parses a [`KeyCode`] from a [`&str`].
|
|
||||||
///
|
|
||||||
/// There are some changes to a few keycodes. All the number keys `Key1`, `Key2`, etc., have
|
|
||||||
/// the `Key` prefix removed; so they are expected to be `1`, `2`, etc.
|
|
||||||
pub fn keycode_from_str(s: &str) -> Option<KeyCode> {
|
|
||||||
let s = s.to_lowercase();
|
|
||||||
let s = s.as_str();
|
|
||||||
|
|
||||||
match s {
|
|
||||||
"1" => Some(KeyCode::Key1),
|
|
||||||
"2" => Some(KeyCode::Key2),
|
|
||||||
"3" => Some(KeyCode::Key3),
|
|
||||||
"4" => Some(KeyCode::Key4),
|
|
||||||
"5" => Some(KeyCode::Key5),
|
|
||||||
"6" => Some(KeyCode::Key6),
|
|
||||||
"7" => Some(KeyCode::Key7),
|
|
||||||
"8" => Some(KeyCode::Key8),
|
|
||||||
"9" => Some(KeyCode::Key9),
|
|
||||||
"0" => Some(KeyCode::Key0),
|
|
||||||
"a" => Some(KeyCode::A),
|
|
||||||
"b" => Some(KeyCode::B),
|
|
||||||
"c" => Some(KeyCode::C),
|
|
||||||
"d" => Some(KeyCode::D),
|
|
||||||
"e" => Some(KeyCode::E),
|
|
||||||
"f" => Some(KeyCode::F),
|
|
||||||
"g" => Some(KeyCode::G),
|
|
||||||
"h" => Some(KeyCode::H),
|
|
||||||
"i" => Some(KeyCode::I),
|
|
||||||
"j" => Some(KeyCode::J),
|
|
||||||
"k" => Some(KeyCode::K),
|
|
||||||
"l" => Some(KeyCode::L),
|
|
||||||
"m" => Some(KeyCode::M),
|
|
||||||
"n" => Some(KeyCode::N),
|
|
||||||
"o" => Some(KeyCode::O),
|
|
||||||
"p" => Some(KeyCode::P),
|
|
||||||
"q" => Some(KeyCode::Q),
|
|
||||||
"r" => Some(KeyCode::R),
|
|
||||||
"s" => Some(KeyCode::S),
|
|
||||||
"t" => Some(KeyCode::T),
|
|
||||||
"u" => Some(KeyCode::U),
|
|
||||||
"v" => Some(KeyCode::V),
|
|
||||||
"w" => Some(KeyCode::W),
|
|
||||||
"x" => Some(KeyCode::X),
|
|
||||||
"y" => Some(KeyCode::Y),
|
|
||||||
"z" => Some(KeyCode::Z),
|
|
||||||
"escape" => Some(KeyCode::Escape),
|
|
||||||
"f1" => Some(KeyCode::F1),
|
|
||||||
"f2" => Some(KeyCode::F2),
|
|
||||||
"f3" => Some(KeyCode::F3),
|
|
||||||
"f4" => Some(KeyCode::F4),
|
|
||||||
"f5" => Some(KeyCode::F5),
|
|
||||||
"f6" => Some(KeyCode::F6),
|
|
||||||
"f7" => Some(KeyCode::F7),
|
|
||||||
"f8" => Some(KeyCode::F8),
|
|
||||||
"f9" => Some(KeyCode::F9),
|
|
||||||
"f10" => Some(KeyCode::F10),
|
|
||||||
"f11" => Some(KeyCode::F11),
|
|
||||||
"f12" => Some(KeyCode::F12),
|
|
||||||
"f13" => Some(KeyCode::F13),
|
|
||||||
"f14" => Some(KeyCode::F14),
|
|
||||||
"f15" => Some(KeyCode::F15),
|
|
||||||
"f16" => Some(KeyCode::F16),
|
|
||||||
"f17" => Some(KeyCode::F17),
|
|
||||||
"f18" => Some(KeyCode::F18),
|
|
||||||
"f19" => Some(KeyCode::F19),
|
|
||||||
"f20" => Some(KeyCode::F20),
|
|
||||||
"f21" => Some(KeyCode::F21),
|
|
||||||
"f22" => Some(KeyCode::F22),
|
|
||||||
"f23" => Some(KeyCode::F23),
|
|
||||||
"f24" => Some(KeyCode::F24),
|
|
||||||
"snapshot" => Some(KeyCode::Snapshot),
|
|
||||||
"scroll" => Some(KeyCode::Scroll),
|
|
||||||
"pause" => Some(KeyCode::Pause),
|
|
||||||
"insert" => Some(KeyCode::Insert),
|
|
||||||
"home" => Some(KeyCode::Home),
|
|
||||||
"delete" => Some(KeyCode::Delete),
|
|
||||||
"end" => Some(KeyCode::End),
|
|
||||||
"pagedown" => Some(KeyCode::PageDown),
|
|
||||||
"pageup" => Some(KeyCode::PageUp),
|
|
||||||
"left" => Some(KeyCode::Left),
|
|
||||||
"up" => Some(KeyCode::Up),
|
|
||||||
"right" => Some(KeyCode::Right),
|
|
||||||
"down" => Some(KeyCode::Down),
|
|
||||||
"back" => Some(KeyCode::Back),
|
|
||||||
"return" => Some(KeyCode::Return),
|
|
||||||
"space" => Some(KeyCode::Space),
|
|
||||||
"compose" => Some(KeyCode::Compose),
|
|
||||||
"caret" => Some(KeyCode::Caret),
|
|
||||||
"numlock" => Some(KeyCode::Numlock),
|
|
||||||
"numpad0" => Some(KeyCode::Numpad0),
|
|
||||||
"numpad1" => Some(KeyCode::Numpad1),
|
|
||||||
"numpad2" => Some(KeyCode::Numpad2),
|
|
||||||
"numpad3" => Some(KeyCode::Numpad3),
|
|
||||||
"numpad4" => Some(KeyCode::Numpad4),
|
|
||||||
"numpad5" => Some(KeyCode::Numpad5),
|
|
||||||
"numpad6" => Some(KeyCode::Numpad6),
|
|
||||||
"numpad7" => Some(KeyCode::Numpad7),
|
|
||||||
"numpad8" => Some(KeyCode::Numpad8),
|
|
||||||
"numpad9" => Some(KeyCode::Numpad9),
|
|
||||||
"numpadadd" => Some(KeyCode::NumpadAdd),
|
|
||||||
"numpaddivide" => Some(KeyCode::NumpadDivide),
|
|
||||||
"numpaddecimal" => Some(KeyCode::NumpadDecimal),
|
|
||||||
"numpadcomma" => Some(KeyCode::NumpadComma),
|
|
||||||
"numpadenter" => Some(KeyCode::NumpadEnter),
|
|
||||||
"numpadequals" => Some(KeyCode::NumpadEquals),
|
|
||||||
"numpadmultiply" => Some(KeyCode::NumpadMultiply),
|
|
||||||
"numpadsubtract" => Some(KeyCode::NumpadSubtract),
|
|
||||||
"abntc1" => Some(KeyCode::AbntC1),
|
|
||||||
"abntc2" => Some(KeyCode::AbntC2),
|
|
||||||
"apostrophe" => Some(KeyCode::Apostrophe),
|
|
||||||
"apps" => Some(KeyCode::Apps),
|
|
||||||
"asterisk" => Some(KeyCode::Asterisk),
|
|
||||||
"at" => Some(KeyCode::At),
|
|
||||||
"ax" => Some(KeyCode::Ax),
|
|
||||||
"backslash" => Some(KeyCode::Backslash),
|
|
||||||
"calculator" => Some(KeyCode::Calculator),
|
|
||||||
"capital" => Some(KeyCode::Capital),
|
|
||||||
"colon" => Some(KeyCode::Colon),
|
|
||||||
"comma" => Some(KeyCode::Comma),
|
|
||||||
"convert" => Some(KeyCode::Convert),
|
|
||||||
"equals" => Some(KeyCode::Equals),
|
|
||||||
"grave" => Some(KeyCode::Grave),
|
|
||||||
"kana" => Some(KeyCode::Kana),
|
|
||||||
"kanji" => Some(KeyCode::Kanji),
|
|
||||||
"lalt" => Some(KeyCode::LAlt),
|
|
||||||
"lbracket" => Some(KeyCode::LBracket),
|
|
||||||
"lcontrol" => Some(KeyCode::LControl),
|
|
||||||
"lshift" => Some(KeyCode::LShift),
|
|
||||||
"lwin" => Some(KeyCode::LWin),
|
|
||||||
"mail" => Some(KeyCode::Mail),
|
|
||||||
"mediaselect" => Some(KeyCode::MediaSelect),
|
|
||||||
"mediastop" => Some(KeyCode::MediaStop),
|
|
||||||
"minus" => Some(KeyCode::Minus),
|
|
||||||
"mute" => Some(KeyCode::Mute),
|
|
||||||
"mycomputer" => Some(KeyCode::MyComputer),
|
|
||||||
"navigateforward" => Some(KeyCode::NavigateForward),
|
|
||||||
"navigatebackward" => Some(KeyCode::NavigateBackward),
|
|
||||||
"nexttrack" => Some(KeyCode::NextTrack),
|
|
||||||
"noconvert" => Some(KeyCode::NoConvert),
|
|
||||||
"oem102" => Some(KeyCode::OEM102),
|
|
||||||
"period" => Some(KeyCode::Period),
|
|
||||||
"playpause" => Some(KeyCode::PlayPause),
|
|
||||||
"plus" => Some(KeyCode::Plus),
|
|
||||||
"power" => Some(KeyCode::Power),
|
|
||||||
"prevtrack" => Some(KeyCode::PrevTrack),
|
|
||||||
"ralt" => Some(KeyCode::RAlt),
|
|
||||||
"rbracket" => Some(KeyCode::RBracket),
|
|
||||||
"rcontrol" => Some(KeyCode::RControl),
|
|
||||||
"rshift" => Some(KeyCode::RShift),
|
|
||||||
"rwin" => Some(KeyCode::RWin),
|
|
||||||
"semicolon" => Some(KeyCode::Semicolon),
|
|
||||||
"slash" => Some(KeyCode::Slash),
|
|
||||||
"sleep" => Some(KeyCode::Sleep),
|
|
||||||
"stop" => Some(KeyCode::Stop),
|
|
||||||
"sysrq" => Some(KeyCode::Sysrq),
|
|
||||||
"tab" => Some(KeyCode::Tab),
|
|
||||||
"underline" => Some(KeyCode::Underline),
|
|
||||||
"unlabeled" => Some(KeyCode::Unlabeled),
|
|
||||||
"volumedown" => Some(KeyCode::VolumeDown),
|
|
||||||
"volumeup" => Some(KeyCode::VolumeUp),
|
|
||||||
"wake" => Some(KeyCode::Wake),
|
|
||||||
"webback" => Some(KeyCode::WebBack),
|
|
||||||
"webfavorites" => Some(KeyCode::WebFavorites),
|
|
||||||
"webforward" => Some(KeyCode::WebForward),
|
|
||||||
"webhome" => Some(KeyCode::WebHome),
|
|
||||||
"webrefresh" => Some(KeyCode::WebRefresh),
|
|
||||||
"websearch" => Some(KeyCode::WebSearch),
|
|
||||||
"webstop" => Some(KeyCode::WebStop),
|
|
||||||
"yen" => Some(KeyCode::Yen),
|
|
||||||
"copy" => Some(KeyCode::Copy),
|
|
||||||
"paste" => Some(KeyCode::Paste),
|
|
||||||
"cut" => Some(KeyCode::Cut),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,8 @@ use crate::{EventQueue, plugin::Plugin, game::GameStages};
|
||||||
|
|
||||||
use super::{events::*, InputButtons, InputEvent};
|
use super::{events::*, InputButtons, InputEvent};
|
||||||
|
|
||||||
|
pub type KeyCode = winit::event::VirtualKeyCode;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InputSystem;
|
pub struct InputSystem;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{any::{Any, TypeId}, cell::{Ref, RefMut}, ptr::NonNull};
|
use std::{any::TypeId, cell::{Ref, RefMut}, ptr::NonNull};
|
||||||
|
|
||||||
use lyra_ecs::{World, ResourceObject};
|
use lyra_ecs::{World, ResourceObject};
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ pub struct ReflectedResource {
|
||||||
fn_reflect: for<'a> fn (world: &'a World) -> Option<Ref<'a, dyn Reflect>>,
|
fn_reflect: for<'a> fn (world: &'a World) -> Option<Ref<'a, dyn Reflect>>,
|
||||||
fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>>,
|
fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>>,
|
||||||
fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>,
|
fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>,
|
||||||
fn_refl_insert: fn (world: &mut World, this: Box<dyn Reflect>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReflectedResource {
|
impl ReflectedResource {
|
||||||
|
@ -28,11 +27,6 @@ impl ReflectedResource {
|
||||||
pub fn reflect_ptr(&self, world: &mut World) -> Option<NonNull<u8>> {
|
pub fn reflect_ptr(&self, world: &mut World) -> Option<NonNull<u8>> {
|
||||||
(self.fn_reflect_ptr)(world)
|
(self.fn_reflect_ptr)(world)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert the resource into the world.
|
|
||||||
pub fn insert(&self, world: &mut World, this: Box<dyn Reflect>) {
|
|
||||||
(self.fn_refl_insert)(world, this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
|
impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
|
||||||
|
@ -51,13 +45,6 @@ impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
|
||||||
world.try_get_resource_ptr::<T>()
|
world.try_get_resource_ptr::<T>()
|
||||||
.map(|ptr| ptr.cast::<u8>())
|
.map(|ptr| ptr.cast::<u8>())
|
||||||
},
|
},
|
||||||
fn_refl_insert: |world: &mut World, this: Box<dyn Reflect>| {
|
|
||||||
let res = this as Box<dyn Any>;
|
|
||||||
let res = res.downcast::<T>()
|
|
||||||
.expect("Provided a non-matching type to ReflectedResource insert method!");
|
|
||||||
let res = *res;
|
|
||||||
world.add_resource(res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,8 +23,6 @@ tracing = "0.1.37"
|
||||||
#mlua = { version = "0.9.2", features = ["lua54"], optional = true } # luajit maybe?
|
#mlua = { version = "0.9.2", features = ["lua54"], optional = true } # luajit maybe?
|
||||||
elua = { path = "./elua", optional = true }
|
elua = { path = "./elua", optional = true }
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
regex = "1.10.3"
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit beea6c33fcb2f5bd16f40e1919b61a89b4aaecb6
|
Subproject commit 70e2985cc44fdb30cdf2157c50d2f0e3385e08fa
|
|
@ -61,14 +61,6 @@ impl ReflectBranch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets self as a [`ReflectedResource`], returning `None` if self is not an instance of it.
|
|
||||||
pub fn as_resource(&self) -> Option<&ReflectedResource> {
|
|
||||||
match self {
|
|
||||||
ReflectBranch::Resource(v) => Some(v),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a boolean indicating if `self` is a reflection of a Resource.
|
/// Returns a boolean indicating if `self` is a reflection of a Resource.
|
||||||
pub fn is_resource(&self) -> bool {
|
pub fn is_resource(&self) -> bool {
|
||||||
matches!(self, ReflectBranch::Resource(_))
|
matches!(self, ReflectBranch::Resource(_))
|
||||||
|
|
|
@ -62,14 +62,14 @@ pub const FN_NAME_INTERNAL_REFLECT: &str = "__lyra_internal_reflect";
|
||||||
/// local cube_comp = ModelComponent.new(cube) -- annoying to write
|
/// local cube_comp = ModelComponent.new(cube) -- annoying to write
|
||||||
///
|
///
|
||||||
/// local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
/// local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
||||||
/// world:spawn(pos, cube_comp)
|
/// local e = world:spawn(pos, cube_comp)
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// With this function:
|
/// With this function:
|
||||||
/// ```lua
|
/// /// ```lua
|
||||||
/// local cube = world:request_res("assets/cube-texture-embedded.gltf")
|
/// local cube = world:request_res("assets/cube-texture-embedded.gltf")
|
||||||
/// local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
/// local pos = Transform.from_translation(Vec3.new(0, 0, -8.0))
|
||||||
/// world:spawn(pos, cube)
|
/// local e = world:spawn(pos, cube)
|
||||||
/// ```
|
/// ```
|
||||||
pub const FN_NAME_INTERNAL_AS_COMPONENT: &str = "__lyra_internal_refl_as_component";
|
pub const FN_NAME_INTERNAL_AS_COMPONENT: &str = "__lyra_internal_refl_as_component";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use lyra_ecs::ResourceObject;
|
use lyra_ecs::ResourceObject;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
use crate::{lua::{wrappers::{LuaActionHandler, LuaDeltaTime, LuaModelComponent}, LuaContext, RegisterLuaType, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptApiProvider, ScriptBorrow, ScriptData, ScriptDynamicBundle, ScriptWorldPtr};
|
use crate::{lua::{wrappers::{LuaDeltaTime, LuaModelComponent}, LuaContext, RegisterLuaType, FN_NAME_INTERNAL_REFLECT_TYPE}, ScriptApiProvider, ScriptBorrow, ScriptData, ScriptDynamicBundle, ScriptWorldPtr};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct LyraEcsApiProvider;
|
pub struct LyraEcsApiProvider;
|
||||||
|
@ -21,7 +21,6 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
||||||
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
||||||
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
||||||
globals.set("ModelComponent", ctx.create_proxy::<LuaModelComponent>()?)?;
|
globals.set("ModelComponent", ctx.create_proxy::<LuaModelComponent>()?)?;
|
||||||
globals.set("ActionHandler", ctx.create_proxy::<LuaActionHandler>()?)?;
|
|
||||||
|
|
||||||
let dt_table = create_reflect_table::<lyra_game::DeltaTime>(&ctx)?;
|
let dt_table = create_reflect_table::<lyra_game::DeltaTime>(&ctx)?;
|
||||||
globals.set("DeltaTime", dt_table)?;
|
globals.set("DeltaTime", dt_table)?;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{ptr::NonNull, sync::Arc};
|
use std::{ptr::NonNull, sync::Arc};
|
||||||
|
|
||||||
use crate::{ScriptBorrow, ScriptEntity, ScriptWorldPtr};
|
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_ecs::{query::dynamic::QueryDynamicType, CommandQueue, Commands, DynamicBundle, World};
|
||||||
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
use lyra_reflect::{ReflectWorldExt, RegisteredType, TypeRegistry};
|
||||||
use lyra_resource::ResourceManager;
|
use lyra_resource::ResourceManager;
|
||||||
|
@ -279,32 +279,6 @@ impl elua::Userdata for ScriptWorldPtr {
|
||||||
Ok(elua::Value::Nil)
|
Ok(elua::Value::Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.method_mut("add_resource", |_, this, res: elua::Value| {
|
|
||||||
let reflect = match res {
|
|
||||||
elua::Value::Userdata(ud) => ud
|
|
||||||
.execute_method::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT, ())
|
|
||||||
.expect("Type does not implement 'reflect_type' properly"),
|
|
||||||
elua::Value::Table(t) => {
|
|
||||||
let f: elua::Function = t.get(FN_NAME_INTERNAL_REFLECT)?;
|
|
||||||
f.exec::<_, ScriptBorrow>(())
|
|
||||||
.expect("Type does not implement 'reflect_type' properly")
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
panic!("how");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let data = reflect.data
|
|
||||||
.expect("Its expected that 'FN_NAME_INTERNAL_REFLECT' returns data in World:add_resource");
|
|
||||||
|
|
||||||
let res = reflect.reflect_branch.as_resource()
|
|
||||||
.ok_or(elua::Error::runtime("Provided type is not a resource!"))?;
|
|
||||||
|
|
||||||
let world = this.as_mut();
|
|
||||||
res.insert(world, data);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.method_mut("request_res", |_, this, path: String| {
|
.method_mut("request_res", |_, this, path: String| {
|
||||||
let world = this.as_mut();
|
let world = this.as_mut();
|
||||||
let mut man = world.get_resource_mut::<ResourceManager>();
|
let mut man = world.get_resource_mut::<ResourceManager>();
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
use lyra_game::input::{keycode_from_str, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, LayoutId, MouseAxis, MouseInput};
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
use crate::{lua::{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)]
|
|
||||||
pub struct LuaActionHandler {
|
|
||||||
handler: ActionHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
impl elua::Userdata for LuaActionHandler {
|
|
||||||
fn name() -> String {
|
|
||||||
"ActionHandler".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build<'a>(_: &elua::State, builder: &mut elua::UserdataBuilder<'a, Self>) -> elua::Result<()> {
|
|
||||||
builder.function("new", |_, table: elua::Table| {
|
|
||||||
let mut handler = ActionHandler::new();
|
|
||||||
|
|
||||||
// create the layouts
|
|
||||||
let layouts = table.get::<_, elua::Table>("layouts")
|
|
||||||
.map_err(|_| elua::Error::runtime("missing 'layouts' in ActionHandler table"))?;
|
|
||||||
for layout_id in layouts.sequence_iter::<u32>() {
|
|
||||||
let layout_id = layout_id?;
|
|
||||||
|
|
||||||
handler.add_layout(LayoutId(layout_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
let actions = table.get::<_, elua::Table>("actions")
|
|
||||||
.map_err(|_| elua::Error::runtime("missing 'actions' in ActionHandler table"))?;
|
|
||||||
for pair in actions.pairs::<String, String>() {
|
|
||||||
let (action_lbl, action_type) = pair?;
|
|
||||||
let action_type = action_type.to_lowercase();
|
|
||||||
|
|
||||||
let action_type = match action_type.as_str() {
|
|
||||||
"axis" => ActionKind::Axis,
|
|
||||||
"button" => ActionKind::Button,
|
|
||||||
_ => todo!("Handle invalid axis type"),
|
|
||||||
};
|
|
||||||
|
|
||||||
handler.add_action(action_lbl, Action::new(action_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
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::<elua::Table>().enumerate() {
|
|
||||||
let tbl = tbl?;
|
|
||||||
|
|
||||||
let layout_id = tbl.get::<_, u32>("layout")?;
|
|
||||||
let mut mapping = ActionMapping::new(LayoutId(layout_id), ActionMappingId(map_id as u32));
|
|
||||||
|
|
||||||
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::<String, elua::Table>() {
|
|
||||||
let (action_lbl, input_binds) = pair?;
|
|
||||||
|
|
||||||
for input in input_binds.sequence_iter::<String>() {
|
|
||||||
let input = input?.to_lowercase();
|
|
||||||
|
|
||||||
let action = handler.action(&action_lbl)
|
|
||||||
.ok_or(elua::Error::Runtime(format!("Unknown action specified in mapping binds: {}", action_lbl)))?;
|
|
||||||
|
|
||||||
let mut binds = Vec::new();
|
|
||||||
|
|
||||||
let input_split: Vec<&str> = input.split(":").collect();
|
|
||||||
let input_name = input_split[0];
|
|
||||||
let button = input_split[1];
|
|
||||||
|
|
||||||
if action.kind == ActionKind::Axis {
|
|
||||||
if button == "axis" {
|
|
||||||
let axis_name = input_split[2];
|
|
||||||
|
|
||||||
let src = process_axis_string(input_name, axis_name)
|
|
||||||
.ok_or(elua::Error::Runtime(format!("invalid bind '{input_name}', unable to find device or axis for device")))?;
|
|
||||||
binds.push(src.into_binding());
|
|
||||||
} else {
|
|
||||||
// splits 'down=1' into 'down' and '1'
|
|
||||||
let (button, val_str) = button.split_once("=")
|
|
||||||
.ok_or(elua::Error::Runtime(format!("invalid bind string for Axis Action: '{input}' (expected '=' with float)")))?;
|
|
||||||
|
|
||||||
let val = val_str.parse::<f32>()
|
|
||||||
.map_err(|e| elua::Error::Runtime(format!("invalid bind string for Axis Action: '{input}' ({e})")))?;
|
|
||||||
|
|
||||||
let src = process_keyboard_string(button)
|
|
||||||
.ok_or(elua::Error::Runtime(format!("invalid key in bind: '{button}'")))?;
|
|
||||||
binds.push(src.into_binding_modifier(val));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
todo!("Process bindings for Button Actions");
|
|
||||||
}
|
|
||||||
|
|
||||||
mapping.bind(action_lbl.clone(), &binds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.add_mapping(mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(LuaActionHandler {
|
|
||||||
handler,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.method(FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
|
|
||||||
Ok(ScriptBorrow::from_resource::<ActionHandler>(Some(this.handler.clone())))
|
|
||||||
})
|
|
||||||
.method(FN_NAME_INTERNAL_REFLECT_TYPE, |_, _, ()| {
|
|
||||||
Ok(ScriptBorrow::from_resource::<ActionHandler>(None))
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> elua::FromLua<'a> for LuaActionHandler {
|
|
||||||
fn from_lua(_: &'a elua::State, val: elua::Value<'a>) -> elua::Result<Self> {
|
|
||||||
let tyname = val.type_name();
|
|
||||||
let ud = val.as_userdata()
|
|
||||||
.ok_or(elua::Error::type_mismatch("ActionHandler", &tyname))?;
|
|
||||||
let handle = ud.as_ref::<LuaActionHandler>()?;
|
|
||||||
|
|
||||||
Ok(handle.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_keyboard_string(key_name: &str) -> Option<ActionSource> {
|
|
||||||
let key = keycode_from_str(key_name)?;
|
|
||||||
|
|
||||||
Some(ActionSource::Keyboard(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_axis_string(device: &str, axis_name: &str) -> Option<ActionSource> {
|
|
||||||
match device {
|
|
||||||
"mouse" => match axis_name {
|
|
||||||
"y" => Some(ActionSource::Mouse(MouseInput::Axis(MouseAxis::Y))),
|
|
||||||
"x" => Some(ActionSource::Mouse(MouseInput::Axis(MouseAxis::X))),
|
|
||||||
"scroll" | "scrollwheel" => Some(ActionSource::Mouse(MouseInput::Axis(MouseAxis::ScrollWheel))),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,6 +9,3 @@ pub use res_handle::*;
|
||||||
|
|
||||||
pub mod model_comp;
|
pub mod model_comp;
|
||||||
pub use model_comp::*;
|
pub use model_comp::*;
|
||||||
|
|
||||||
pub mod input_actions;
|
|
||||||
pub use input_actions::*;
|
|
Loading…
Add table
Reference in a new issue