mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-04-03 15:46:04 +02:00
emscripten: Fix navigator.getGamepads crash in worker threads
The three EM_JS functions (SDL_GetEmscriptenJoystickVendor,
SDL_GetEmscriptenJoystickProduct, SDL_IsEmscriptenJoystickXInput)
call navigator.getGamepads() which is only available on the main
browser thread. With PROXY_TO_PTHREAD, the joystick callbacks are
dispatched to a worker where the Gamepad API is not available,
causing a TypeError.
Convert these from EM_JS to static functions using
MAIN_THREAD_EM_ASM_INT, which proxies the JavaScript execution to
the main browser thread. This matches the pattern already used by
other navigator.getGamepads() calls in the same file.
(cherry picked from commit be8643f739)
This commit is contained in:
committed by
Sam Lantinga
parent
c391e73432
commit
5be888591c
@@ -35,53 +35,62 @@ static SDL_joylist_item *SDL_joylist = NULL;
|
||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||
static int numjoysticks = 0;
|
||||
|
||||
EM_JS(int, SDL_GetEmscriptenJoystickVendor, (int device_index), {
|
||||
static int SDL_GetEmscriptenJoystickVendor(int device_index)
|
||||
{
|
||||
// Let's assume that if we're calling these function then the gamepad object definitely exists
|
||||
let gamepad = navigator['getGamepads']()[device_index];
|
||||
return MAIN_THREAD_EM_ASM_INT({
|
||||
let gamepad = navigator['getGamepads']()[$0];
|
||||
|
||||
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||
let vendor_str = 'Vendor: ';
|
||||
if (gamepad['id']['indexOf'](vendor_str) > 0) {
|
||||
let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length'];
|
||||
return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16);
|
||||
}
|
||||
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||
let vendor_str = 'Vendor: ';
|
||||
if (gamepad['id']['indexOf'](vendor_str) > 0) {
|
||||
let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length'];
|
||||
return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16);
|
||||
}
|
||||
|
||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||
let id_split = gamepad['id']['split']('-');
|
||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) {
|
||||
return parseInt(id_split[0], 16);
|
||||
}
|
||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||
let id_split = gamepad['id']['split']('-');
|
||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) {
|
||||
return parseInt(id_split[0], 16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
return 0;
|
||||
}, device_index);
|
||||
}
|
||||
|
||||
EM_JS(int, SDL_GetEmscriptenJoystickProduct, (int device_index), {
|
||||
let gamepad = navigator['getGamepads']()[device_index];
|
||||
static int SDL_GetEmscriptenJoystickProduct(int device_index)
|
||||
{
|
||||
return MAIN_THREAD_EM_ASM_INT({
|
||||
let gamepad = navigator['getGamepads']()[$0];
|
||||
|
||||
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||
let product_str = 'Product: ';
|
||||
if (gamepad['id']['indexOf'](product_str) > 0) {
|
||||
let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length'];
|
||||
return parseInt(gamepad['id']['substr'](product_str_index, 4), 16);
|
||||
}
|
||||
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||
let product_str = 'Product: ';
|
||||
if (gamepad['id']['indexOf'](product_str) > 0) {
|
||||
let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length'];
|
||||
return parseInt(gamepad['id']['substr'](product_str_index, 4), 16);
|
||||
}
|
||||
|
||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||
let id_split = gamepad['id']['split']('-');
|
||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) {
|
||||
return parseInt(id_split[1], 16);
|
||||
}
|
||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||
let id_split = gamepad['id']['split']('-');
|
||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) {
|
||||
return parseInt(id_split[1], 16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
return 0;
|
||||
}, device_index);
|
||||
}
|
||||
|
||||
EM_JS(int, SDL_IsEmscriptenJoystickXInput, (int device_index), {
|
||||
let gamepad = navigator['getGamepads']()[device_index];
|
||||
static int SDL_IsEmscriptenJoystickXInput(int device_index)
|
||||
{
|
||||
return MAIN_THREAD_EM_ASM_INT({
|
||||
let gamepad = navigator['getGamepads']()[$0];
|
||||
|
||||
// Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD)
|
||||
// Firefox: xinput
|
||||
// TODO: Safari
|
||||
return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0;
|
||||
});
|
||||
// Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD)
|
||||
// Firefox: xinput
|
||||
// TODO: Safari
|
||||
return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0;
|
||||
}, device_index);
|
||||
}
|
||||
|
||||
static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user