REBOL:如何在等待警报触发时执行另一项任务?

发布于 2024-08-30 01:12:40 字数 445 浏览 1 评论 0原文

所以我创建了一个警报函数:

alarm: func[seconds message [string! unset!]][
     wav: load %attention.wav
     sound-port: open sound://
     wait seconds do [
     insert sound-port wav
     wait sound-port
     close sound-port
     if (value? 'message) [
           print message
        ]
   ]
]

它的工作原理如下:

alarm 30 "Will trigger in 30 seconds"

现在我如何显示一个在等待警报时递增的计时器,因为 Rebol 不支持线程?

So I have created an alarm function:

alarm: func[seconds message [string! unset!]][
     wav: load %attention.wav
     sound-port: open sound://
     wait seconds do [
     insert sound-port wav
     wait sound-port
     close sound-port
     if (value? 'message) [
           print message
        ]
   ]
]

which works like this:

alarm 30 "Will trigger in 30 seconds"

Now how can I for example show a timer which increments while waiting for the alarm since Rebol doesn't support thread ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

后知后觉 2024-09-06 01:12:40

REBOL 没有传统的多任务/线程支持。但是,您可以使用 REBOL/View 中的 GUI 来伪造它,因为您正在使用声音内容,所以我假设您正在使用它。

关键是在您的接口对象之一上设置一个计时器,该计时器定期调用一个函数来检查您想要监视的事物的状态。在此示例中,我重写了警报函数来设置警报数据变量,当周期性函数从布局中的监视器对象每秒调用一次时,将由周期性函数检查该变量(这就是“速率 1 的感觉 [engage] : :periodic]”东西确实如此)。

虽然很粗糙,但这个技巧对于弥补丢失的线程有很大帮​​助(如果你可以忍受 GUI)。您可以检查/更新周期函数中的各种内容,甚至使用状态机实现简单的多任务处理。另请注意,如果您需要多个警报,您可以将警报数据设置为警报列表,而不是单个警报。

另请参阅 http://www.rebol.com/docs/view-face- events.html 了解有关特殊事件处理的更多信息。

REBOL [
    Title: "Alarmer"
    File: %alarm.r
    Author: oofoe
    Date: 2010-04-28
    Purpose: "Demonstrate non-blocking alarm."
]

alarm-data: none

alarm: func [
    "Set alarm for future time."
    seconds "Seconds from now to ring alarm."
    message [string! unset!] "Message to print on alarm."
] [
    alarm-data: reduce [now/time + seconds  message]
]

ring: func [
    "Action for when alarm comes due."
    message [string! unset!]
] [
    set-face monitor either message [message]["RIIIING!"]
    ; Your sound playing can also go here (my computer doesn't have speakers).
]

periodic: func [
    "Called every second, checks alarms."
    fact action event
] [
    if alarm-data [
        ; Update alarm countdown.
        set-face monitor rejoin [
            "Alarm will ring in " 
            to integer! alarm-data/1 - now/time
            " seconds."
        ]

        ; Check alarm.
        if now/time > alarm-data/1 [
            ring alarm-data/2
            alarm-data: none ; Reset once fired.
        ]
    ]
]


view layout [
    monitor: text 256 "Alarm messages will be shown here."  
        rate 1  feel [engage: :periodic]
    button 256 "re/start countdown" [
        alarm 10 "This is the alarm message."
        set-face monitor "Alarm set."
    ]
]

REBOL doesn't have conventional multi-tasking/threading support. However, you can fake it using the GUI in REBOL/View, which since you're using the sound stuff, I assume you're using.

The key is to set a timer on one of your interface objects that periodically calls a function to check on the status of the things you want to monitor. In this example, I've rewritten your alarm function to set the alarm-data variable, which will be checked by the periodic function when it gets called every second from the monitor object in the layout (that's what the "rate 1 feel [engage: :periodic]" stuff does).

While crude, this trick goes a long way to compensate for missing threads (if you can put up with having a GUI). You can check/update all sorts of things in the periodic function, even implement simple multi-tasking with a state machine. Also note that you could set up alarm-data as a list of alarms instead of a single one if you need more than one.

Also see http://www.rebol.com/docs/view-face-events.html for more information about special event handling.

REBOL [
    Title: "Alarmer"
    File: %alarm.r
    Author: oofoe
    Date: 2010-04-28
    Purpose: "Demonstrate non-blocking alarm."
]

alarm-data: none

alarm: func [
    "Set alarm for future time."
    seconds "Seconds from now to ring alarm."
    message [string! unset!] "Message to print on alarm."
] [
    alarm-data: reduce [now/time + seconds  message]
]

ring: func [
    "Action for when alarm comes due."
    message [string! unset!]
] [
    set-face monitor either message [message]["RIIIING!"]
    ; Your sound playing can also go here (my computer doesn't have speakers).
]

periodic: func [
    "Called every second, checks alarms."
    fact action event
] [
    if alarm-data [
        ; Update alarm countdown.
        set-face monitor rejoin [
            "Alarm will ring in " 
            to integer! alarm-data/1 - now/time
            " seconds."
        ]

        ; Check alarm.
        if now/time > alarm-data/1 [
            ring alarm-data/2
            alarm-data: none ; Reset once fired.
        ]
    ]
]


view layout [
    monitor: text 256 "Alarm messages will be shown here."  
        rate 1  feel [engage: :periodic]
    button 256 "re/start countdown" [
        alarm 10 "This is the alarm message."
        set-face monitor "Alarm set."
    ]
]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文