Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input API design #83

Closed
jice-nospam opened this issue Feb 25, 2020 · 15 comments
Closed

input API design #83

jice-nospam opened this issue Feb 25, 2020 · 15 comments
Labels
awaiting_confirmation Believed fix, waiting for testing enhancement New feature or request

Comments

@jice-nospam
Copy link
Contributor

This issue is dedicated to designing a keyboard/mouse API that works well for both real time and turn by turn games, on native and WASM target.

Issues with current implementation :

  • keyboard provides only keycode, no scancode or character and handles only key press events
  • mouse interprets any button event as a left click
  • the game loop can only handle one key/mouse event per tick

API proposal :

  1. being able to check the current status of the controllers :
impl BTerm {
    fn is_key_code_pressed(&self, key_code: KeyCode) -> bool;
    fn is_scan_code_pressed(&self, scan_code: ScanCode) -> bool;
    fn is_mouse_button_pressed(&self, button_num: usize)-> bool;
    fn mouse_cell_pos(&self) -> (i32, i32); // in console cell coordinates
    fn mouse_pixel_pos(&self) -> (f64,f64); // in pixels
}
  1. but also provide the raw events to the user
impl BTerm {
    fn pop_event(&mut self) -> Option<InputEvent>;
}

I prefer a pop_event function to an iterator to avoid having to deal with a clear_event function in case the game logic is updated more than once per tick.

As for input events, winit does it pretty well, we should stick to it :
Keyboard events can be defined as KeyPress/KeyRelease (or KeyInput with a state).
Both events contain both key_code and scan_code when possible.
Mouse button events are MousePress/MouseRelease (or MouseInput) and MouseWheel for scrolling events
Text input can use a dedicated CharEvent containing a char field.

@jice-nospam jice-nospam mentioned this issue Feb 25, 2020
2 tasks
@Zireael07
Copy link

Zireael07 commented Feb 27, 2020

Also, I just noticed that contrary to just what a site having a HTML button does, wasm target does not treat touch as mouse...

@thebracket
Copy link
Collaborator

I'll try and include that in the input redesign. There's back-end work to support all of this ongoing in the new backend-cleanup branch right now. All backends now use VirtualKeyCode from winit, and the RLTK context no longer has to carry around a back-end link. I have a few other bugs to clean up/catch at the same time, but this gives a much better foundation on which to build.

thebracket added a commit that referenced this issue Feb 27, 2020
This is a general clean-up of the back-end architecture:

* The context object no longer includes the back-end, making it much more lightweight/efficient.
* WASM bug-fixes including background colors (finally!)
* GL (WASM and native) includes a call-back for when you want to render natively.
* Other platforms include access to BACKEND for access to dirty details. This varies in usefulness by platform, currently. Amethyst will get its own branch/PR soon to improve native access.

FIXES #53
Assists #83

* WIP: Remove backend linkage from console types.

* WIP: It doesn't actually render anything, but platform is removed from the main context now.

* Success in removing the platform entry from bterm. Only works for native as of yet.

* Cleanup imports.

* Curses non-functional but now compiles.

* Curses system working.

* Curses uses the real VirtualKeyCode.

* Crossterm is working in the new environment.

* Sparse console support in crossterm. No multiple fonts, obviously.

* Crossterm also uses the real VirtualKeyCode.

* Amethyst back-end works.

* Oops - forgot to set default back to opengl.

* WASM doesn't do anything, but it compiles now.

* Almost works.

* Move framebuffer.

* WASM testing success.

* WASM exposes actual VirtualKeyCode from winit, also.

* WebGL/WASM background colors are working once more. FIXES #53.

* Warning fixes.

* Fix build script for wasm.

* Add the option to pass-through native GL to a callback, for native rendering when needed (GL only for now).
@thebracket
Copy link
Collaborator

Now that the back-end cleanup is done, I'm tracking implementation work in the new branch: https://github.com/thebracket/bracket-lib/tree/input_api

thebracket added a commit that referenced this issue Feb 27, 2020
…ionality is in place for native (no other platform, including WASM yet). The beginnings of an event queue work, with minimal events so far. The new example, input_harness, demonstrates the mouse and event queue funcitonality so far.
@jice-nospam
Copy link
Contributor Author

