Skip to content

Commit

Permalink
Refactor input processors to make them more straightforward and perfo…
Browse files Browse the repository at this point in the history
…rmant (#511)

* Convert input processor traits into enums

* improve

* typo

* typo

* typo

* Use `Vec<Arc<*AxisProcessor>>` to represent pipelines of processors

* Merged `input_processing/dual_axis/modifier.rs` into `mod.rs`.

* Add example

* Remove outdated entries in RELEASES.md

* Update RELEASES.md
  • Loading branch information
Shute052 authored Apr 22, 2024
1 parent b62725c commit 654d6c8
Show file tree
Hide file tree
Showing 23 changed files with 1,827 additions and 1,739 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ derive_more = { version = "0.99", default-features = false, features = [
"error",
] }
itertools = "0.12"
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_flexitos = "0.2"
dyn-clone = "1.0"
dyn-eq = "0.1"
Expand Down
46 changes: 26 additions & 20 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,42 @@
### Breaking Changes

- removed `Direction` type in favor of `bevy::math::primitives::Direction2d`.
- added input processors for `SingleAxis`, `DualAxis`, `VirtualAxis`, and `VirtualDpad` to refine input values:
- added processor traits:
- added input processors for `SingleAxis`, `DualAxis`, `VirtualAxis`, and `VirtualDpad` to refine input values:
- added processor enums:
- `AxisProcessor`: Handles single-axis values.
- `DualAxisProcessor`: Handles dual-axis values.
- added built-in processors:
- Pipelines: Combine multiple processors into a pipeline.
- `AxisProcessingPipeline`: Chain processors for single-axis values.
- `DualAxisProcessingPipeline`: Chain processors for dual-axis values.
- added processor traits for defining custom processors:
- `CustomAxisProcessor`: Handles single-axis values.
- `CustomDualAxisProcessor`: Handles dual-axis values.
- added built-in processor variants (no variant versions implemented `Into<Processor>`):
- Pipelines: Handle input values sequentially through a sequence of processors.
- `AxisProcessor::Pipeline`: Pipeline for single-axis inputs.
- `DualAxisProcessor::Pipeline`: Pipeline for dual-axis inputs.
- you can also create them by these methods:
- `AxisProcessor::with_processor` or `From<Vec<AxisProcessor>>::from` for `AxisProcessor::Pipeline`.
- `DualAxisProcessor::with_processor` or `From<Vec<DualAxisProcessor>>::from` for `DualAxisProcessor::Pipeline`.
- Inversion: Reverses control (positive becomes negative, etc.)
- `AxisInverted`: Single-axis inversion.
- `DualAxisInverted`: Dual-axis inversion.
- `AxisProcessor::Inverted`: Single-axis inversion.
- `DualAxisInverted`: Dual-axis inversion, implemented `Into<DualAxisProcessor>`.
- Sensitivity: Adjusts control responsiveness (doubling, halving, etc.).
- `AxisSensitivity`: Single-axis scaling.
- `DualAxisSensitivity`: Dual-axis scaling.
- `AxisProcessor::Sensitivity`: Single-axis scaling.
- `DualAxisSensitivity`: Dual-axis scaling, implemented `Into<DualAxisProcessor>`.
- Value Bounds: Define the boundaries for constraining input values.
- `AxisBounds`: Restricts single-axis values to a range.
- `DualAxisBounds`: Restricts single-axis values to a range along each axis.
- `CircleBounds`: Limits dual-axis values to a maximum magnitude.
- `AxisBounds`: Restricts single-axis values to a range, implemented `Into<AxisProcessor>` and `Into<DualAxisProcessor>`.
- `DualAxisBounds`: Restricts single-axis values to a range along each axis, implemented `Into<DualAxisProcessor>`.
- `CircleBounds`: Limits dual-axis values to a maximum magnitude, implemented `Into<DualAxisProcessor>`.
- Deadzones: Ignores near-zero values, treating them as zero.
- Unscaled versions:
- `AxisExclusion`: Excludes small single-axis values.
- `DualAxisExclusion`: Excludes small dual-axis values along each axis.
- `CircleExclusion`: Excludes dual-axis values below a specified magnitude threshold.
- `AxisExclusion`: Excludes small single-axis values, implemented `Into<AxisProcessor>` and `Into<DualAxisProcessor>`.
- `DualAxisExclusion`: Excludes small dual-axis values along each axis, implemented `Into<DualAxisProcessor>`.
- `CircleExclusion`: Excludes dual-axis values below a specified magnitude threshold, implemented `Into<DualAxisProcessor>`.
- Scaled versions:
- `AxisDeadZone`: Normalizes single-axis values based on `AxisExclusion` and `AxisBounds::default`.
- `DualAxisDeadZone`: Normalizes dual-axis values based on `DualAxisExclusion` and `DualAxisBounds::default`.
- `CircleDeadZone`: Normalizes dual-axis values based on `CircleExclusion` and `CircleBounds::default`.
- `AxisDeadZone`: Normalizes single-axis values based on `AxisExclusion` and `AxisBounds::default`, implemented `Into<AxisProcessor>` and `Into<DualAxisProcessor>`.
- `DualAxisDeadZone`: Normalizes dual-axis values based on `DualAxisExclusion` and `DualAxisBounds::default`, implemented `Into<DualAxisProcessor>`.
- `CircleDeadZone`: Normalizes dual-axis values based on `CircleExclusion` and `CircleBounds::default`, implemented `Into<DualAxisProcessor>`.
- removed `DeadZoneShape`.
- removed functions for inverting, adjusting sensitivity, and creating deadzones from `SingleAxis` and `DualAxis`.
- added `with_processor`, `replace_processor`, and `no_processor` to manage processors for `SingleAxis`, `DualAxis`, `VirtualAxis`, and `VirtualDpad`.
- added `with_processor`, `replace_processor`, and `no_processor` to manage processors for `SingleAxis`, `DualAxis`, `VirtualAxis`, and `VirtualDpad`.
- added App extensions: `register_axis_processor` and `register_dual_axis_processor` for registration of processors.
- added `serde_typetag` procedural macro attribute for processor type tagging.
- made the dependency on bevy's `bevy_gilrs` feature optional.
Expand Down
15 changes: 7 additions & 8 deletions examples/input_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ fn spawn_player(mut commands: Commands) {
)
.insert(
Action::LookAround,
// You can also add a pipeline to handle axis-like user inputs.
DualAxis::mouse_motion().with_processor(
DualAxisProcessingPipeline::default()
// The first processor is a circular deadzone.
.with(CircleDeadZone::new(0.1))
// The next processor doubles inputs normalized by the deadzone.
.with(DualAxisSensitivity::all(2.0)),
),
// You can also use a sequence of processors as the processing pipeline.
DualAxis::mouse_motion().replace_processor(DualAxisProcessor::from(vec![
// The first processor is a circular deadzone.
CircleDeadZone::new(0.1).into(),
// The next processor doubles inputs normalized by the deadzone.
DualAxisSensitivity::all(2.0).into(),
])),
);
commands
.spawn(InputManagerBundle::with_map(input_map))
Expand Down
2 changes: 1 addition & 1 deletion examples/virtual_dpad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn spawn_player(mut commands: Commands) {
down: KeyCode::KeyS.into(),
left: KeyCode::KeyA.into(),
right: KeyCode::KeyD.into(),
processor: None,
processor: DualAxisProcessor::None,
},
)]);
commands
Expand Down
12 changes: 7 additions & 5 deletions macros/src/typetag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ pub(crate) fn expand_serde_typetag(input: &ItemImpl) -> TokenStream {

let trait_path = &trait_.1;

let self_ty = input.self_ty.clone();
let where_clause = &input.generics.where_clause;
let generics_params = &input.generics.params;

let ident = match type_name(&self_ty) {
let self_ty = &input.self_ty;

let ident = match type_name(self_ty) {
Some(name) => quote!(#name),
None => {
let impl_token = input.impl_token;
let ty = &input.self_ty;
let span = quote!(#impl_token, #ty);
let span = quote!(#impl_token, #self_ty);
let msg = "expected explicit name for Type";
return Error::new_spanned(span, msg).to_compile_error();
}
Expand All @@ -37,7 +39,7 @@ pub(crate) fn expand_serde_typetag(input: &ItemImpl) -> TokenStream {
quote! {
#input

impl<'de> #crate_path::typetag::RegisterTypeTag<'de, dyn #trait_path> for #self_ty {
impl<'de, #generics_params> #crate_path::typetag::RegisterTypeTag<'de, dyn #trait_path> for #self_ty #where_clause {
fn register_typetag(
registry: &mut #crate_path::typetag::MapRegistry<dyn #trait_path>,
) {
Expand Down
Loading

0 comments on commit 654d6c8

Please sign in to comment.