Leafwing-Studios / leafwing-input-manager

A straightforward stateful input manager for the Bevy game engine.
Apache License 2.0
720 stars 108 forks source link

Refactoring underlying architecture to support various input types #483

Closed Shute052 closed 5 months ago

Shute052 commented 8 months ago

Motivation

Setting the stage for future additions (maybe):

This also gives users the freedom to tailor the input kinds they want.

Tasks

Undecided Changes

InputStream trait

Replace the large InputStreams with smaller, single-responsibility implementations:

/// Allows defining a specific kind of stream collecting user inputs.
pub trait InputStream<'a> {
    /// Collects the inputs from a [`World`] for testing.
    fn from_world(world: &'a World) -> Self;
}

/// Bulit-in support for `ButtonInput<KeyCode>`.
pub type KeyCodeStream = ButtonInput<KeyCode>
impl<'a> InputStream<'a> for ButtonInput<KeyCode> {
    fn from_world(world: &'a World) -> Self {
        world.resource::<Self>().clone()
    }
}

InputQuery

Similar to Bevy's Query:

fn button_pressed(input_query: InputQuery<KeyCodeStream>, button: KeyCode) -> bool {
    let keycode_input: KeyCodeStream = input_query.get();
    keycode_input.pressed(button)
}
Shute052 commented 8 months ago

It's a huge task, but I'm hoping this setup will work out. This makes it easy to add new stuff later on, like touchscreens and gestures, and allowing users to customize their input types.

Any other ideas for now?

Shute052 commented 8 months ago

Should we prioritize removing input_mocking.rs first? See the comment.

alice-i-cecile commented 8 months ago

Not fully sold on the rename: I like the way that the current API makes the state machine nature clear.

Otherwise this looks good. And yes, we should swap out for a lighter solution to input mocking for tests: I think that will make the refactoring much easier.

Shute052 commented 8 months ago

Updated the description.


image


And how do I make all the references look like the one above? Even though the content in markdown is the same!

alice-i-cecile commented 8 months ago

And how do I make all the references look like the one above? Even though the content in markdown is the same!

Yeah, Github works in mysterious ways sometimes. I haven't been able to figure out what triggers the "expand issue number" formatting either!

jnhyatt commented 8 months ago

@Shute052 I just opened #496 based on some issues I was seeing. The current bevy_ui integration is somewhat hacky, and this new interface looks like it could significantly simplify that API and impl. Have you looked into adding UI interactions as an input type? I notice you have bevy_mod_picking listed as a potential input frontend, and I was considering that bevy_ui and bevy_mod_picking could potentially use a similar/the same API to generate input events. I'd love to collaborate on the rewrite if you think there's room for it.

Shute052 commented 8 months ago

I'd love to collaborate on the rewrite if you think there's room for it

I'm totally on board with this plan, but I'll be away from work for 10 days and won't be able to continue working on this until I get back

michael-jaquier commented 7 months ago

Hey. First thanks for the lib.

This

input sequences (https://github.com/Leafwing-Studios/leafwing-input-manager/issues/485)

would be very cool for me. i wanted to setup some "input modes" that toggle and this would let me do it directly with leafwing no need for anything ontop. If im understanding correctly though this is blocked until this larger story gets wrapped up?

Shute052 commented 7 months ago

until this larger story gets wrapped up?

@michael-jaquier Hi! Which input modes were you interested in? Adding support for some of these could be very beneficial for other users as well.

I'm currently working on #494 first. The code and documentation are nearly complete, but I'm holding off on pushing it just yet. I've actually explored different approaches, and I want to make sure the latest one is thoroughly tested before pushing it.

After that, I'll move on to #490. I think this will pave the way for a more straightforward implementation of InputSequence. Attempting to implement it now would be a complex and disruptive undertaking, due to the lack of separation of concerns and high coupling among the current underlying code.

michael-jaquier commented 7 months ago

Hey @Shute052 the idea for me was to have a system where users can input the "B" key to enter "Build Mode" then another key press would give them something from that mode.

Something like

delay = 1.5 seconds
input_map.insert_sequence(Action::BuildRedBox, [KeyB, KeyR], delay)

Does that make sense? Reading the abstract from here https://github.com/Leafwing-Studios/leafwing-input-manager/issues/485 I think this would fit my use case perfectly and not force me to build a

struct BuildMode(bool)

Ontop of your library

Shute052 commented 7 months ago

@michael-jaquier Here is my recent draft. While English isn't my native language, I struggle with naming and writing documentation.

/// Specifies the interval in milliseconds.
pub enum InputInterval {
    Min(f32),
    Max(f32),
    Range(f32, f32),
}

/// Specifies the timing rules for each user input in a sequence.
pub enum InputTimingRules {
    Every(InputInterval),
    EachBetween(Vec<InputInterval>),
}

/// Inserts a sequence of user inputs with specified timing rules.
fn insert_sequence(action: impl Actionlike, sequence: Vec<UserInput>, intervals: InputTimingRules);
michael-jaquier commented 7 months ago

Thats exactly what I needed indeed. That's the root of my query -- Will that implementation need to wait for this larger refactor? Or is there perhaps a dev branch I could use to test this feature ( once its out of draft mode )

Shute052 commented 7 months ago

If things go smoothly, we should have that trial branch in less than a month. I'm aiming to wrap up #494 in the next few days, and then move on to #490 which will make it easier for us to add new input types. After that, we can give implementing Sequence a try.

alice-i-cecile commented 5 months ago

534 is getting merged; I'm going to close this out.