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_SIZING
或 WM_MOVING
消息,最后是 WM_EXITSIZEMOVE
.
这两件事一起意味着当您调用任何 SDL 事件函数并且 win32 执行 move/resize 操作时,您会卡住直到拖动完成。
EventFilter 解决这个问题的方法是它作为 WndProc 本身的一部分被调用。这意味着您不需要排队消息并在 SDL_Peek/Wait/Peep 事件结束时将它们交还给您。作为抽水的一部分,您会立即将它们交给您。
在我的架构中,这非常适合。 YMMV.
我有一个典型的 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_SIZING
或 WM_MOVING
消息,最后是 WM_EXITSIZEMOVE
.
这两件事一起意味着当您调用任何 SDL 事件函数并且 win32 执行 move/resize 操作时,您会卡住直到拖动完成。
EventFilter 解决这个问题的方法是它作为 WndProc 本身的一部分被调用。这意味着您不需要排队消息并在 SDL_Peek/Wait/Peep 事件结束时将它们交还给您。作为抽水的一部分,您会立即将它们交给您。
在我的架构中,这非常适合。 YMMV.