Tema:
En la implementación actual de los navegadores modernos (como Firefox o Chrome), solo hay dos eventos de joystick/gamepad:
Dado que parece que la idea original detrás de implementar la compatibilidad con joystick/gamepad en el navegador era permitir juegos en el navegador, el joystick se hizo dependiente de la llamada requestAnimationFrame() para crear una sincronización de bucle de juego con v_sync.
Sin embargo, en otros casos de uso, por ejemplo, cuando el joystick se usa para controlar algo de forma remota a través de una red o conexión inalámbrica, el mejor caso es enviar datos solo cuando hay algo útil que decir: ¿sucedió algo? El uso de requestAnimationFrame() inunda la interfaz con datos potencialmente inútiles.
Desafortunadamente, actualmente no existe una interfaz establecida para desencadenar eventos de gamepad. : (Tenga en cuenta que hay una discusión sobre este mismo problema en los foros de Mozilla y W3C, por lo que esto puede, eventualmente , cambiar).
Dado que inundar un dispositivo industrial o un sistema de control remoto con mensajes inútiles no es una "mejor práctica", la pregunta es cómo generar el equivalente de un evento de gamepad sin inundar la red o detener el navegador en un ciclo de espera.
Webworkers fue una idea, pero no se pueden usar porque no tienen acceso al contexto window.event y no pueden interactuar con el joystick/gamepad. Al menos no directamente.
Para manejar esto de manera eficiente, algún método para desencadenar un "evento" que permita enviar datos, solo cuando sucede algo de interés.
Para el beneficio de aquellos que pueden estar enfrentando este mismo problema, aquí está la solución que finalmente implementé:
=======================
Mi solución:
Esta solución se basa en el hecho de que el atributo time_stamp del gamepad solo cambia cuando sucede algo . ( es decir , se presionó un botón o se movió un eje de joystick)
Implementé esto en dos pasos como se indicó anteriormente:
Primero:
Cuando el gamepad se conecta, inmediatamente capturo el atributo time_stamp y lo almaceno en una variable (old_time).
window.addEventListener("gamepadconnected", (event) => { js = event.gamepad; gamepad_connected(); // Gamepad is now connected old_time = gopigo3_joystick.time_stamp // Capture the initial value of the time_stamp send_data(gopigo3_joystick) // send it to the robotLuego hago cualquier bucle y procesamiento de datos que necesito hacer.
Como parte de ese bucle, periódicamente intento enviar datos al dispositivo del servidor con el siguiente código:
function is_something_happening(old_time, gopigo3_joystick) { if (gopigo3_joystick.trigger_1 == 1 || gopigo3_joystick.head_enable == 1) { if (old_time != Number.parseFloat(jsdata.timestamp).toFixed()) { send_data(gopigo3_joystick) old_time = gopigo3_joystick.time_stamp } } return; } function send_data(gpg_data) { // this sends a gamepad data frame to the robot for interpreting. [code goes here]; return; }La primera función, is_something_happening, prueba dos condiciones de calificación:
Ambas condiciones deben cumplirse, de lo contrario, la prueba falla y regresa inmediatamente.
Solo si se cumplen ambas condiciones, se llama a la función send_data().
Esto da como resultado una interfaz estable a la que siempre se llama si ha sucedido algo de interés, pero solo si ha sucedido algo de interés.
Nota: Hay comandos de teclado que se pueden enviar, pero dado que tienen eventos activos, pueden llamar a send_data() por sí mismos, ya que solo se activan cuando se presiona una tecla.