Controller on / off management #85
-
Hello everyone! As long as the controller stays alive, everything works perfectly. But it (PS Dualshock 4) turns itself off after 10 minutes. ❓ Is the library able to manage the re-connection of a controller? Here is my current code: let gamecontroller = null;
const buttonStates = {
back: false,
dpdown: false,
};
async function sdlInit() {
if (process.platform !== 'linux') {
console.log('SDL2 initialization skipped (not on Linux)');
return false;
}
try {
// Cleanup previous instance
if (gamecontroller) {
gamecontroller = null;
console.log('Cleaned up previous SDL2 instance');
}
const mod = await import('sdl2-gamecontroller');
gamecontroller = mod.default || mod;
// Setup event listeners
gamecontroller.on("error", (data) => {
console.error("SDL2 Error:", JSON.stringify(data));
});
gamecontroller.on("warning", (data) => {
console.warn("SDL2 Warning:", JSON.stringify(data));
// if (data.message.includes('too long')) {
// restartSDL();
// }
});
gamecontroller.on("sdl-init", (data) => {
console.log(JSON.stringify(data));
console.log("SDL2 Initialized successfully");
});
gamecontroller.on("controller-device-added", (data) => {
// if (!sdlInitialized) return;
console.log(JSON.stringify(data));
try {
gamecontroller.setLeds(0x0f, 0x62, 0xfe, data.player);
} catch (err) {
console.error('LED set failed:', err);
}
});
gamecontroller.on("controller-device-removed", (data) => {
console.log(JSON.stringify(data));
// gamecontroller = null;
});
gamecontroller.on('controller-button-up', (event) => {
// if (!sdlInitialized) return;
buttonStates[event.button] = false;
});
gamecontroller.on('controller-button-down', (event) => {
// if (!sdlInitialized) return;
buttonStates[event.button] = true;
if (buttonStates.back && buttonStates.dpdown) {
console.log('Triggering process kill combo');
killChildProcesses(childProcesses);
}
});
console.log('SDL2 Gamecontroller initialized');
return true;
} catch (err) {
console.error('SDL2 Initialization failed:', err);
sdlInitialized = false;
return false;
}
}
function restartSDL() {
console.log('Restarting SDL...');
sdlInitialized = false;
setTimeout(() => sdlInit(), 1000);
}
// IPC handler
ipcMain.handle('game-controller-init', async () => {
console.log("game-controller-init: ");
return await sdlInit();
}); As you see (I tried many things) I'm trying to reset everything by setting gamecontroller to null but it's probably not the right way to go.
Is there a way to get Am I missing something? I think I am ; Thanks anybody for any piece of advice / orientation / documentation 🙏🏼 -- Phil |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
The The sequence that I would expect is:
I am wondering if trying to stop the game controller and restart it is actually causing multiple SDL event loops and maybe the first one is eating all the events. I do not account for that in the code but there should be a way to clean up an instance. I'll have a look. Also, can you implement |
Beta Was this translation helpful? Give feedback.
-
Yes, definitely. If I don't do this "re-connection dance", the sequence is:
The controller never reconnects.
Yes, they are working (and in combinations, specifically let gamecontroller = null;
const buttonStates = {
back: false,
dpdown: false,
};
async function sdlInit() {
if (process.platform !== 'linux') {
console.log('SDL2 initialization skipped (not on Linux)');
return false;
}
try {
const mod = await import('sdl2-gamecontroller');
gamecontroller = mod.default || mod;
// Setup event listeners
gamecontroller.on("error", (data) => {
console.error("SDL2 Error:", JSON.stringify(data));
});
gamecontroller.on("warning", (data) => {
console.warn("SDL2 Warning:", JSON.stringify(data));
});
gamecontroller.on("sdl-init", (data) => {
console.log(JSON.stringify(data));
console.log("SDL2 Initialized successfully");
});
gamecontroller.on("controller-device-added", (data) => {
console.log(JSON.stringify(data));
try {
gamecontroller.setLeds(0x0f, 0x62, 0xfe, data.player);
} catch (err) {
console.error('LED set failed:', err);
}
});
gamecontroller.on("controller-device-removed", (data) => {
console.log(JSON.stringify(data));
});
gamecontroller.on('controller-button-up', (event) => {
buttonStates[event.button] = false;
});
gamecontroller.on('controller-button-down', (event) => {
buttonStates[event.button] = true;
if (buttonStates.back && buttonStates.dpdown) {
console.log('Triggering process kill combo');
killChildProcesses(childProcesses);
}
});
console.log('SDL2 Gamecontroller initialized');
return true;
} catch (err) {
console.error('SDL2 Initialization failed:', err);
return false;
}
}
await sdlInit(); Thanks a lot for your help @davidnixon, this quick reply is really nice of you.
Yes! This is what I expect too, and thanks for clearing this up ; Would you by any chance 🙏🏼 happen to have a minimal JS test implementation where the buttons still work after a reconnect? For a bit of context: I'm using sdl2-gamecontroller to be able to still get a specific button combination (back + dp_down) even when the app (an electron app that uses the Chrome - well, Chromium - gamecontroller API) does not have focus. And for now I managed to get it to work perfectly, I even manage the case where the controller is not on at startup, so the Chrome gamecontroller API sends the connection info to the node process, that then inits sdl2-gamecontroller, and everything is peachy. The only thing that I've been stuck on for weeks 😢 now is the re-connection of a wireless controller. |
Beta Was this translation helpful? Give feedback.
-
Just to be sure I ran stand-alone the example in the README page, and everything works: Buttons, colors, even accel and gyro AFAIK, wow. But after turning the controller (DS4) off and on again, it doesn't reconnect. |
Beta Was this translation helpful? Give feedback.
-
I did a couple of more test on my side.
Can you have a look at your bluetooth and see if maybe that is related. I am looking for my PS5 controller to more closely replicate your use-case but I think somebody it actually using it to play PS5! |
Beta Was this translation helpful? Give feedback.
-
I ran additional tests based on my theory that two event loops might be running, which could explain why connections and button events weren’t being handled. To test this, I opened the sample app in two separate windows using |
Beta Was this translation helpful? Give feedback.
-
Wow, David, this is fantastic work, thank you very much for this comprehensive data / intel, I'm going to process this and put it to good use. I mean, I only tested a Dualshock 4, and you tested across the board!! The "wired Logitech controller" report is especially valuable to me ; Really, thanks a bunch.
All this time it never occurred to me that the PB could be on the BT adapter part. I feel like my part of the work is now on the Bluetooth side of things. I'm going to test more BT adapters, right now I'm using a But as for this discussion / question, you answered it: This (great) lib does handle controller re-connection. PS I just invited you to the project repo, that will be public once I iron out the bugs (and figure out a license) :) |
Beta Was this translation helpful? Give feedback.
I did a couple of more test on my side.
node test/lengthy.js