2017-10-22 119 views
1

我有一个典型的SDL事件循环中调用SDL_WaitEvent,跑进热烈讨论的问题(见herehere)在我的应用程序无法调整大小时重新绘制,因为SDL_WaitEvent不返回直到在某些平台上完成调整大小(Win32 & Mac OS)。在每一次讨论中,都提到了使用SDL_SetEventFilter来解决这个问题的技巧,并且或多或少被接受为解决方案和黑客。SDL2 SDL_SetEventFilter VS SDL_WaitEvent

使用SDL_SetEventFilter方法完美地工作,但现在我正在查看我的代码,并且实际上已将我的SDL_WaitEvent中的所有代码移动到EventFilter中,并仅处理那里的事件。

建筑上它的鱼腥味。

除了在单独的线程上被调用的可能性之外,是否有任何问题与这种将消息分派给我的应用程序的方法由SDL_SetEventFilter设置?

奖励问题:SDL如何在内部处理此问题?据我所知,这个调整大小的问题植根于底层平台。例如,Win32将发出WM_SIZING,然后输入自己的内部消息泵,直到发出WM_SIZE。什么是触发SDL EventFilter运行?

+0

什么是违反SDL_PollEvent?而不是无限期地等待事件,只要轮询他们每个周期(如果有的话)。 – skypjack

+0

这没有帮助。 SDL_PollEvent的行为与SDL_WaitEvent的行为完全相同,将会阻止,直到调整大小/移动完成 –

+0

如果它解决了问题,我不会将它作为注释发布,对吧?这只是一个偏离主题的建议。 – skypjack

回答

0

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

SDL处理事件的方式是,当您拨打SDL_WaitEvent/SDL_PeekEvent/SDL_PeepEvents时,它会泵送win32直到没有留言。在该泵期间,它将处理win32消息,并将其转换为队列中的SDL事件,以在泵完成后返回。

win32处理移动/调整大小操作的方法是进入消息泵,直到移动/调整大小完成。这是一个常规的消息泵,所以在这段时间内你的WndProc仍然被调用。你会得到一个WM_ENTERSIZEMOVE,其次是许多WM_SIZINGWM_MOVING消息,然后最后一个WM_EXITSIZEMOVE

这两件事情在一起意味着,当你调用任何SDL事件函数和win32做一个移动/调整大小的操作时,你会被卡住直到拖动完成。

EventFilter解决这个问题的方式是它作为WndProc本身的一部分被调用。这意味着您无需在SDL_Peek/Wait/Peep事件结束时对消息进行排队并将它们交还给您。你立即把它们交给你,作为泵送的一部分。

在我的架构中,这完全适合。因人而异。