Also, I just noticed that contrary to just what a site having a HTML button does, wasm target does not treat touch as mouse...

I don't think touch and mouse click should be treated a the same thing. winit has dedicated events for touch support and it's quite different from mouse (no left/right buttons, but you can have simultaneous touch events at different places. Touch also has a notion of pressure, see winit's doc). I've focused the current design on mouse/keyboard. Pushing it further would include touch & joystick support but I guess we're not there yet.

@thebracket
Copy link
Collaborator

I'm going to pretend that Touch events don't exist for the first pass. There's a lot of them, and I don't have much in the way of devices that can test them. I'll get the basics going, and revisit touch.

@Zireael07
Copy link

Some libraries, e.g. winit, seem to use pointer events instead, and those work across most browsers and seem to react to mouse OR touch?

@thebracket
Copy link
Collaborator

It's been a pretty solid day in terms of implementing this:

  • The basic API outlined is present. Scan codes are a problem on the pure terminal back-ends, still working on that one. (A char to scan-code routine is needed, since neither curses nor crossterm give me that data).
  • Native has very good event stream support.
  • WASM has ok event stream support (the important ones).
  • Amethyst has ok event stream support. There's a few events I haven't figured out how to find, yet.
  • Curses and Crossterm have event streams, but only for the things they support.

The context object is now small, support Clone and Debug, and can be safely bypassed when you want to work in a threaded environment. You'll still need it for render batch submission, but otherwise you can access input and batches completely independently of the context. I was a little worried that the Mutex locking would slow things down, but an uncontested (and they HAVE to be uncontested in most of the architecture, at least on the inside) lock call turns out to be really cheap. Frame rates have actually gone up!

@thebracket
Copy link
Collaborator

I'm out of time for now; apparently I need to fix RLTK example 13.

@jice-nospam
Copy link
Contributor Author

Thanks, I've started using this in my bracket port. I will probably submit some PR next week because I still have issues but don't feel the urge to answer to them.

@jice-nospam
Copy link
Contributor Author

I think there's a misunderstanding about the input API.
The static API (for example is_key_code_pressed) shows the current status of the controller. As long as a key is pressed, is_key_code_pressed returns true. On the other hand, the event API shows change of status. So when I press and release a key, the following events occur :

  • is_key_code_pressed returns false
  • I receive a KeyboardInput event for a key press event
  • is_key_code_pressed now returns true as long as the key stays pressed
  • I receive a KeyboardInput event for a key release event
  • is_key_code_pressed now returns false again

I've created the pull request #95 to demonstrate what I had in mind.

@thebracket thebracket added the enhancement New feature or request label Mar 4, 2020
@thebracket
Copy link
Collaborator

I've integrated the PR, and taken a stab at making it work across back-ends. It's good on native and WASM, not bad on Amethyst, and poor-but-working on Curses/Crossterm (since neither actually supports key_key events, and Curses doesn't do mouse_up either - so there's some nasty emulation that doesn't reflect keys held down properly).

I think we're getting closer.

@jice-nospam
Copy link
Contributor Author

Looks nice! As far as doryen-rs is concerned, everything on the input API works as intended (at least using the native backend). I'll try to see if everything still works on WASM target

@thebracket
Copy link
Collaborator

I'm going to take one more stab at the console-based back-ends (particularly scan codes and keyboard latches), and do a little more testing - but I'm pretty sure this one will be merged very soon. :-)

@thebracket
Copy link
Collaborator

Alright! I've cleaned up a lot of niggling things on the input_api branch. I think it's good to merge:

  • Amethyst now uses an EventChannel, making for much more consistent input.
  • There's a faux VirtualKeyCode to ScanCode converter in Curses/Crossterm to fake the scancodes. Obtained by writing a tool that received both from winit and wrote them to a file while I pressed every key on my keyboard.
  • WASM no longer receives "cursor moved" on every frame: only when it actually moved.

With that, I think I'll start merging.

@thebracket
Copy link
Collaborator

It's merged!

@thebracket thebracket added the awaiting_confirmation Believed fix, waiting for testing label Mar 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting_confirmation Believed fix, waiting for testing enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants