-
Notifications
You must be signed in to change notification settings - Fork 113
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
APP-538: Make base key and mouse events more robust #1528
Conversation
import type { ServiceError } from '../gen/proto/stream/v1/stream_pb_service.esm'; | ||
|
||
interface Props { | ||
name: string; | ||
resources: Resource[]; | ||
} | ||
|
||
// eslint-disable-next-line no-shadow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, for some reason ESLint thinks that we're shadowing another variable with const enum
s. That's weird, we'll need to investigate more.
@@ -45,16 +53,14 @@ const angle = ref(0); | |||
const videoStreamStates = new Map<string, boolean>(); | |||
const selectCameras = ref(''); | |||
|
|||
const pressed = new Set<Keys>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now add all pressed keys to a stack of unique items, and then digest those items from oldest to newest input. The key is deleted from the stack when a keyup / mouseup event occurs. This allows us to better handle multiple keys pressed at the same time by a keyboard, or even a touchscreen!
let linearValue = 0; | ||
let angularValue = 0; | ||
|
||
for (const item of pressed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we loop through the stack of pressed keys, and apply weights for each key. We don't need to worry about values growing larger than 1, because all items in a Set
can be guaranteed to be unique.
The result of this behavior is that pressing the left and right keys (or the up and down keys) will cancel each other out.
new commonApi.Vector3(), | ||
displayError | ||
); | ||
const req = new baseApi.SetVelocityRequest(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BaseControlHelper isn't providing much abstraction value anymore since we've componentized everything, so I've moved all methods into the component. Switching to protobuf-ts will simplify this even more.
/> | ||
</div> | ||
<KeyboardInput | ||
@keydown="handleKeyDown" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've simplified the internals of <KeyboardInput>
so that it's now just emitting keydown and keyup events with normalized input.
|
||
const handleKeyDown = (key: Keys) => { | ||
pressed.add(key); | ||
digestInput(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We re-digest input whenever a keydown happens, or a keyup happens and the length of pressed keys is still greater than zero.
|
||
const handlePointerDown = (key: Keys) => { | ||
emitKeyDown(key); | ||
window.addEventListener('pointerup', () => emitKeyUp(key), { once: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This specifically fixes one of the issues people are encountering: dragging a mouse away from a button and releasing the mouse button causes the robot to drive forever, off into the sunset, never to be seen again.
If we instead apply the keyup event to the window, the mouse can be anywhere and the input will still be canceled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳 LGTM!
|
This PR refactors how we handle mouse and key events from the
<KeyboardInput>
component, making them behave more predictably, with fewer cases in which a stop signal will not be sent if the user is not interacting anymore. More details in comments.