Events: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: added/changed whitespace and comments, aligned statements, used a template for the output section.) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 28: | Line 28: | ||
The event interface: |
The event interface: |
||
< |
<syntaxhighlight lang="ada">protected type Event is |
||
procedure Signal; |
procedure Signal; |
||
procedure Reset; |
procedure Reset; |
||
Line 34: | Line 34: | ||
private |
private |
||
Fired : Boolean := False; |
Fired : Boolean := False; |
||
end Event;</ |
end Event;</syntaxhighlight> |
||
The event implementation: |
The event implementation: |
||
< |
<syntaxhighlight lang="ada">protected body Event is |
||
procedure Signal is |
procedure Signal is |
||
begin |
begin |
||
Line 49: | Line 49: | ||
null; |
null; |
||
end Wait; |
end Wait; |
||
end Event;</ |
end Event;</syntaxhighlight> |
||
With the event defined above: |
With the event defined above: |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
procedure Test_Events is |
procedure Test_Events is |
||
Line 68: | Line 68: | ||
Put_Line ("Signal X"); |
Put_Line ("Signal X"); |
||
X.Signal; |
X.Signal; |
||
end Test_Events;</ |
end Test_Events;</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 77: | Line 77: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">SetTimer, internal, 1000 |
||
Return |
Return |
||
Line 87: | Line 87: | ||
F2:: ; external event: fire on F2 key press |
F2:: ; external event: fire on F2 key press |
||
TrayTip, external, f2 key pressed |
TrayTip, external, f2 key pressed |
||
Return</ |
Return</syntaxhighlight> |
||
=={{header|BASIC256}}== |
=={{header|BASIC256}}== |
||
{{trans|Gambas}} |
{{trans|Gambas}} |
||
<syntaxhighlight lang="basic256"> |
|||
<lang BASIC256> |
|||
subroutine Timer1_Timer() |
subroutine Timer1_Timer() |
||
print hour; ":"; minute; ":"; second |
print hour; ":"; minute; ":"; second |
||
end subroutine |
end subroutine |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 107: | Line 107: | ||
===API=== |
===API=== |
||
This uses a Windows event object: |
This uses a Windows event object: |
||
< |
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB" |
||
WAIT_TIMEOUT = 258 |
WAIT_TIMEOUT = 258 |
||
Line 123: | Line 123: | ||
DEF PROCelapsed |
DEF PROCelapsed |
||
SYS "SetEvent", hEvent% |
SYS "SetEvent", hEvent% |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
===Native=== |
===Native=== |
||
This uses a simple variable as a semaphore: |
This uses a simple variable as a semaphore: |
||
< |
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB" |
||
Event% = FALSE |
Event% = FALSE |
||
Line 141: | Line 141: | ||
DEF PROCelapsed |
DEF PROCelapsed |
||
Event% = TRUE |
Event% = TRUE |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
=={{header|C}}== |
=={{header|C}}== |
||
Using pipe to communicate to <code>fork</code>ed child. Since child will be blocking trying to read the other end of the pipe, this can be used for synchronization. |
Using pipe to communicate to <code>fork</code>ed child. Since child will be blocking trying to read the other end of the pipe, this can be used for synchronization. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <unistd.h> |
#include <unistd.h> |
||
Line 163: | Line 163: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Timers; |
using System.Timers; |
||
Line 185: | Line 185: | ||
((Timer)sender).Stop(); |
((Timer)sender).Stop(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre>10-11-2010 18:35:11 |
<pre>10-11-2010 18:35:11 |
||
Line 192: | Line 192: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="lisp">(ns async-example.core |
||
(:require [clojure.core.async :refer [>! <! >!! <!! go chan]]) |
(:require [clojure.core.async :refer [>! <! >!! <!! go chan]]) |
||
(:require [clj-time.core :as time]) |
(:require [clj-time.core :as time]) |
||
Line 229: | Line 229: | ||
; Invoke -main function |
; Invoke -main function |
||
(-main) |
(-main) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Output}} |
{{Output}} |
||
<pre> |
<pre> |
||
Line 240: | Line 240: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">program Events; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 293: | Line 293: | ||
end; |
end; |
||
Readln; |
Readln; |
||
end.</ |
end.</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 301: | Line 301: | ||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">def makeEvent() { |
||
def [var fired, var firer] := Ref.promise() |
def [var fired, var firer] := Ref.promise() |
||
Line 324: | Line 324: | ||
return event |
return event |
||
}</ |
}</syntaxhighlight> |
||
The event object has this behavior: the return value of <code>.wait()</code> will be resolved after the time of the earliest <code>.signal()</code> for which there is no intervening <code>.reset()</code>. |
The event object has this behavior: the return value of <code>.wait()</code> will be resolved after the time of the earliest <code>.signal()</code> for which there is no intervening <code>.reset()</code>. |
||
< |
<syntaxhighlight lang="e">def e := makeEvent() |
||
{ |
{ |
||
Line 341: | Line 341: | ||
}) |
}) |
||
println("[1] Waiting 1 second...") |
println("[1] Waiting 1 second...") |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Erlang}} |
{{trans|Erlang}} |
||
< |
<syntaxhighlight lang="elixir">defmodule Events do |
||
def log(msg) do |
def log(msg) do |
||
time = Time.utc_now |> to_string |> String.slice(0..7) |
time = Time.utc_now |> to_string |> String.slice(0..7) |
||
Line 372: | Line 372: | ||
end |
end |
||
Events.main</ |
Events.main</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 385: | Line 385: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Events can be implemented by using the selective receive expression and erlang's built in message passing. Here task waits for the message 'go' before it will continue. |
Events can be implemented by using the selective receive expression and erlang's built in message passing. Here task waits for the message 'go' before it will continue. |
||
< |
<syntaxhighlight lang="erlang"> |
||
-module(events). |
-module(events). |
||
-compile(export_all). |
-compile(export_all). |
||
Line 408: | Line 408: | ||
P ! go, |
P ! go, |
||
timer:sleep(100). |
timer:sleep(100). |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
< |
<syntaxhighlight lang="erlang"> |
||
66> events:main(). |
66> events:main(). |
||
0: 0:57 => Program start |
0: 0:57 => Program start |
||
Line 418: | Line 418: | ||
0: 0:58 => Task resumed |
0: 0:58 => Task resumed |
||
ok |
ok |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="fsharp">open System |
||
open System.Timers |
open System.Timers |
||
Line 436: | Line 436: | ||
timer.Start() |
timer.Start() |
||
ignore <| Console.ReadLine() |
ignore <| Console.ReadLine() |
||
0</ |
0</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
{{trans|Gambas}} |
{{trans|Gambas}} |
||
< |
<syntaxhighlight lang="freebasic"> |
||
Sub Timer1_Timer() |
Sub Timer1_Timer() |
||
Print Time |
Print Time |
||
End Sub |
End Sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 453: | Line 453: | ||
=={{header|Gambas}}== |
=={{header|Gambas}}== |
||
< |
<syntaxhighlight lang="gambas">Public Sub Timer1_Timer() |
||
Print Str(Time(Now)) |
Print Str(Time(Now)) |
||
End</ |
End</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 472: | Line 472: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
A Go channel can represent an manual-reset event, as described by the task. The two states of signaled and reset correspond to the presence or absence of a value on the channel. The program signals by sending a value on the channel. The event is reset when the waiting task explicitly executes the channel receive operation, <-event. |
A Go channel can represent an manual-reset event, as described by the task. The two states of signaled and reset correspond to the presence or absence of a value on the channel. The program signals by sending a value on the channel. The event is reset when the waiting task explicitly executes the channel receive operation, <-event. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 494: | Line 494: | ||
event <- 0 |
event <- 0 |
||
time.Sleep(100 * time.Millisecond) |
time.Sleep(100 * time.Millisecond) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 505: | Line 505: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">import Control.Concurrent (threadDelay, forkIO) |
||
import Control.Concurrent.SampleVar |
import Control.Concurrent.SampleVar |
||
Line 515: | Line 515: | ||
signalEvent (Event sv) = writeSampleVar sv () |
signalEvent (Event sv) = writeSampleVar sv () |
||
resetEvent (Event sv) = emptySampleVar sv |
resetEvent (Event sv) = emptySampleVar sv |
||
waitEvent (Event sv) = readSampleVar sv</ |
waitEvent (Event sv) = readSampleVar sv</syntaxhighlight> |
||
< |
<syntaxhighlight lang="haskell">main = do e <- newEvent |
||
forkIO (waitTask e) |
forkIO (waitTask e) |
||
putStrLn "[1] Waiting 1 second..." |
putStrLn "[1] Waiting 1 second..." |
||
Line 526: | Line 526: | ||
waitTask e = do putStrLn "[2] Waiting for event..." |
waitTask e = do putStrLn "[2] Waiting for event..." |
||
waitEvent e |
waitEvent e |
||
putStrLn "[2] Received event."</ |
putStrLn "[2] Received event."</syntaxhighlight> |
||
Note: Because there is no serialization of the text output, there is a chance that it will appear interleaved. |
Note: Because there is no serialization of the text output, there is a chance that it will appear interleaved. |
||
Line 533: | Line 533: | ||
The following only works in Unicon. The example illustrates the multiple tasks can |
The following only works in Unicon. The example illustrates the multiple tasks can |
||
receive the same event: |
receive the same event: |
||
< |
<syntaxhighlight lang="unicon">record Event(cond, value) |
||
procedure main() |
procedure main() |
||
Line 552: | Line 552: | ||
signal(event.cond,0) |
signal(event.cond,0) |
||
every wait(t1|t2) |
every wait(t1|t2) |
||
end</ |
end</syntaxhighlight> |
||
Sample run: |
Sample run: |
||
Line 567: | Line 567: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
An example using the [[wp:Yahoo!_UI_Library|YUI]] library: |
An example using the [[wp:Yahoo!_UI_Library|YUI]] library: |
||
< |
<syntaxhighlight lang="javascript">YUI().use('event-custom', function(Y) { |
||
// add a custom event: |
// add a custom event: |
||
Y.on('my:event', function () { |
Y.on('my:event', function () { |
||
Line 576: | Line 576: | ||
Y.fire('my:event'); |
Y.fire('my:event'); |
||
}, 1000); |
}, 1000); |
||
});</ |
});</syntaxhighlight> |
||
An example simulating [[wp:Document_Object_Model|DOM]] events: |
An example simulating [[wp:Document_Object_Model|DOM]] events: |
||
< |
<syntaxhighlight lang="javascript">YUI().use('node-event-simulate', function(Y) { |
||
// add a click event handler to a DOM node with id "button": |
// add a click event handler to a DOM node with id "button": |
||
Y.one("#button").on("click", function (e) { |
Y.one("#button").on("click", function (e) { |
||
Line 587: | Line 587: | ||
Y.one("#button").simulate("click"); |
Y.one("#button").simulate("click"); |
||
}, 1000); |
}, 1000); |
||
});</ |
});</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 594: | Line 594: | ||
between two child threads. |
between two child threads. |
||
< |
<syntaxhighlight lang="julia"> |
||
function dolongcomputation(cond) |
function dolongcomputation(cond) |
||
det(rand(4000, 4000)) |
det(rand(4000, 4000)) |
||
Line 615: | Line 615: | ||
sleep(5) |
sleep(5) |
||
println("Done sleeping.") |
println("Done sleeping.") |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}}<pre> |
{{output}}<pre> |
||
Starting task, sleeping... |
Starting task, sleeping... |
||
Line 628: | Line 628: | ||
Paste in the REPL: |
Paste in the REPL: |
||
< |
<syntaxhighlight lang="lisp"> |
||
(defun log (msg) |
(defun log (msg) |
||
(let ((`#(,h ,m ,s) (erlang:time))) |
(let ((`#(,h ,m ,s) (erlang:time))) |
||
Line 648: | Line 648: | ||
(! pid 'go) |
(! pid 'go) |
||
(timer:sleep 100)))) |
(timer:sleep 100)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Usage: |
Usage: |
||
Line 667: | Line 667: | ||
To catch an event, a corresponding event handler - a function with a predefined name - has to be definined in the code. Examples for such event handlers are: |
To catch an event, a corresponding event handler - a function with a predefined name - has to be definined in the code. Examples for such event handlers are: |
||
< |
<syntaxhighlight lang="lingo">-- the current window was closed |
||
on closeWindow |
on closeWindow |
||
... |
... |
||
Line 675: | Line 675: | ||
on mouseDown |
on mouseDown |
||
... |
... |
||
end</ |
end</syntaxhighlight> |
||
Also "Sprites" (visual elements) receive events by setting up such event handlers in scripts attached to them. Both predefined and custom events can be sent programmatically to sprites, e.g. using: |
Also "Sprites" (visual elements) receive events by setting up such event handlers in scripts attached to them. Both predefined and custom events can be sent programmatically to sprites, e.g. using: |
||
< |
<syntaxhighlight lang="lingo">-- send event #mouseDown programmatically to sprite 1 |
||
sendSprite(1, #mouseDown) |
sendSprite(1, #mouseDown) |
||
Line 684: | Line 684: | ||
-- send custom event #fooBar to all existing sprites |
-- send custom event #fooBar to all existing sprites |
||
sendAllSprites(#fooBar)</ |
sendAllSprites(#fooBar)</syntaxhighlight> |
||
Using a binary plugin ("Xtra"), in Windows also lower level window messages can be both sent and received: |
Using a binary plugin ("Xtra"), in Windows also lower level window messages can be both sent and received: |
||
{{libheader|Msg Xtra}} |
{{libheader|Msg Xtra}} |
||
< |
<syntaxhighlight lang="lingo">mx = xtra("Msg").new() |
||
-- send message WM_LBUTTONDOWN to a specific window identified by HWND hwnd |
-- send message WM_LBUTTONDOWN to a specific window identified by HWND hwnd |
||
Line 702: | Line 702: | ||
WM_COPYDATA = 74 |
WM_COPYDATA = 74 |
||
WM_MOUSEWHEEL = 522 |
WM_MOUSEWHEEL = 522 |
||
mx.msg_listen([WM_COPYDATA, WM_MOUSEWHEEL], VOID, #msgReceived)</ |
mx.msg_listen([WM_COPYDATA, WM_MOUSEWHEEL], VOID, #msgReceived)</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Mathematica supports events from timers (via Pause[]), task schedule descriptors. This will print a message after 4 seconds, then terminate the program. |
Mathematica supports events from timers (via Pause[]), task schedule descriptors. This will print a message after 4 seconds, then terminate the program. |
||
< |
<syntaxhighlight lang="mathematica">Print["Will exit in 4 seconds"]; Pause[4]; Quit[] |
||
->Will exit in 4 seconds</ |
->Will exit in 4 seconds</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="nim">import posix |
||
var p: array[2, cint] |
var p: array[2, cint] |
||
Line 724: | Line 724: | ||
discard close p[1] |
discard close p[1] |
||
discard p[0].read(addr p[1], 1) |
discard p[0].read(addr p[1], 1) |
||
echo "received signal from pipe"</ |
echo "received signal from pipe"</syntaxhighlight> |
||
===Stdlib Semaphore=== |
===Stdlib Semaphore=== |
||
This version using locks module for signaling the condition. |
This version using locks module for signaling the condition. |
||
< |
<syntaxhighlight lang="nim">import locks |
||
from os import sleep |
from os import sleep |
||
import times |
import times |
||
Line 758: | Line 758: | ||
deinitLock lock |
deinitLock lock |
||
main()</ |
main()</syntaxhighlight> |
||
Compile and run: <pre>nim c -r --threads:on events_cond.nim</pre> |
Compile and run: <pre>nim c -r --threads:on events_cond.nim</pre> |
||
Line 771: | Line 771: | ||
An event is often implemented with a control channel. A task is waiting for an object on the channel. When the event occurs, another task sends an object on this channel. |
An event is often implemented with a control channel. A task is waiting for an object on the channel. When the event occurs, another task sends an object on this channel. |
||
< |
<syntaxhighlight lang="oforth">: anEvent |
||
| ch | |
| ch | |
||
Channel new ->ch |
Channel new ->ch |
||
#[ ch receive "Ok, event is signaled !" println ] & |
#[ ch receive "Ok, event is signaled !" println ] & |
||
System sleep(1000) |
System sleep(1000) |
||
ch send($myEvent) ;</ |
ch send($myEvent) ;</syntaxhighlight> |
||
An emitter is a general implementation for handling events : an emitter waits for events emitted and launches listeners that are waiting for those events. |
An emitter is a general implementation for handling events : an emitter waits for events emitted and launches listeners that are waiting for those events. |
||
< |
<syntaxhighlight lang="oforth">import: emitter |
||
: anEvent2 |
: anEvent2 |
||
Line 789: | Line 789: | ||
$myEvent e emit |
$myEvent e emit |
||
] |
] |
||
e close ;</ |
e close ;</syntaxhighlight> |
||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
Events can be implemented as mutable references to dataflow variables: |
Events can be implemented as mutable references to dataflow variables: |
||
< |
<syntaxhighlight lang="oz">declare |
||
fun {NewEvent} |
fun {NewEvent} |
||
{NewCell _} |
{NewCell _} |
||
Line 822: | Line 822: | ||
{Delay 1000} |
{Delay 1000} |
||
{System.showInfo "[1] Signaling event."} |
{System.showInfo "[1] Signaling event."} |
||
{SignalEvent E}</ |
{SignalEvent E}</syntaxhighlight> |
||
However, this code is quite unidiomatic. If we need to wait for an event just once (like in this example), we can simply use a dataflow variable, i.e. an event that cannot be reset: |
However, this code is quite unidiomatic. If we need to wait for an event just once (like in this example), we can simply use a dataflow variable, i.e. an event that cannot be reset: |
||
< |
<syntaxhighlight lang="oz">declare |
||
E |
E |
||
in |
in |
||
Line 836: | Line 836: | ||
{Delay 1000} |
{Delay 1000} |
||
{System.showInfo "[1] Signaling event."} |
{System.showInfo "[1] Signaling event."} |
||
E = unit</ |
E = unit</syntaxhighlight> |
||
If we want to synchronize two threads repeatedly and exchange data, it is natural to use ports and streams. Streams are just lists with an unbound tail. A port is basically a pointer to the tail of a list, i.e. it keeps track of where the next event can be written to: |
If we want to synchronize two threads repeatedly and exchange data, it is natural to use ports and streams. Streams are just lists with an unbound tail. A port is basically a pointer to the tail of a list, i.e. it keeps track of where the next event can be written to: |
||
< |
<syntaxhighlight lang="oz">declare |
||
MyPort |
MyPort |
||
in |
in |
||
Line 857: | Line 857: | ||
{System.showInfo "[1] Signaling event."} |
{System.showInfo "[1] Signaling event."} |
||
{Port.send MyPort unit} |
{Port.send MyPort unit} |
||
end</ |
end</syntaxhighlight> |
||
It is important to limit the scope of a stream as much as possible to ensure that the already read part of the stream is garbage-collected. |
It is important to limit the scope of a stream as much as possible to ensure that the already read part of the stream is garbage-collected. |
||
Line 863: | Line 863: | ||
This is an example of using the [http://search.cpan.org/perldoc?AnyEvent AnyEvent] module. |
This is an example of using the [http://search.cpan.org/perldoc?AnyEvent AnyEvent] module. |
||
The result is this: it prints "Hello world!" after one second, then after another second prints "Hi!" four times every quarter of a second and then immediately prints "Bye!" and quits: |
The result is this: it prints "Hello world!" after one second, then after another second prints "Hi!" four times every quarter of a second and then immediately prints "Bye!" and quits: |
||
< |
<syntaxhighlight lang="perl">use AnyEvent; |
||
# a new condition with a callback: |
# a new condition with a callback: |
||
Line 893: | Line 893: | ||
# wait for the $quit condition to be ready: |
# wait for the $quit condition to be ready: |
||
$quit->recv();</ |
$quit->recv();</syntaxhighlight> |
||
This is the same using AnyEvent [http://search.cpan.org/perldoc?AE simplified API]: |
This is the same using AnyEvent [http://search.cpan.org/perldoc?AE simplified API]: |
||
< |
<syntaxhighlight lang="perl">use AnyEvent; |
||
my $quit = AE::cv sub { warn "Bye!\n" }; |
my $quit = AE::cv sub { warn "Bye!\n" }; |
||
Line 909: | Line 909: | ||
}; |
}; |
||
$quit->recv;</ |
$quit->recv;</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 915: | Line 915: | ||
in main() acts as signalling an event, and the one in echo() from whichever goes first acts to signal |
in main() acts as signalling an event, and the one in echo() from whichever goes first acts to signal |
||
that the other can/should resume. |
that the other can/should resume. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<span style="color: #008080;">constant</span> <span style="color: #000000;">lock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">init_cs</span><span style="color: #0000FF;">()</span> |
<span style="color: #008080;">constant</span> <span style="color: #000000;">lock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">init_cs</span><span style="color: #0000FF;">()</span> |
||
<span style="color: #008080;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
<span style="color: #008080;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
||
Line 946: | Line 946: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
Typically the first thread to attempt enter_cs() is released first, but there is |
Typically the first thread to attempt enter_cs() is released first, but there is |
||
Line 959: | Line 959: | ||
</pre> |
</pre> |
||
External events such as timers and user input are handled in pGUI, eg |
External events such as timers and user input are handled in pGUI, eg |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
||
Line 977: | Line 977: | ||
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span> |
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Line 987: | Line 987: | ||
This will print a message after one second, then terminate the program after |
This will print a message after one second, then terminate the program after |
||
another four seconds: |
another four seconds: |
||
< |
<syntaxhighlight lang="picolisp">(alarm 1 |
||
(prinl "Exit in 4 seconds") |
(prinl "Exit in 4 seconds") |
||
(alarm 4 (bye)) )</ |
(alarm 4 (bye)) )</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
$timer = New-Object -TypeName System.Timers.Timer -Property @{Enabled=$true; Interval=1000; AutoReset=$true} |
$timer = New-Object -TypeName System.Timers.Timer -Property @{Enabled=$true; Interval=1000; AutoReset=$true} |
||
Line 1,009: | Line 1,009: | ||
$global:counter = 0 |
$global:counter = 0 |
||
& $job.Module {$global:counter} |
& $job.Module {$global:counter} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 1,021: | Line 1,021: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">OpenWindow (0, 10, 10, 150, 40, "Event Demo") |
||
ButtonGadget (1, 10, 10, 35, 20, "Quit") |
ButtonGadget (1, 10, 10, 35, 20, "Quit") |
||
Line 1,032: | Line 1,032: | ||
EndIf |
EndIf |
||
ForEver</ |
ForEver</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
<syntaxhighlight lang="python"> |
|||
<lang Python> |
|||
import threading |
import threading |
||
import time |
import time |
||
Line 1,057: | Line 1,057: | ||
print("Main: Done") |
print("Main: Done") |
||
t.join() |
t.join() |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 1,068: | Line 1,068: | ||
the task (since it's a useless value): |
the task (since it's a useless value): |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 1,077: | Line 1,077: | ||
(void (sync task)) ; wait for the task to be done before exiting |
(void (sync task)) ; wait for the task to be done before exiting |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
{{trans|Go}} |
{{trans|Go}} |
||
<lang |
<syntaxhighlight lang="raku" line>note now, " program start"; |
||
my $event = Channel.new; |
my $event = Channel.new; |
||
Line 1,095: | Line 1,095: | ||
note now, " program signaling event"; |
note now, " program signaling event"; |
||
$event.send(0); |
$event.send(0); |
||
await $todo;</ |
await $todo;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Instant:1403880984.089974 program start |
<pre>Instant:1403880984.089974 program start |
||
Line 1,108: | Line 1,108: | ||
Although REXX can be event driven, most events would probably have to be actively checked to see if the event occurs. |
Although REXX can be event driven, most events would probably have to be actively checked to see if the event occurs. |
||
<br>Here is a ''time-driven'' example of events happening, based on specific timer ticks. |
<br>Here is a ''time-driven'' example of events happening, based on specific timer ticks. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program demonstrates a method of handling events (this is a time─driven pgm).*/ |
||
signal on halt /*allow user to HALT (Break) the pgm.*/ |
signal on halt /*allow user to HALT (Break) the pgm.*/ |
||
parse arg timeEvent /*allow the "event" to be specified. */ |
parse arg timeEvent /*allow the "event" to be specified. */ |
||
Line 1,125: | Line 1,125: | ||
nop /*replace NOP with the "process" code.*/ |
nop /*replace NOP with the "process" code.*/ |
||
end /*while*/ /*NOP is a REXX statement, does nothing*/ |
end /*while*/ /*NOP is a REXX statement, does nothing*/ |
||
signal event? /*see if another event has happened. */</ |
signal event? /*see if another event has happened. */</syntaxhighlight> |
||
{{out|output|text= when using the input of: <tt> 1 3 5 0 7 9 </tt>}} |
{{out|output|text= when using the input of: <tt> 1 3 5 0 7 9 </tt>}} |
||
<pre> |
<pre> |
||
Line 1,151: | Line 1,151: | ||
Rust ensures memory safety at compile-time without needing a garbage collector or runtime. There are several concurrency primitives in it's standard library. |
Rust ensures memory safety at compile-time without needing a garbage collector or runtime. There are several concurrency primitives in it's standard library. |
||
<syntaxhighlight lang="rust"> |
|||
<lang Rust> |
|||
use std::{sync::mpsc, thread, time::Duration}; |
use std::{sync::mpsc, thread, time::Duration}; |
||
Line 1,169: | Line 1,169: | ||
Ok(()) |
Ok(()) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Tcl has been event-driven since 7.5, but only supported channel and timer events (plus variable traces, which can be used to create event-like entitites). With the addition of coroutines, it becomes much simpler to create general events: |
Tcl has been event-driven since 7.5, but only supported channel and timer events (plus variable traces, which can be used to create event-like entitites). With the addition of coroutines, it becomes much simpler to create general events: |
||
{{works with|Tcl|8.6}} |
{{works with|Tcl|8.6}} |
||
< |
<syntaxhighlight lang="tcl"># Simple task framework built from coroutines |
||
proc pause ms { |
proc pause ms { |
||
after $ms [info coroutine];yield |
after $ms [info coroutine];yield |
||
Line 1,227: | Line 1,227: | ||
X signal |
X signal |
||
} |
} |
||
waitForTasksToFinish</ |
waitForTasksToFinish</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>waiting for event |
<pre>waiting for event |
||
Line 1,233: | Line 1,233: | ||
received event</pre> |
received event</pre> |
||
Of course, the classic way of writing this is much shorter, but intermingles the tasks: |
Of course, the classic way of writing this is much shorter, but intermingles the tasks: |
||
< |
<syntaxhighlight lang="tcl">after 1000 set X signalled |
||
puts "waiting for event" |
puts "waiting for event" |
||
vwait X |
vwait X |
||
puts "received event"</ |
puts "received event"</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 1,242: | Line 1,242: | ||
The tasks to be executed are added to a list by the Scheduler class. The Timer.sleep method suspends the current fiber and signals the scheduler (by calling a private method) to execute the tasks one by one in their own fibers - in Wren only one fiber can execute at a time. The task results are then available to the main fiber on its resumption after Timer.sleep has completed. |
The tasks to be executed are added to a list by the Scheduler class. The Timer.sleep method suspends the current fiber and signals the scheduler (by calling a private method) to execute the tasks one by one in their own fibers - in Wren only one fiber can execute at a time. The task results are then available to the main fiber on its resumption after Timer.sleep has completed. |
||
< |
<syntaxhighlight lang="ecmascript">import "scheduler" for Scheduler |
||
import "timer" for Timer |
import "timer" for Timer |
||
Line 1,258: | Line 1,258: | ||
System.print(a) // still 3 |
System.print(a) // still 3 |
||
Timer.sleep(3000) // wait 3 seconds |
Timer.sleep(3000) // wait 3 seconds |
||
System.print(a) // now 3 * 3 + 1 = 10</ |
System.print(a) // now 3 * 3 + 1 = 10</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,269: | Line 1,269: | ||
=={{header|Yabasic}}== |
=={{header|Yabasic}}== |
||
{{trans|Gambas}} |
{{trans|Gambas}} |
||
<syntaxhighlight lang="yabasic"> |
|||
<lang Yabasic> |
|||
sub Timer1_Timer() |
sub Timer1_Timer() |
||
print Time$ |
print Time$ |
||
end sub |
end sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
zkl provides an Atomics library for things like this. Events are async, waiting for an event doesn't poll. |
zkl provides an Atomics library for things like this. Events are async, waiting for an event doesn't poll. |
||
< |
<syntaxhighlight lang="zkl">var event=Atomic.Bool(); // False |
||
// create thread waiting for event |
// create thread waiting for event |
||
fcn(event){event.wait(); println(vm," ping!")}.launch(event); |
fcn(event){event.wait(); println(vm," ping!")}.launch(event); |
||
Atomic.sleep(1); |
Atomic.sleep(1); |
||
event.set(); |
event.set(); |
||
println("done")</ |
println("done")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |