What's the rational behind having user events? Why wouldn't an app just run whatever code needing to be run?
In my understanding, it helps with implementing asynchronous actions.
I just used them, so I can give a concrete example:
My main thread handles most program logic and rendering. To save CPU it uses ControlFlow::Wait to be put to sleep until new events arrive that may need processing (e.g. user input).
My app loads large images, which can take a while (>1 second), so I do that on separate threads, because otherwise the app would just hang while the load happens The loader thread loads the image, then sends the data over to the main thread for rendering. Once new data arrives, the main thread should update the UI, e.g. switch from showing a loading circle to showing the actual image.
However, without user input, my main thread is sleeping, so it never runs any code that could react to the new data that arrived. To fix that, the loader thread sends a user event, which wakes the main thread up, so that it can run and handle the new data. My user event also contains information about what exactly happened with the loading, e.g. if an image couldn't be loaded, the main thread will be told this way.
You could already achieve this through EventLoopProxy::wakeup previously but I guess it is kind of nice to send a payload along with the signal.
How often is it that:
@cheako Neither of those points seem to be related to this issue, so I ask that you open new issue(s) to discuss them. If you don't have any more questions to ask about send_event, please close this issue.
I'm trying to understand why this feature is a thing and how bad do I need to keep it for my libraries that wrap winit.
Those two points are my guess as to when and why one thread would need to wakeup the winit event loop.
How often is it that:
Winit must run on the main thread? If this is a requirement, and I reasonably think it could be, this is news to me.
This requirement isn't unique to Winit. GLFW works the same way. It's due to the way that the underlying platform APIs work. Custom user events provide a way to send messages back to the main thread.
@cheako These two points do not seam related to the original issue. Please open new ones, so that people searching for similar points can find them in the future.
Most helpful comment
I just used them, so I can give a concrete example:
My main thread handles most program logic and rendering. To save CPU it uses
ControlFlow::Waitto be put to sleep until new events arrive that may need processing (e.g. user input).My app loads large images, which can take a while (>1 second), so I do that on separate threads, because otherwise the app would just hang while the load happens The loader thread loads the image, then sends the data over to the main thread for rendering. Once new data arrives, the main thread should update the UI, e.g. switch from showing a loading circle to showing the actual image.
However, without user input, my main thread is sleeping, so it never runs any code that could react to the new data that arrived. To fix that, the loader thread sends a user event, which wakes the main thread up, so that it can run and handle the new data. My user event also contains information about what exactly happened with the loading, e.g. if an image couldn't be loaded, the main thread will be told this way.