2017-10-22 1 views
1

hatte ich eine typische SDL Ereignisschleife SDL_WaitEvent Aufruf und lief in eine viel diskutierte Frage (siehe here und here), wo meine Anwendung nicht in der Lage war während eines Resize wieder Unentschieden, weil SDL_WaitEvent nicht zurückgibt bis eine Größenänderung auf bestimmten Plattformen abgeschlossen ist (Win32 & Mac OS). In jeder dieser Diskussionen wird die Technik, SDL_SetEventFilter zu benutzen, um es zu umgehen, erwähnt und mehr oder weniger als eine Lösung und ein Hack akzeptiert.SDL2 SDL_SetEventFilter vs SDL_WaitEvent

Die Verwendung der SDL_SetEventFilter Ansatz funktioniert perfekt, aber jetzt schaue ich auf meinen Code und ich habe praktisch den gesamten Code von meinem SDL_WaitEvent in meinem EventFilter bewegt und nur Ereignisse dort zu behandeln.

Architektonisch ist es fischig wie heck.

Gibt es irgendwelche Probleme mit diesem Ansatz des Versendens von Nachrichten an meine Anwendung in der Funktion SDL_SetEventFilter eingestellt, neben der Möglichkeit, in einem separaten Thread aufgerufen werden?

Bonusfrage: Wie geht SDL intern damit um? Soweit ich weiß, ist dieses Größenänderungsproblem in der zugrunde liegenden Plattform verwurzelt. Zum Beispiel gibt Win32 ein WM_SIZING aus und gibt dann seine eigene interne Nachrichtenpumpe ein, bis WM_SIZE ausgegeben wird. Was löst den SDL EventFilter aus?

+0

Was ist gegen 'SDL_PollEvent'? Anstatt unbegrenzt auf Ereignisse zu warten, können Sie sie in jedem Zyklus abfragen. – skypjack

+0

Das hilft nicht. SDL_PollEvent verhält sich genau wie SDL_WaitEvent und blockiert so lange, bis die Größenänderung/Verschiebung abgeschlossen ist. –

+0

Wenn das Problem gelöst wurde, würde ich es nicht als Kommentar posten, oder? Es war nur ein Vorschlag außerhalb des Themas. – skypjack

Antwort

0

Beantworten meiner eigenen Frage nach mehr Experimenten und Sichten durch die Quelle.

Die Art und Weise, wie SDL Ereignisse verarbeitet, besteht darin, dass beim Aufruf von SDL_WaitEvent/SDL_PeekEvent/SDL_PeepEvents win32 solange gepumpt wird, bis keine Nachrichten mehr vorliegen. Während dieses Pumpens verarbeitet es die Win32-Nachrichten und wandelt sie in SDL-Ereignisse um, die in die Warteschlange gestellt werden, um nach Abschluss der Pumpe zurückzukehren.

Die Art und Weise, wie win32 Verschiebe-/Größenänderungsoperationen durchführt, besteht darin, in eine Nachrichtenpumpe zu gehen, bis die Verschiebung/Größenänderung abgeschlossen ist. Es ist eine normale Nachrichtenpumpe, daher wird Ihr WndProc während dieser Zeit immer noch aufgerufen. Sie erhalten eine WM_ENTERSIZEMOVE, gefolgt von vielen WM_SIZING oder WM_MOVING Nachrichten, dann endlich eine WM_EXITSIZEMOVE.

Diese zwei Dinge zusammen bedeutet, dass, wenn Sie eine der SDL-Ereignisfunktionen aufrufen und win32 macht eine Verschiebung/Größenänderung Operation, Sie stecken bleiben, bis das Ziehen abgeschlossen ist.

Die Art und Weise, wie EventFilter damit umgehen kann, ist, dass es als Teil des WndProc selbst aufgerufen wird. Das bedeutet, dass Sie am Ende von SDL_Peek/Wait/Peep Event keine Nachrichten in Warteschlange stellen und sie Ihnen zurückgeben müssen. Sie erhalten sie sofort als Teil des Pumpens.

In meiner Architektur passt das perfekt. YMMV.