REBOL には、従来のマルチタスク/スレッドのサポートがありません。ただし、REBOL/View の GUI を使用してそれを偽造することはできます。これは、サウンドを使用しているため、使用していると思われます。
重要なのは、インターフェイス オブジェクトの 1 つにタイマーを設定して、関数を定期的に呼び出して監視対象の状態をチェックすることです。この例では、alarm 関数を書き直して、alarm-data 変数を設定します。この変数は、レイアウト内の監視オブジェクトから毎秒呼び出されるときに定期関数によってチェックされます (これが、「レート 1 の感じ [engage : :定期]" というものがあります)。
粗野ではありますが、このトリックは、不足しているスレッドを補うのに大いに役立ちます (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."
]
]