专栏首页音视频直播技术专家「SDL第四篇」事件处理

「SDL第四篇」事件处理

SDL中的事件处理

要想了解 SDL 的事件处理,我们必须要知道的一个原理是,SDL将所有事件都存放在一个队列中。所有对事件的操作,其实就是对队列的操作。了解了这个原理后,我们再来说SDL提供的 API 就很容易理解了。

  • SDL_PollEvent: 将队列头中的事件抛出来。
  • SDL_WaitEvent: 当队列中有事件时,抛出事件。否则处于阻塞状态,释放 CPU。
  • SDL_WaitEventTimeout: 与SDL_WaitEvent的区别时,当到达超时时间后,退出阻塞状态。
  • SDL_PeekEvent: 从队列中取出事件,但该事件不从队列中删除。
  • SDL_PushEvent: 向队列中插入事件。

SDL只提供了这样几个简单的API,下面们来介绍几个常见的事件:

  • SDL_WindowEvent : Window窗口相关的事件。
  • SDL_KeyboardEvent : 键盘相关的事件。
  • SDL_MouseMotionEvent : 鼠标移动相关的事件。
  • SDL_QuitEvent : 退出事件。
  • SDL_UserEvent : 用户自定义事件。

关于事件更加详的信息可以到 SDL Wiki 上进行查询。现在我们来看一个使用的例子吧。

例子

在我们之前文章的例子中,大家已经发现一个问题,那就是窗口只显示了 3 秒钟,之后就自动消失了。

有的同学可以会通过修改代码最后面的 SDL_Delay 函数,增加它的等待时间让窗口多活一段时间。

但这样的体验实在是太糟糕了。有没有一种好的办法可以解决这个问题呢?能不能窗口一直显示,直到检测到用户按了ctrl+c 或 使用鼠标点击关闭按钮后才关闭呢?

当然是可以的。我们只需要在之前的程序的末尾增加下面这段代码即可。它会一直检测用户是否按下了退出按钮。如果检测到了,则直接退出,否则保持显示状态。

while(!quit){
    SDL_Event event;
    while(SDL_PollEvent(&event)){
        switch(event.type){
            case SDL_QUIT:
               quit = 1;
               break;
            default:
               SDL_Log(".");
        }
    }
}

SDL_PollEvent 与 SDL_WaitEvent

增加了上面的代码,我们的实验程序似乎也显的很正规了。但有一个问题不知你发现没有 ?当我们打开任务管理器时,发现我们的程序居然占了 100% 的 CPU。My GOD!这个的结果是决对不能接受的。

是什么原因造成的呢?我们来仔细看一下我们增加的代码吧。它由两层 while 循环组成,最里面的while循环的意思是,当队列中一直能取出事件,那就让他一直做下去,直到事件队列为空。外面的while循环的意思是,当队列为空的时候,重新执行内部的while循环。

也就是说,这段代码一直在工作,从不休息。所以导致cpu占到了 100%。即然找到了问题的原因,我们就好处理了,只要在外层循环的最后 delay一下,让CPU休息一下就好了。

当然,SDL还为我们提供了 SDL_WaitEvent方法,使用这个API,你的CPU就不会跑到 100%了,因为当它发现队列为空时,它会阻塞在那里,并将CPU释放掉。

即然有 SDL_WaitEvent了,为什么还要有SDL_PollEvent呢?这主要是由于使用的场景不同。对于游戏来说,它要求事件的实时处理; 而对于一些其它实时性不高的case来说,则可以使用 SDL_WaitEvent了。

小结

到此,本文的内容就介绍完了。在本文中主要介绍了SDL是如何处理事件的,SDL为我们提供了非常简单的API,这大大减少了我们的开发成本。

另外,我在文章的最后,介绍了SDL_PollEvent 与 SDL_WaitEvent两个 API的区别。这也是使用 SDL 事件处理中最容易引起困惑的地方。

希望本文能对您有所帮助,谢谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 「SDL第五篇」彻底理解纹理(Texture)

    这是SDL系列文章的第五篇,本文将彻底让你理解什么是纹理。并带你深入探讨SDL的几个重要概念SDL_Window、SDL_Render、SDL_Surface ...

    音视频_李超
  • 「SDL第二篇」窗口渲染

    上一篇文章中我们对SDL作了简单的介绍,重点介绍了如何编译SDL以及如何使用它。在文章的最后我们留下了一个疑问,即虽然我们创建了窗口,但窗口却并没有真正显示出来...

    音视频_李超
  • 「SDL第六篇」孙悟空与多线程

    今天将向大家介绍一下SDL中的多线程的使用。通过下面对SDL 线程与锁相关的API介绍,你会发现,它与 Linux, Windows相关的API几乎是一模一样的...

    音视频_李超
  • SDL系列讲解(二) 环境搭建

    准备环境 这一节,我们讲解下如何搭建SDL 的 Android开发环境。我们当前的电脑环境为: 系统 Window 7 64位 内存 8...

    用户1263308
  • C语言+SDL2 图形化编程

    程设大作业小火车第一版本是命令行界面,第二版本是图形化界面,由于egg库对以后工程开发没有用,我不想用egg库,花了很长时间浏览了一下OpenGL的中文教程,觉...

    饶文津
  • SDL系列讲解(一) 简介

    什么是 SDL Simple DirectMedia Layer(SDL)是一个跨平台开发库,主要提供对音频,键盘,鼠标,操纵杆的操作,通过OpenGL和Di...

    用户1263308
  • 「SDL第五篇」彻底理解纹理(Texture)

    这是SDL系列文章的第五篇,本文将彻底让你理解什么是纹理。并带你深入探讨SDL的几个重要概念SDL_Window、SDL_Render、SDL_Surface ...

    音视频_李超
  • SDL系列讲解(十一) SDL_QUIT流程

    明天会将自己的很早的一部小说发出,一次发出写的所有的六章,如果时间,或者某天突然觉得可以续写了,那么就是它又一次起航了。 工作期间,码了一个记录工作的小说,有兴...

    用户1263308
  • 【音视频连载-003】基础学习篇-SDL 消息循环和事件响应

    为了让窗口显示出来,在程序中写了一个死循环,这几行代码就是 SDL 消息循环和事件响应的核心缩影了。

    glumes
  • SDL系列讲解(十) 按键处理流程

    SDL系列讲解(一) 简介 SDL系列讲解(二) 环境搭建 SDL系列讲解(三) 工具安装 SDL是什么,能干什么,为什么我们要学习它? SDL系列讲解(四)...

    用户1263308

扫码关注云+社区

领取腾讯云代金券