Skip to content

Commit

Permalink
Add derive macro
Browse files Browse the repository at this point in the history
  • Loading branch information
Shatur committed Oct 7, 2024
1 parent da0c41a commit ad1251e
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 26 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "bevy_enhanced_input"
version = "0.1.0"
authors = ["Hennadii Chernyshchyk <[email protected]>"]
edition = "2021"
description = "Dynamic and contextual input mappings for Bevy "
description = "Dynamic and contextual input mappings for Bevy"
readme = "README.md"
repository = "https://github.com/projectharmonia/bevy_enhanced_input"
keywords = ["bevy", "input"]
Expand All @@ -12,6 +12,7 @@ license = "MIT OR Apache-2.0"
include = ["/src", "/tests", "/LICENSE*"]

[dependencies]
bevy_enhanced_input_macros = { path = "macros" }
bevy = { version = "0.14", default-features = false, features = ["serialize"] }
bevy_egui = { version = "0.30", default-features = false, features = [
"immutable_ctx", # Require to get read-only access in our exclusive system.
Expand All @@ -34,3 +35,6 @@ ui_priority = ['bevy/bevy_ui']

# Prioritizes 'egui' over actions when processing inputs.
egui_priority = ['dep:bevy_egui']

[workspace]
members = ["macros"]
35 changes: 10 additions & 25 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,18 @@ impl InputContext for OnFoot {
}
}

#[derive(Debug)]
#[derive(Debug, InputAction)]
#[action_dim(Axis2D)]
struct Walk;

impl InputAction for Walk {
const DIM: ActionValueDim = ActionValueDim::Axis2D;
}

#[derive(Debug)]
#[derive(Debug, InputAction)]
#[action_dim(Bool)]
struct Jump;

impl InputAction for Jump {
const DIM: ActionValueDim = ActionValueDim::Bool;
}

#[derive(Debug)]
#[derive(Debug, InputAction)]
#[action_dim(Bool)]
struct EnterCar;

impl InputAction for EnterCar {
const DIM: ActionValueDim = ActionValueDim::Bool;
}

#[derive(Component)]
struct InCar;

Expand All @@ -66,20 +57,14 @@ impl InputContext for InCar {
}
}

#[derive(Debug)]
#[derive(Debug, InputAction)]
#[action_dim(Axis2D)]
struct Drive;

impl InputAction for Drive {
const DIM: ActionValueDim = ActionValueDim::Axis2D;
}

#[derive(Debug)]
#[derive(Debug, InputAction)]
#[action_dim(Bool)]
struct ExitCar;

impl InputAction for ExitCar {
const DIM: ActionValueDim = ActionValueDim::Bool;
}

fn spawn(mut commands: Commands) {
commands.spawn(OnFoot);
}
Expand Down
14 changes: 14 additions & 0 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "bevy_enhanced_input_macros"
version = "0.1.0"
description = "Bevy Enhanced Input Macros"
edition = "2021"
license = "MIT OR Apache-2.0"

[lib]
proc-macro = true

[dependencies]
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
proc-macro2 = "1.0"
50 changes: 50 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use proc_macro::TokenStream;
use proc_macro2::TokenTree;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Meta};

#[proc_macro_derive(InputAction, attributes(action_dim))]
pub fn input_action_derive(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);

const ATTR_NAME: &str = "action_dim";
let mut dim = None;
for attr in input.attrs {
let Meta::List(list) = attr.meta else {
continue;
};

if list
.path
.segments
.iter()
.any(|segment| segment.ident == ATTR_NAME)
{
assert!(dim.is_none(), "`{ATTR_NAME}` can be defined only once");

let mut token_iter = list.tokens.into_iter();
let token = token_iter
.next()
.unwrap_or_else(|| panic!("`{ATTR_NAME}` should have argument"));

let TokenTree::Ident(indent) = token else {
panic!("`{token}` is invalid argument for `{ATTR_NAME}`");
};

dim = Some(indent);

assert!(
token_iter.next().is_none(),
"`{ATTR_NAME}` should have only a single argument"
);
}
}

let dim = dim.unwrap_or_else(|| panic!("`InputAction` should have `{ATTR_NAME}` attribute"));
let struct_name = input.ident;
TokenStream::from(quote! {
impl InputAction for #struct_name {
const DIM: ActionValueDim = ActionValueDim::#dim;
}
})
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod prelude {
input_reader::KeyboardModifiers,
EnhancedInputPlugin,
};
pub use bevy_enhanced_input_macros::InputAction;
}

use bevy::{ecs::system::SystemState, input::InputSystem, prelude::*};
Expand Down

0 comments on commit ad1251e

Please sign in to comment.