vibe-d / eventcore

High performance proactor event loop abstraction library
MIT License
60 stars 42 forks source link

What EventDrive* should I use to react to WinAPI gui messages? #174

Closed drug007 closed 3 years ago

drug007 commented 3 years ago

In X11 I adopt display fd by means of EventDriverSockets.adopStream and use waitForData to register a callback. But I can not realize what to do in case of Windows...

s-ludwig commented 3 years ago

On Windows, you should use the default "WinAPI" driver. It will use MsgWaitForMultipleObjectsEx for its event loop and calls TranslateMessage/DispatchMessage, so that all window messages are dispatched to their window procedure as usual.

If you need any advanced message processing, such as classical dialog handling (IsDialogMessage), this would need an additional message hook API, but that would be quick to add.

drug007 commented 3 years ago

It will use MsgWaitForMultipleObjectsEx for its event loop and calls TranslateMessage/DispatchMessage, so that all window messages are dispatched to their window procedure as usual.

I understand that from the source code easily. But I can't realize what API should I use to add a callback, the event driver has the individual driver features like sockets, pipes etc. In X11 I use sockets and waitForData, what one of these features should I use in Windows? I'm a linux user in general so some obvious things can elude me.

s-ludwig commented 3 years ago

This is done via the window procedure, which is set using RegisterClass (WNDCLASS.lpfnWndProc member). Whenever a window is then created with that particular class name, the window procedure will be called for each message that goes to the window (done by DispatchMessage).

drug007 commented 3 years ago

Ok, I see. So eventcore encapsulates native windows message loop. But when I register a class and create the window, eventDriver exits the event loop because it has zero waiters. So I need to do something more...

drug007 commented 3 years ago

I added a dummy timer and the native window works as expected except on closing the window event loop continue to work because of the dummy timer. Probably better would be to create a dummy event and then sending it on WM_DESTROY message to gracefully exit of event loop. Is it right (ideomatic to eventcore) approach?

drug007 commented 3 years ago

Now I create an event and trigger it on WM_DESTROY. It works but I get:

Warning: Event handles leaked at driver shutdown.

But as I can see the event callback is removed on triggering and eventcore does not provide API to remove an event manually. How to exit the event loop gracefully?

s-ludwig commented 3 years ago

Interesting, I never came across this issue, apparently because vibe-core starts to wait for an event (eventdriver.events) as soon as its event loop starts. That event is used for other threads to signal a manual event loop exit. So creating an event, calling wait on it and then cancelWait/releaseRef after the window got closed should work properly.

I wonder if that should be something to document as a recommended way to handle windows, or if there should rather be a Windows-specific API addition, such as exposing addWaiter/removeWaiter.

drug007 commented 3 years ago

releaseRef is what I need. Currently I think that custom event is ideomatic way to achive the goal, no need to expose addWaiter/removeWaiter they should belong to private API.