Sam,
But SDL_PollEvent() always calls SDL_PumpEvents(). And SDL_PumpEvents()
collect all pending events. So, if there is a device that
generates a new
event everytime it is polled, the above loop will result in a deadlock.
With my preliminar driver, this was happening because the driver was
updating axis/buttons status (via SDL_PrivateJoystick*
functions) everytime
SDL_SYS_JoystickUpdate() was called, without checking if the status was
different from the previous one.
That’s why all of the joystick drivers only generate events if
the joystick state has changed.
This means that the following event loop is theorically much
faster (and not
deadlock-prone) than the above:
SDL_PumpEvents();
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS))
{
switch (event.type)
{
…
}
}
But this is not very clear by looking at the current documentation.
Yes, that’s correct on both counts.
Martin, can you add the above loop to the docs as an alternate way
of handling events?
The only problem with the above is if devices are generating events
faster than you are handling them, the event queue will fill up and
you’ll drop events. It’s not very likely, but it’s something that
you should be aware of if you’re using that form of event handling.
It’s not a problem of dropping events, it’s a problem of a real dead-lock.
In the first loop, when you call SDL_PollEvent() it calls SDL_PumpEvents()
that gathers new events. Now, think of a device configured to send a new
event everytime is polled. For example, an auto-centering joystick, or a
HotRod configured in auto-play that presses/releases a key everytime it is
polled. In this case, the function loop enters inside a never ending loop,
because each time SDL_PollEvent() is called, a new event is generated.
I know this quite irrealistic or bizzare, but I see it as a hole.
If there was a “event frame termination” function, one could change
SDL_PollEvent() in this way:
SDL_PollEvent()
{
if (!EventsAlreadyPumpedThisFrame)
SDL_PumpEvents();
return SDL_PeepEvents(...);
}
But since SDL does not know when that flag must be reset, the only other way
I see is to explicitally divide the event functions into two groups: the
gathering one (SDL_PumpEvents()) and the queue inspecting one
(SDL_PeepEvents() or SDL_PollEvent() without a PumpEvents call).
Anyway, even if you prefer to leave things as they are, I bet it’s better to
specify that the loop I’ve posted is faster, if not more proof, than the
"standard" one.
However, I’ve updated my Win32 joystick functions to use the DirectInput
buffered input, so that I basically convert the DirectInput events into SDL
joystick events (SDL_PrivateJoystick*) directly, without any internal
caching or stuff. All works correctly now with both event-polling loops.
About the fallback for old MM joystick routines, I’ve noticed that there is
no internal driver switching structure for the joystick subsystem (the video
subsystem can select which video driver must be used, and automatically
switch to another one if the default/suggested is not available). Do you
want me to add such a thing for the joystick subsystem? It should not be
difficult difficult. Or I could simply merge the old routines into my
current driver and let the fallback happen internally. Let me know what you
prefer.
Thanks—
Giovanni Bajo
Lead Programmer
Protonic Interactive
www.protonic.net
- Black holes are generated when God divides by zero -