events - 使用协程进行事件处理的正确方法是什么?

标签 events lua coroutine

我正在尝试弄清楚如何使用协程(在 Lua 中)处理事件。我发现一种常见的方法似乎是创建包装函数,该函数产生当前的协程,然后在您等待的事情发生时恢复它。这似乎是一个不错的解决方案,但是这些问题怎么办? :

  1. 如何同时等待多个事件,并根据哪个事件先发生进行分支?还是应该重新设计程序以避免这种情况?

  2. 如何在一定时间后取消等待?事件循环可以在其套接字发送/接收包装器中包含超时参数,但是自定义事件呢?

  3. 如何从外部触发协程改变其状态?例如,我想要一个函数,在调用时会导致协程跳转到不同的步骤,或开始等待不同的事件。

编辑:

目前,我有一个系统,我在其中注册一个带有事件的协程,每次事件发生时,协程都会以事件名称和信息作为参数恢复。对于这个系统,1 和 2 不是问题,3 可以通过让 coro 期望一个特殊的事件名称来解决,该名称使其跳转到不同的步骤,并使用该名称作为参数恢复它。自定义对象也可以具有以相同方式注册事件处理程序的方法。

我只是想知道这是否被认为是使用协程进行事件处理的正确方法。例如,如果我有一个读取事件和一个计时器事件(作为读取的超时),并且读取事件首先发生,我必须手动取消计时器。它似乎不符合顺序性质或使用协程处理事件。

最佳答案

How do you wait for multiple events at the same time, and branch depending on which one comes first?

如果你需要为此使用协程,而不仅仅是你注册的 Lua 函数(例如,如果你有一个函数可以做一些事情,等待一个事件,然后做更多的事情),那么这非常简单。当协程恢复时,coroutine.yield 将返回传递给 coroutine.resume 的所有值。

因此,只需传递事件,然后让脚本自行决定是否正在等待该事件。事实上,您可以构建一个简单的函数来执行此操作:

function WaitForEvents(...)
  local events = {...}
  assert(#... ~= 0, "You must pass at least one parameter")

  do
    RegisterForAnyEvent(coroutine.running()) --Registers the coroutine with the system, so that it will be resumed when an event is fired.
    local event = coroutine.yield()
    for i, testEvt in ipairs(events) do
      if(event == testEvt) then
        return
      end
    end
  until(false)
end

此函数将继续产生,直到它所给定的事件之一被触发为止。该循环假定 RegisterForAnyEvent 是临时的,仅注册一个事件的函数,因此每次触发事件时都需要重新注册。

How to cancel the waiting after a certain period?

在上面的循环中放入一个计数器,并在一定时间后离开。我将把它作为练习留给读者;这完全取决于您的应用程序如何测量时间。

How do you trigger the coroutine to change its state from outside?

你不能用魔法将 Lua 函数转变为不同的“状态”。您只能调用函数并让它们返回结果。因此,如果你想在某个进程中跳过,你必须将你的Lua函数系统编写为可跳过的。

如何做到这一点取决于您。您可以让每组非等待命令成为一个单独的 Lua 函数。或者您可以将等待状态设计为能够向前跳过。或者其他什么。

关于events - 使用协程进行事件处理的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11622736/

相关文章:

c# - 在 C# 中取消订阅事件的正确方法是什么?

java - 当 JButton ActionEvent 执行时,如何通知具有 GUI 构建器类实例的类

Lua - 需要回退/错误处理

javascript - 如何检查 Javascript 生成器是否已经退出?

android - 如何停止或取消 Kotlin 协程(立即停止当前运行的代码块)?

c# - 如何让一个协程在其他协程开始之前先完成

c# - 如何在 C# 中绘制流数据图表

javascript - js : trigger function after a bunch of events were called

c - 如何连接两个 Lua lua L_Buffer 对象?

c++ - lua 脚本和应用程序的不同路径