Key Event Handling - More ergonomic API for handling single key presses
Aligorith opened this issue · 1 comments
As an exercise in evaluating the functionality of this library, I tried adding a simple "Z-Key toggles Wireframe/Shaded" draw mode for the anim.rs example. Cue two days of frustration banging into various "why is this glitching" followed by "compiler says no" problems.
Here are a bunch of things that could make this experience easier the next time someone new to this library tries to do this stuff:
1) There needs to be something like "Input.keypress_event(keycode)
Currently, to handle a one-off "tap the key, an action happens, then don't repeat again until you hit the key again" (i.e. a toggle action doesn't randomly flicker, as keypress + keyrelease events are fired repeatedly), you need to do something like:
while win.update() && !win.input.hit(three::KEY_ESCAPE) {
// Handle z-key toggles material
if win.input.hit(three::controls::Key::Z) &&
win.input.keys_hit().contains(&three::controls::Key::Z)
{
// Toggle material now
mesh.set_material(...)
}
}
Instead of having to call both, perhaps just having a single method that does both steps would suffice?
2) The standard Rust traits - Copy, PartialEq, Debug, ... - need to be implemented on most types in this library
If trying to create a demo app that depends on this library (as an extern/separate crate), it's currently impossible to store any of the types defined by this crate in a struct (e.g. to wrap together all the viewport handling in a "ViewportState" object, that has a single ".update()" method that's exposed/called from the "while window.update() {...}" main event loop.
For example, the following code fails to compile, as rustc complains about PartialEq not being implemented for Orbit, but you cannot implement PartialEq for that as it's in a different crate (!):
struct ViewportState {
orbit : three::controls::Orbit, <--- fails with error about PartialEq
... other state variables you've defined - e.g. wireframe vs solid state ...
}
impl ViewportState {
fn update(&self, input: &three::Input) {
self.orbit.update(input);
// Do other hotkey handling here (e.g. zkey handler)...
}
}
3) Add an Event Handling Example
There needs to be an example in the examples folder showing how you'd combine single-keypress events (e.g. for toggling/triggering particular one-off actions, not repeating stepping motions), viewport controls (e.g. Orbit, FirstPerson), and/or the axis (two separate keys for repeating actions along some scale).
@Aligorith it all sounds wonderful!
Worth noting that at this stage the library will only survive if it's ported over to a modern graphics stack - #222.