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.
This commit is contained in:
committed by
Sam Lantinga
parent
3c11b43e59
commit
be8643f739
@@ -35,53 +35,62 @@ static SDL_joylist_item *SDL_joylist = NULL;
|
|||||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||||
static int numjoysticks = 0;
|
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'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)
|
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||||
let vendor_str = 'Vendor: ';
|
let vendor_str = 'Vendor: ';
|
||||||
if (gamepad['id']['indexOf'](vendor_str) > 0) {
|
if (gamepad['id']['indexOf'](vendor_str) > 0) {
|
||||||
let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length'];
|
let vendor_str_index = gamepad['id']['indexOf'](vendor_str) + vendor_str['length'];
|
||||||
return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16);
|
return parseInt(gamepad['id']['substr'](vendor_str_index, 4), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||||
let id_split = gamepad['id']['split']('-');
|
let id_split = gamepad['id']['split']('-');
|
||||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) {
|
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[0], 16))) {
|
||||||
return 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), {
|
static int SDL_GetEmscriptenJoystickProduct(int device_index)
|
||||||
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)
|
// Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)
|
||||||
let product_str = 'Product: ';
|
let product_str = 'Product: ';
|
||||||
if (gamepad['id']['indexOf'](product_str) > 0) {
|
if (gamepad['id']['indexOf'](product_str) > 0) {
|
||||||
let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length'];
|
let product_str_index = gamepad['id']['indexOf'](product_str) + product_str['length'];
|
||||||
return parseInt(gamepad['id']['substr'](product_str_index, 4), 16);
|
return parseInt(gamepad['id']['substr'](product_str_index, 4), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
// Firefox, Safari: 046d-c216-Logitech Dual Action (or 46d-c216-Logicool Dual Action)
|
||||||
let id_split = gamepad['id']['split']('-');
|
let id_split = gamepad['id']['split']('-');
|
||||||
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) {
|
if (id_split['length'] > 1 && !isNaN(parseInt(id_split[1], 16))) {
|
||||||
return 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), {
|
static int SDL_IsEmscriptenJoystickXInput(int device_index)
|
||||||
let gamepad = navigator['getGamepads']()[device_index];
|
{
|
||||||
|
return MAIN_THREAD_EM_ASM_INT({
|
||||||
|
let gamepad = navigator['getGamepads']()[$0];
|
||||||
|
|
||||||
// Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD)
|
// Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD)
|
||||||
// Firefox: xinput
|
// Firefox: xinput
|
||||||
// TODO: Safari
|
// TODO: Safari
|
||||||
return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0;
|
return gamepad['id']['toLowerCase']()['indexOf']('xinput') >= 0;
|
||||||
});
|
}, device_index);
|
||||||
|
}
|
||||||
|
|
||||||
static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user