This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
api:event:zh [2023/10/12 18:00] hfsr [通用事件处理函数] |
api:event:zh [2023/11/29 13:11] (current) hfsr [通用事件处理函数] |
||
---|---|---|---|
Line 10: | Line 10: | ||
- 让程序在作为前台程序执行时处理事件(优先模式)。 | - 让程序在作为前台程序执行时处理事件(优先模式)。 | ||
- | 在驱动模式下,你需要在程序中为事件注册回调(callback)函数(用 `event.listen()`函数),然后退出程序,以继续执行原先的程序(通常是shell)。 | + | 在驱动模式下,你的程序需要先为事件注册回调函数(用 `event.listen()`函数),然后退出,以继续执行主程序(通常是shell)。 |
- | 而在优先模式下,你无需在程序中注册事件,可以直接使用`events.pull()`函数进行处理。 | + | 在优先模式下,你无需在程序中注册事件,可以直接使用`events.pull()`函数拉取并处理信号。 |
- | //注意://虽然从技术层面上讲可以同时使用两种工作模式,但不推荐这样做。为了保证所有已注册的函数都能接收到事件,事件的一次触发只有在所有函数都被调用后才算结束。因此如果你将处理函数(handler)进行了注册,又执行了拉取(pull)操作,那么同一个事件会被响应两次。 | + | **注意:**虽然从技术层面上讲可以同时使用两种工作模式,但不推荐这样做。为了保证所有已注册的函数都能接收到事件,事件只有在所有函数均被调用后才会被消耗掉。因此如果你注册了处理函数,同时又进行了拉取,那么同一个事件会被响应两次。 |
===== 函数 ===== | ===== 函数 ===== | ||
- `event.listen(event: string, callback: function): boolean` | - `event.listen(event: string, callback: function): boolean` | ||
- | 新注册一个事件侦听器,其会在触发指定事件后被调用。 | + | 注册一个新的事件侦听器,会在指定名称的事件出现后被调用。 |
- | **event(事件)** - 需要侦听的信号名称。\\ | + | **event** - 需要侦听的信号名称。\\ |
- | **callback(回调函数)** - 在收到指定信号后调用的函数。此函数将会接收注册的事件名称作为第一个参数,然后接收触发事件的[[component:signals|信号]]所定义的所有参数。\\ | + | **callback** - 在收到指定信号后调用的函数。此函数将会接收注册的事件名称作为第一个参数,然后接收触发事件的[[component:signals|信号]]所定义的所有参数。\\ |
- | **返回值:**如果注册成功,数据类型为`number`,代表了事件id,可传递给`event.cancel`函数取消事件。如果函数已经注册过此类事件,将会返回`false`。 | + | **返回值:**若注册成功,数据类型为`number`,代表了事件id,可用于传递给`event.cancel`函数取消事件。若函数已经注册过此类事件,将会返回`false`。 |
+ | \\ | ||
- `event.ignore(event: string, callback: function): boolean` | - `event.ignore(event: string, callback: function): boolean` | ||
- | 注销一个事件侦听器。 | + | 注销一个先前注册的事件侦听器。 |
- | **event(事件)** - 需要注销的信号名称。\\ | + | **event** - 需要注销的信号名称。\\ |
- | **callback(回调函数)** - 之前注册到此事件的回调函数。\\ | + | **callback** - 之前注册到此事件的回调函数。\\ |
- | **返回值:**如果事件成功注销则返回`true`。如果指定的函数并未注册到此类事件则返回`false`。\\ | + | **返回值:**若事件成功注销则返回`true`。若指定的函数并未注册到此类事件则返回`false`。\\ |
- | //注意://事件侦听器返回`false`后将会被自动注销。相当于调用 `event.ignore`,并向其传递对应参数。 | + | **注意:**事件侦听器返回`false`后将会注销自身。等价于调用 `event.ignore`,并向其传递侦听器函数与所注册的事件名称。 |
+ | \\ | ||
- `event.timer(interval: number, callback: function[, times: number]): number` | - `event.timer(interval: number, callback: function[, times: number]): number` | ||
- | 开启一个新的定时器,在经过`interval`指定的时长后将会被触发。 | + | 开启一个新的定时器,在经过`interval`指定的时长后将会被触发。 |
- | **interval(触发间隔)** - 调用回调函数的间隔时长,单位为秒。可以为像0.05这样的小数。\\ | + | **interval** - 调用回调函数的间隔时长,单位为秒。可以为像0.05这样的小数。\\ |
- | **callback(回调函数)** - 要调用的函数。\\ | + | **callback** - 要调用的函数。\\ |
- | **times(次数)** - 应调用的次数。如果省略则函数只会被调用一次。指定为`math.huge`可以无限次重复调用。\\ | + | **times** - 应调用的次数。若省略则函数只会被调用一次。指定为`math.huge`可以无限次重复调用。\\ |
**返回值:**定时器id,可以随时用于取消定时器。\\ | **返回值:**定时器id,可以随时用于取消定时器。\\ | ||
- | //注意://定时器的精度可能会发生变化。如果电脑闲置并进入了休眠模式,则电脑只会每游戏刻唤醒一次。因此触发回调函数的时间点可能会偏差至多0.05秒。 | + | **注意:**定时器的精度可能会发生变化。如果电脑闲置并进入了休眠模式,则电脑只会每游戏刻唤醒一次。因此触发回调函数的时间点可能会偏差至多0.05秒。 |
+ | \\ | ||
- `event.cancel(timerId: number): boolean` | - `event.cancel(timerId: number): boolean` | ||
取消某个先前由`event.timer`函数创建的定时器。 | 取消某个先前由`event.timer`函数创建的定时器。 | ||
- | **timerId(定时器id)** - 由`event.timer`函数返回的定时器id。\\ | + | **timerId** - 由`event.timer`函数返回的定时器id。\\ |
- | **返回值:**如果定时器被成功终止则返回`true`。如果不存在指定id对应的定时器则返回`false`。 | + | **返回值:**若定时器被成功终止则返回`true`。若不存在指定id对应的定时器则返回`false`。 |
+ | \\ | ||
- `event.pull([timeout: number], [name: string], ...): string, ...` | - `event.pull([timeout: number], [name: string], ...): string, ...` | ||
- | 从队列中拉取下一个可用事件,或者等待可用事件出现。 | + | 从队列中拉取下一个可用事件,或者等待可用事件出现。 |
- | **timeout(超时时间)** - 如果指定了值,则函数会至多等待此秒数。超时后仍未出现可用事件,则函数会返回`nil`。\\ | + | **timeout** - 若指定了值,则函数会至多等待此秒数。超时后仍未出现可用事件,函数会返回`nil`。\\ |
- | **name(事件名称)** - 目标事件的模式字符串,作为事件的过滤器。如果进行了指定则函数只会返回名称符合此模式的事件。值可以为`nil`,此时事件名称不会被过滤。模式字符串的使用可参考`string.match`函数。\\ | + | **name** - 目标事件的模式字符串,作为事件的过滤器。如果进行了指定则函数只会返回名称符合此模式的事件。值可以为`nil`,此时事件名称不会被过滤。模式字符串的使用可参考`string.match`函数。\\ |
**...** - 任意数量的参数,顺序需要与目标[[component:signals|信号]]所定义的相同。它们会被作为过滤器来筛选信号返回的额外参数,判断方式为是否完全相等。值可以为`nil`,这样将不会过滤此参数。\\ | **...** - 任意数量的参数,顺序需要与目标[[component:signals|信号]]所定义的相同。它们会被作为过滤器来筛选信号返回的额外参数,判断方式为是否完全相等。值可以为`nil`,这样将不会过滤此参数。\\ | ||
- | 样例: | + | 筛选样例: |
- | `touch`信号(在玩家点击二级或三级显示器时触发)带有如下参数:` screenX: number, screenY: number, playerName: string`(点击处的X、Y坐标,进行点击的玩家ID) | + | `touch`信号(在玩家点击2级或3级显示器时触发)带有如下参数:` screenX: number, screenY: number, playerName: string`(点击处的X、Y坐标,进行点击的玩家ID) |
- | 若要仅拉取玩家"Steve"的点击,你需要使用: | + | 若要仅拉取玩家"Steve"的点击,你需要使用: |
- | `local _, x, y = event.pull("touch", nil, nil, "Steve")` | + | `local _, x, y = event.pull("touch", nil, nil, "Steve")` |
- | - `event.pullFiltered([timeout: number], [filter: function]): string, ...` (自1.5.9起) | + | \\ |
- | 从队列中拉取并返回下一个可用事件,或者等待可用事件出现。支持以函数作为过滤器。**timeout(超时时间)** - 如果指定了值,则函数会至多等待此秒数。超时后仍未出现可用事件,则函数会返回`nil`。\\ | + | - `event.pullFiltered([timeout: number], [filter: function]): string, ...`(自1.5.9起添加) |
- | **filter(过滤器)** - 如果指定了值,则此函数将会被作为事件的过滤器。让程序能够进行高级过滤。 | + | 从队列中拉取并返回下一个可用事件,或者等待可用事件出现。支持以函数作为过滤器。 |
+ | **timeout** - 若指定了值,则函数会至多等待此秒数。超时后仍未出现可用事件,则函数会返回`nil`。\\ | ||
+ | **filter** - 若指定了值,则此函数将会被作为事件的过滤器。让程序能够进行高级过滤。 | ||
- | 样例: | + | 样例: |
```lua | ```lua | ||
Line 73: | Line 79: | ||
end | end | ||
- | local e = {event.pullFiltered(filter)} --程序将会不限时等待拉取key_up(松开按键)、key_down(按下按键)和click(点击屏幕)事件。过滤器会确保只拉取allowedPlayers表中的玩家触发的事件。 | + | local e = {event.pullFiltered(filter)} --程序将会不限时等待拉取key_up、key_down和click事件。过滤器会确保只拉取allowedPlayers表中的玩家触发的事件。 |
``` | ``` | ||
- | - `event.pullMultiple(...): ...` (自1.5.9起) | + | - `event.pullMultiple(...): ...`(自1.5.9起添加) |
- | `pullMultiple`函数可接收多个要拉取的事件名称作为参数,同时支持基本的过滤功能。 | + | `pullMultiple`函数可接收多个要拉取的事件名称作为参数,同时支持基本的过滤功能。 |
+ | \\ | ||
- `event.onError(message: any)` | - `event.onError(message: any)` | ||
- | 事件回调函数的全局异常处理函数。如果有事件侦听器抛出异常,此函数将会进行处理,以避免其影响到不相关的代码(指仅调用了`events.pull`函数触发函数执行的代码)。默认情况下,此函数会将报错信息记录到临时文件中。 | + | 全局的异常处理函数,用于处理事件回调函数抛出的错误。若有事件侦听器抛出异常,此函数将会进行处理,以避免其影响到不相关的代码(指仅是调用了`events.pull`函数触发函数执行的代码)。默认情况下,此函数会将报错信息记录到临时文件系统中的文件。 |
- | 如果你想以其他方式处理事件报错,可以将此函数替换为自定义函数。 | + | 如果你想以其他方式处理事件报错,可以将此函数替换为自定义函数。 |
+ | \\ | ||
- `event.push(name: string[, ...])` | - `event.push(name: string[, ...])` | ||
此函数仅仅为[[api:computer|computer.pushSignal]]的别名,并没有对参数进行任何修改。鉴于event(事件) API库中已经有了`event.pull`,添加此别名会更符合逻辑。 | 此函数仅仅为[[api:computer|computer.pushSignal]]的别名,并没有对参数进行任何修改。鉴于event(事件) API库中已经有了`event.pull`,添加此别名会更符合逻辑。 | ||
Line 88: | Line 96: | ||
在OpenOS 1.6.4及更高版本,中断功能已经被删除。下列两个函数现在已经过时。 | 在OpenOS 1.6.4及更高版本,中断功能已经被删除。下列两个函数现在已经过时。 | ||
- | - `event.shouldSoftInterrupt(): boolean` (自1.5.9起添加,在1.6.4被移除) | + | - `event.shouldSoftInterrupt(): boolean`(自1.5.9起添加,在1.6.4被移除) |
- | - `event.shouldInterrupt(): boolean` (自1.5.9起添加,在1.6.4被移除) | + | - `event.shouldInterrupt(): boolean`(自1.5.9起添加,在1.6.4被移除) |
- | 中断是一类用于关闭或停止进程的消息。在OpenOS中`computer.pullSignal()`函数和修饰过的此函数会产生两种类型的事件。 | + | 中断是一类用于关闭或停止进程的消息。在OpenOS中`computer.pullSignal()`函数及其封装会产生两种类型的事件。 |
若`event.pull*()`函数在指定了过滤器但不指定超时时间的情况下执行,一定情况下意味着无限期执行。这两种事件非常有用。 | 若`event.pull*()`函数在指定了过滤器但不指定超时时间的情况下执行,一定情况下意味着无限期执行。这两种事件非常有用。 | ||
- | - 软件中断是在按下`Ctrl+C`时产生的事件信号。信号包含两个参数,事件名称`"interrupted"` (中断)和电脑运行时间。 | + | - 软中断是在按下`Ctrl+C`时产生的事件信号。信号包含两个参数,事件名称`"interrupted"`和电脑运行时间。 |
- | - 硬件中断在按下`Ctrl-Alt-C`时产生。它会通过抛出`"interrupted"`(中断)异常以强制停止`event.pull*()`函数。 | + | - 硬中断在按下`Ctrl-Alt-C`时产生。它会通过抛出`"interrupted"`异常以强制退出`event.pull*()`函数。 |
===== 简易事件处理样例 ===== | ===== 简易事件处理样例 ===== | ||
Line 115: | Line 123: | ||
===== 通用事件处理函数 ===== | ===== 通用事件处理函数 ===== | ||
- | 此处提供了一个较好的通用事件处理函数。此样例中以`event.pull()`函数返回的事件ID作为回调函数列表的键,用元方法来处理未定义事件。请注意`event.pull`函数会让程序进入等待状态,直到出现可用事件。 | + | 此处提供了一个较好的通用事件处理函数。此样例的主要功能是以`event.pull()`函数返回的事件名称作为回调函数列表的键,用元方法来处理未定义事件。请注意`event.pull`函数会让程序进入等待状态,直到出现可用事件。 |
```lua | ```lua | ||
Line 157: | Line 165: | ||
event.listen("key_up", handleEvent) --注册handleEvent函数,使其在key_up事件发生时被调用,然后结束程序 | event.listen("key_up", handleEvent) --注册handleEvent函数,使其在key_up事件发生时被调用,然后结束程序 | ||
``` | ``` | ||
- | 也可以直接注册`myEventHandlers.key_up`,这样的话处理函数(`key_up`函数)会额外收到一个参数(事件名称)作为第一个参数。 | + | 也可以直接注册`myEventHandlers.key_up`,这样的话处理函数会额外收到一个参数(事件名称)作为第一个参数。 |
目录 | 目录 | ||
----------- | ----------- | ||
{{page>api:contents:zh&noheader&noeditbutton&nouser&nofooter}} | {{page>api:contents:zh&noheader&noeditbutton&nouser&nofooter}} |