SDL2 SDL_SetEventFilter 对比 SDL_WaitEvent

SDL2 SDL_SetEventFilter vs SDL_WaitEvent

我有一个典型的 SDL 事件循环调用 SDL_WaitEvent,并且 运行 成为一个备受讨论的问题(参见 here and here),我的应用程序在调整大小,因为 SDL_WaitEvent 不会 return 直到在某些平台上完成调整大小(Win32 & Mac OS)。在这些讨论中的每一个中,都提到了使用 SDL_SetEventFilter 来绕过它的技术,并且或多或少地被接受为一种解决方案和技巧。

使用 SDL_SetEventFilter 方法效果很好,但现在我正在查看我的代码,实际上我已经将所有代码从我的 SDL_WaitEvent 移到了我的 EventFilter 中,并在那里处理事件。

从建筑的角度来看,它很可疑。

除了可以在单独的线程上调用之外,这种在 SDL_SetEventFilter 设置的函数中向我的应用程序发送消息的方法是否有任何问题?

额外问题:SDL 如何在内部处理此问题?据我了解,此调整大小问题根源于底层平台。例如,Win32 将发出一个 WM_SIZING,然后进入它自己的内部消息泵,直到发出 WM_SIZE。是什么触发了 SDL EventFilter 运行?

经过更多实验和筛选源后回答我自己的问题。

SDL 处理事件的方式是,当您调用 SDL_WaitEvent/SDL_PeekEvent/SDL_PeepEvents 时,它会发送 win32,直到没有消息为止。在该泵期间,它将处理 win32 消息并将它们转换为 SDL 事件,在泵完成后将其排队到 return。

win32 处理 move/resize 操作的方式是进入消息泵,直到 moving/resizing 完成。这是一个常规的消息泵,因此您的 WndProc 在此期间仍会被调用。您将收到 WM_ENTERSIZEMOVE,然后是许多 WM_SIZINGWM_MOVING 消息,最后是 WM_EXITSIZEMOVE.

这两件事一起意味着当您调用任何 SDL 事件函数并且 win32 执行 move/resize 操作时,您会卡住直到拖动完成。

EventFilter 解决这个问题的方法是它作为 WndProc 本身的一部分被调用。这意味着您不需要排队消息并在 SDL_Peek/Wait/Peep 事件结束时将它们交还给您。作为抽水的一部分,您会立即将它们交给您。

在我的架构中,这非常适合。 YMMV.