如何将自定义 Pyglet 事件排队,同时将输入和图形事件保持在最高优先级?

Posted

技术标签:

【中文标题】如何将自定义 Pyglet 事件排队,同时将输入和图形事件保持在最高优先级?【英文标题】:How can I queue up custom Pyglet events while keeping input and graphics events at highest priority? 【发布时间】:2015-04-26 21:00:16 【问题描述】:

好的,所以有一个非常长的低优先级函数调用列表。我希望键盘触发的事件继续按时执行,我希望显示器按时继续更新,但是,当这两件事都不需要完成时,我希望所有剩余的 CPU 时间都用于继续遍历低优先级函数调用列表,一一进行。

我尝试通过在处理低优先级事件的事件处理程序的最后一行递归调用dispatch_event 来实现此行为。这个调用是递归的,因为被调度的事件类型是另一个相同类型的低优先级事件。此事件处理程序主体中的代码只是从长列表中弹出一个函数调用,然后执行它。

但是,这不起作用,因为事实证明dispatch_event 实际上会立即触发事件的事件处理程序,而不是将其添加到队列中。因此,结果是执行陷入递归循环,导致堆栈溢出。

那么...我应该怎么做呢?

【问题讨论】:

嗨,你能发布一些相关的代码吗? 【参考方案1】:
#!/usr/bin/python
import pyglet
from time import time, sleep

class Window(pyglet.window.Window):
    def __init__(self, refreshrate):
        super(Window, self).__init__(vsync = False)
        self.frames = 0
        self.framerate = pyglet.text.Label(text='Unknown', font_name='Verdana', font_size=8, x=10, y=10, color=(255,255,255,255))
        self.last = time()
        self.alive = 1
        self.refreshrate = refreshrate

    def on_draw(self):
        self.render()

    def render(self):
        self.clear()
        if time() - self.last >= 1:
            self.framerate.text = str(self.frames)
            self.frames = 0
            self.last = time()
        else:
            self.frames += 1
        self.framerate.draw()
        self.flip()

    def on_close(self):
        self.alive = 0

    def on_key_release(self, symbol, modkey):
            print(symbol, modkey)

    def on_mouse_motion(x, y, dx, dy):
        print('Mouse from:',x,y,'moved:',dx,dy)

    def run(self):
        while self.alive:
            self.render()
            event = self.dispatch_events() # <-- This is the event queue
            sleep(1.0/self.refreshrate)

win = Window(23) # set the fps
win.run()

这可以处理鼠标和键盘,同时不会阻塞任何事件队列。在事件派发器中生成事件或监听事件或在def render() 中进行您需要做的渲染。

【讨论】:

看来这段代码会浪费时间休眠,只会以帧速率的速度执行事件,但不会更快。没有? @user1123936 ofc,这就是帧限制的全部意义所在,将计算机计算能力保留给其他事物并保持机器的帧速率稳定。用户不希望感觉游戏/GUI 在帧率上出现断断续续或上下波动,他们想要稳定帧率的错觉。您可以移除睡眠,但在 def render() 中添加您自己的计时器,这样对象每秒只渲染 X 时间,但 dispatch_events() 仍然以可能的最高速度触发。

以上是关于如何将自定义 Pyglet 事件排队,同时将输入和图形事件保持在最高优先级?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义参数传递给事件处理程序

如何将自定义日志转发到 Azure Sentinel

如何将自定义事件/信号从一个进程发送到 MacOS 中的另一个进程

如何将自定义视图+控制器添加到模型?

将自定义事件表单从一页发送到另一页

php 如何将自定义过滤器字段添加到没有过滤器插件的Tribe事件日历(在此示例中 - 按类别和标记过滤)。示例:https: