-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Read and store joypad events in a separate thread on x11 platform #56125
Conversation
} | ||
if (no_events) { | ||
usleep(10000); // 10ms | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: It would probably be better to use a poll()
to detect changes. However:
- This is how the other thread is being managed; so I used this approach for consistency.
poll()
should be used on both threads, but this would the require refactoring theJoypad
class (separating the OS file descriptors from the Godot data to avoidmutex
sharing) and is probably best done in a separate PR as an enhancement instead of a bug fix.- The other thread (as well as the
XEvent
polling) uses aselect()
call (which is currently not used to detect changes, but only to check whether a change has happened to prevent the next call from blocking). Theseselect()
calls should be replaced withpoll()
calls too. Again, this is best done in a separate PR as an enhancement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The USB polling rate is 125 Hz by default (I believe most gamepads stick to this value). Shouldn't we use 8000
as a sleep duration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would make sense if there was a single joypad and the purpose of the delay was to wait until there was new data. In reality the delay would be less than 8000 μs, because there is the time needed to read the data. The required delay would also be indeterminate if there were multiple joypads, because they wouldn't be synchronised.
Note: The purpose of this delay is to not be busy waiting; especially when there are no joypads attached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thread/Mutex changes seems fine to me.
Not sure about usleep(10000); // 10ms
, but probably it's also OK.
Sorry for the delay reviewing. Should be fine to merge after a rebase. |
Thanks! |
Currently, joypad events are only read once every iteration. As demonstrated in #55850, this can result in joypad events being missed. The OS will drop old events in its queue if they are not read and its queue gets full.
This PR creates a separate thread to read the OS' joypad events and store them in a Godot queue until they are processed. This PR only fixes the Linux platform. The other platforms probably need to be updated in the same way.
Note: A lot of the changes are around updating the mutexes; as there are now three threads trying to access the
joypads
array:Joypad
elements at the time they're accessed.Joypad
element in the array now has its own mutex.Joypad
event queues.Joypad
element.Fixes #55850.