在'while'中测试'SDL_PollEvent'的正确方法

时间:2015-04-17 18:31:45

标签: c++ c sdl sdl-2

正如手册所说,函数SDL_PollEvent"如果有待处理事件,则返回1;如果没有可用事件,则返回0。"这就是我们使用测试SDL_PollEvent(&e)!=0eSDL_Event)的原因。

但是,使用此测试怎么样:!SDL_PollEvent(&e)?它应该有效,但显然会引起一些问题。

这是一个代码示例:

    #include <SDL2/SDL.h>
    #include <stdio.h>

    int main(int argc, char* args[]){
      SDL_Init(SDL_INIT_VIDEO);
      SDL_Window* window =   SDL_CreateWindow("Hello",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100,  SDL_WINDOW_SHOWN);
      SDL_Event e;
      int quit=0;
      while(!quit){
          //Here the test
          while (!SDL_PollEvent(&e)){
             if (e.type==SDL_QUIT)
                quit=1;
             else if ( e.type == SDL_KEYDOWN )
                printf( "Hello\n" );
          }
      }
      SDL_DestroyWindow(window);
      SDL_Quit();
      return 0;
   }

这段代码应该做的是打开一个新窗口并打印&#34; Hello&#34;每次按下一个键,在控制台中。此代码可以很好地处理测试SDL_PollEvent(&e)!=0但是当我使用测试SDL_KEYDOWN时它没有读取!SDL_PollEvent(&e)事件(但它会在while中输入并处理SDL_QUIT 1}}没有任何问题的事件) 为什么会出现这种情况?

3 个答案:

答案 0 :(得分:6)

while (!SDL_PollEvent(&e))

需要:

while (SDL_PollEvent(&e))

如果它应与SDL_PollEvent(&e) != 0

相同

因为!SDL_PollEvent(&e)与调用while(0)

相同

答案 1 :(得分:2)

(1 != 0)为真,但(!1)为假。

无论如何,您可能应该使用SDL_WaitEvent

答案 2 :(得分:0)

附录

人们可能认为做这样的事情更清楚,因为它确保对用户输入做出反应。然而,这目前是一个依赖于操作系统的,可能是疯狂的 CPU 猪,并且会为这个线程(在 Windows 上)最大化你的 CPU。因此,您可能认为您可以在那里等待 1 秒钟,但是您的窗口充其量将变得完全没有响应或非常滞后...... 如果您可以忍受一点 CPU 开销而无所作为,那么您可以妥协使用 20-100 [ms] 延迟。

...
    // Set the event handler...
    ...
    bool isRunning = true;
    while (isRunning) {
        // Do the main thing here...
        ...
        while(SDL_PollEvent(&windowEvent)) {
            switch (windowEvent.type) {
                case SDL_QUIT:              isRunning = false;
                case SDL_KEYDOWN:           isRunning = false;
                case SDL_MOUSEBUTTONDOWN:   isRunning = false;
                break;
            }
            SDL_Delay(100); // Wrong!
        }
    }
    // End the program

很明显,这也不是正确的方法。我们需要使用其他一些机制。查看 SDL 存储库,我们发现了一个关于未解决问题的冗长但非常相关的讨论:


解决问题

确保将延迟放在外循环中,在 SDL_PollEvent() 之前。

    // main loop
    ...
        while(SDL_PollEvent(&windowEvent)) {
            switch (windowEvent.type) {
                case SDL_QUIT:              isRunning = false;
                case SDL_KEYDOWN:           isRunning = false;
                case SDL_MOUSEBUTTONDOWN:   isRunning = false;
                break;
            }
        }
        SDL_Delay(100); // Right!
    }