REBOL 没有传统的多任务/线程支持。但是,您可以使用 REBOL/View 中的 GUI 来伪造它,因为您使用的是声音的东西,我假设您正在使用它。
关键是在您的一个接口对象上设置一个计时器,该对象定期调用一个函数来检查您要监视的事物的状态。在这个例子中,我重写了你的警报函数来设置警报数据变量,当它每秒从布局中的监视器对象调用时,周期性函数将检查它(这就是“速率 1 的感觉 [参与: :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."
]
]