Events: Difference between revisions

2,245 bytes added ,  5 months ago
added Easylang
(added Easylang)
 
(4 intermediate revisions by 4 users not shown)
Line 28:
 
The event interface:
<langsyntaxhighlight lang="ada">protected type Event is
procedure Signal;
procedure Reset;
Line 34:
private
Fired : Boolean := False;
end Event;</langsyntaxhighlight>
The event implementation:
<langsyntaxhighlight lang="ada">protected body Event is
procedure Signal is
begin
Line 49:
null;
end Wait;
end Event;</langsyntaxhighlight>
With the event defined above:
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Test_Events is
Line 68:
Put_Line ("Signal X");
X.Signal;
end Test_Events;</langsyntaxhighlight>
Sample output:
<pre>
Line 77:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetTimer, internal, 1000
Return
 
Line 87:
F2:: ; external event: fire on F2 key press
TrayTip, external, f2 key pressed
Return</langsyntaxhighlight>
 
 
=={{header|BASIC256}}==
{{trans|Gambas}}
<syntaxhighlight lang="basic256">
<lang BASIC256>
subroutine Timer1_Timer()
print hour; ":"; minute; ":"; second
end subroutine
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 107:
===API===
This uses a Windows event object:
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB"
WAIT_TIMEOUT = 258
Line 123:
DEF PROCelapsed
SYS "SetEvent", hEvent%
ENDPROC</langsyntaxhighlight>
===Native===
This uses a simple variable as a semaphore:
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB"
Event% = FALSE
Line 141:
DEF PROCelapsed
Event% = TRUE
ENDPROC</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <unistd.h>
 
Line 163:
}
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Timers;
 
Line 185:
((Timer)sender).Stop();
}
}</langsyntaxhighlight>
Sample output:
<pre>10-11-2010 18:35:11
Line 192:
=={{header|Clojure}}==
{{trans|Go}}
<langsyntaxhighlight lang="lisp">(ns async-example.core
(:require [clojure.core.async :refer [>! <! >!! <!! go chan]])
(:require [clj-time.core :as time])
Line 229:
; Invoke -main function
(-main)
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 240:
 
=={{header|Delphi}}==
<langsyntaxhighlight Delphilang="delphi">program Events;
 
{$APPTYPE CONSOLE}
Line 293:
end;
Readln;
end.</langsyntaxhighlight>
Sample output:
<pre>
Line 301:
 
=={{header|E}}==
<langsyntaxhighlight lang="e">def makeEvent() {
def [var fired, var firer] := Ref.promise()
Line 324:
return event
}</langsyntaxhighlight>
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>.
<langsyntaxhighlight lang="e">def e := makeEvent()
 
{
Line 341:
})
println("[1] Waiting 1 second...")
}</langsyntaxhighlight>
 
=={{header|EasyLang}}==
 
[https://easylang.dev/show/#cod=y89TKMnMTS3iUlBQyM0vS1UoSsxLyc9NU9BSMDQwQOWB1CRnFiXnpCoYgdhgjQqGXHpc+XlAzaXFqfEp+eV5cKMgQhVQuhJFux4XRLcBFwA= Run it]
 
<syntaxhighlight>
on timer
move randomf * 100 randomf * 100
circle 2
timer 1
.
on mouse_down
move mouse_x mouse_y
circle 2
.
timer 0
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang="elixir">defmodule Events do
def log(msg) do
time = Time.utc_now |> to_string |> String.slice(0..7)
Line 372 ⟶ 389:
end
 
Events.main</langsyntaxhighlight>
 
{{out}}
Line 385 ⟶ 402:
=={{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.
<langsyntaxhighlight lang="erlang">
-module(events).
-compile(export_all).
Line 408 ⟶ 425:
P ! go,
timer:sleep(100).
</syntaxhighlight>
</lang>
'''Output:'''
<langsyntaxhighlight lang="erlang">
66> events:main().
0: 0:57 => Program start
Line 418 ⟶ 435:
0: 0:58 => Task resumed
ok
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
{{trans|C#}}
<langsyntaxhighlight lang="fsharp">open System
open System.Timers
 
Line 436 ⟶ 453:
timer.Start()
ignore <| Console.ReadLine()
0</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Gambas}}
<langsyntaxhighlight lang="freebasic">
Sub Timer1_Timer()
Print Time
End Sub
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 451 ⟶ 468:
</pre>
 
 
=={{header|FutureBasic}}==
Event timer fires every tenth of a second
<syntaxhighlight lang="futurebasic">
timerbegin, 0.1, YES
cls : printf @"%@", time(@"h:mm:ss a zzz")
timerend
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
4:44:36 PM EDT
</langpre>
 
=={{header|Gambas}}==
<langsyntaxhighlight lang="gambas">Public Sub Timer1_Timer()
 
Print Str(Time(Now))
 
End</langsyntaxhighlight>
Output:
<pre>
Line 472 ⟶ 503:
=={{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.
<langsyntaxhighlight lang="go">package main
 
import (
Line 494 ⟶ 525:
event <- 0
time.Sleep(100 * time.Millisecond)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 505 ⟶ 536:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Concurrent (threadDelay, forkIO)
import Control.Concurrent.SampleVar
 
Line 515 ⟶ 546:
signalEvent (Event sv) = writeSampleVar sv ()
resetEvent (Event sv) = emptySampleVar sv
waitEvent (Event sv) = readSampleVar sv</langsyntaxhighlight>
<langsyntaxhighlight lang="haskell">main = do e <- newEvent
forkIO (waitTask e)
putStrLn "[1] Waiting 1 second..."
Line 526 ⟶ 557:
waitTask e = do putStrLn "[2] Waiting for event..."
waitEvent e
putStrLn "[2] Received event."</langsyntaxhighlight>
Note: Because there is no serialization of the text output, there is a chance that it will appear interleaved.
 
Line 533 ⟶ 564:
The following only works in Unicon. The example illustrates the multiple tasks can
receive the same event:
<langsyntaxhighlight lang="unicon">record Event(cond, value)
 
procedure main()
Line 552 ⟶ 583:
signal(event.cond,0)
every wait(t1|t2)
end</langsyntaxhighlight>
 
Sample run:
Line 567 ⟶ 598:
=={{header|JavaScript}}==
An example using the [[wp:Yahoo!_UI_Library|YUI]] library:
<langsyntaxhighlight lang="javascript">YUI().use('event-custom', function(Y) {
// add a custom event:
Y.on('my:event', function () {
Line 576 ⟶ 607:
Y.fire('my:event');
}, 1000);
});</langsyntaxhighlight>
An example simulating [[wp:Document_Object_Model|DOM]] events:
<langsyntaxhighlight lang="javascript">YUI().use('node-event-simulate', function(Y) {
// add a click event handler to a DOM node with id "button":
Y.one("#button").on("click", function (e) {
Line 587 ⟶ 618:
Y.one("#button").simulate("click");
}, 1000);
});</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 594 ⟶ 625:
between two child threads.
 
<langsyntaxhighlight lang="julia">
function dolongcomputation(cond)
det(rand(4000, 4000))
Line 615 ⟶ 646:
sleep(5)
println("Done sleeping.")
</syntaxhighlight>
</lang>
{{output}}<pre>
Starting task, sleeping...
Line 628 ⟶ 659:
Paste in the REPL:
 
<langsyntaxhighlight lang="lisp">
(defun log (msg)
(let ((`#(,h ,m ,s) (erlang:time)))
Line 648 ⟶ 679:
(! pid 'go)
(timer:sleep 100))))
</syntaxhighlight>
</lang>
 
Usage:
Line 667 ⟶ 698:
 
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:
<langsyntaxhighlight lang="lingo">-- the current window was closed
on closeWindow
...
Line 675 ⟶ 706:
on mouseDown
...
end</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="lingo">-- send event #mouseDown programmatically to sprite 1
sendSprite(1, #mouseDown)
 
Line 684 ⟶ 715:
 
-- send custom event #fooBar to all existing sprites
sendAllSprites(#fooBar)</langsyntaxhighlight>
 
Using a binary plugin ("Xtra"), in Windows also lower level window messages can be both sent and received:
{{libheader|Msg Xtra}}
<langsyntaxhighlight lang="lingo">mx = xtra("Msg").new()
 
-- send message WM_LBUTTONDOWN to a specific window identified by HWND hwnd
Line 702 ⟶ 733:
WM_COPYDATA = 74
WM_MOUSEWHEEL = 522
mx.msg_listen([WM_COPYDATA, WM_MOUSEWHEEL], VOID, #msgReceived)</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight Mathematicalang="mathematica">Print["Will exit in 4 seconds"]; Pause[4]; Quit[]
->Will exit in 4 seconds</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">import posix
 
var p: array[2, cint]
Line 724 ⟶ 755:
discard close p[1]
discard p[0].read(addr p[1], 1)
echo "received signal from pipe"</langsyntaxhighlight>
 
===Stdlib Semaphore===
This version using locks module for signaling the condition.
 
<langsyntaxhighlight lang="nim">import locks
from os import sleep
import times
Line 758 ⟶ 789:
deinitLock lock
 
main()</langsyntaxhighlight>
 
Compile and run: <pre>nim c -r --threads:on events_cond.nim</pre>
Line 771 ⟶ 802:
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.
 
<langsyntaxhighlight Oforthlang="oforth">: anEvent
| ch |
Channel new ->ch
#[ ch receive "Ok, event is signaled !" println ] &
System sleep(1000)
ch send($myEvent) ;</langsyntaxhighlight>
 
An emitter is a general implementation for handling events : an emitter waits for events emitted and launches listeners that are waiting for those events.
<langsyntaxhighlight Oforthlang="oforth">import: emitter
 
: anEvent2
Line 789 ⟶ 820:
$myEvent e emit
]
e close ;</langsyntaxhighlight>
 
=={{header|Oz}}==
{{trans|Haskell}}
Events can be implemented as mutable references to dataflow variables:
<langsyntaxhighlight lang="oz">declare
fun {NewEvent}
{NewCell _}
Line 822 ⟶ 853:
{Delay 1000}
{System.showInfo "[1] Signaling event."}
{SignalEvent E}</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="oz">declare
E
in
Line 836 ⟶ 867:
{Delay 1000}
{System.showInfo "[1] Signaling event."}
E = unit</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="oz">declare
MyPort
in
Line 857 ⟶ 888:
{System.showInfo "[1] Signaling event."}
{Port.send MyPort unit}
end</langsyntaxhighlight>
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 ⟶ 894:
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:
<langsyntaxhighlight Perllang="perl">use AnyEvent;
 
# a new condition with a callback:
Line 893 ⟶ 924:
 
# wait for the $quit condition to be ready:
$quit->recv();</langsyntaxhighlight>
This is the same using AnyEvent [http://search.cpan.org/perldoc?AE simplified API]:
<langsyntaxhighlight Perllang="perl">use AnyEvent;
 
my $quit = AE::cv sub { warn "Bye!\n" };
Line 909 ⟶ 940:
};
 
$quit->recv;</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 915 ⟶ 946:
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.
<!--<langsyntaxhighlight Phixlang="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;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 946 ⟶ 977:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
{{out}}
Typically the first thread to attempt enter_cs() is released first, but there is
Line 959 ⟶ 990:
</pre>
External events such as timers and user input are handled in pGUI, eg
<!--<langsyntaxhighlight Phixlang="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: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
Line 977 ⟶ 1,008:
<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>
<!--</langsyntaxhighlight>-->
 
=={{header|PicoLisp}}==
Line 987 ⟶ 1,018:
This will print a message after one second, then terminate the program after
another four seconds:
<langsyntaxhighlight PicoLisplang="picolisp">(alarm 1
(prinl "Exit in 4 seconds")
(alarm 4 (bye)) )</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
$timer = New-Object -TypeName System.Timers.Timer -Property @{Enabled=$true; Interval=1000; AutoReset=$true}
 
Line 1,009 ⟶ 1,040:
$global:counter = 0
& $job.Module {$global:counter}
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,021 ⟶ 1,052:
 
=={{header|PureBasic}}==
<langsyntaxhighlight Purebasiclang="purebasic">OpenWindow (0, 10, 10, 150, 40, "Event Demo")
ButtonGadget (1, 10, 10, 35, 20, "Quit")
 
Line 1,032 ⟶ 1,063:
EndIf
ForEver</langsyntaxhighlight>
 
=={{header|Python}}==
 
<syntaxhighlight lang="python">
<lang Python>
import threading
import time
Line 1,057 ⟶ 1,088:
print("Main: Done")
t.join()
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 1,068 ⟶ 1,099:
the task (since it's a useless value):
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,077 ⟶ 1,108:
 
(void (sync task)) ; wait for the task to be done before exiting
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Go}}
<syntaxhighlight lang="raku" perl6line>note now, " program start";
my $event = Channel.new;
 
Line 1,095 ⟶ 1,126:
note now, " program signaling event";
$event.send(0);
await $todo;</langsyntaxhighlight>
{{out}}
<pre>Instant:1403880984.089974 program start
Line 1,108 ⟶ 1,139:
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 &nbsp; ''time-driven'' &nbsp; example of events happening, based on specific timer ticks.
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates a method of handling events (this is a time─driven pgm).*/
signal on halt /*allow the user to HALT (Break) the programpgm.*/
parse arg timeEvent /*allow the "event" to be specified. */
if timeEvent='' then timeEvent=5 5 /*Not specified? Then use the default.*/
 
event?: do forever /*determine if an event has occurred. */
theEvent= right(time(), 1) /*maybe it's an event, ─or─ maybe not.*/
if pos(theEvent, timeEvent)\==>0 then signal happening
end /*forever*/
 
say 'Control should never get here!' /*This is a logic can─never─happen ! */
halt: say '════════════ program halted.'; exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
happening: say 'an event occurred at' time()", the event is:" theEvent
do while theEvent==right(time(), 1) /*spin until a tic (a second) changes. */
nop /*replace NOP with the "process" code.*/
end /*while*/ /*NOP is a special REXX statement. , does nothing*/
signal event? signal event? /*see if another event has happened. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 1 &nbsp; 3 &nbsp; 5 &nbsp; 0 &nbsp; 7 &nbsp; 9 </tt>}}
<pre>
an event occurred at 16:13:29, the event is: 9
Line 1,151 ⟶ 1,182:
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};
 
Line 1,169 ⟶ 1,200:
Ok(())
}
</syntaxhighlight>
</lang>
 
=={{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:
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl"># Simple task framework built from coroutines
proc pause ms {
after $ms [info coroutine];yield
Line 1,227 ⟶ 1,258:
X signal
}
waitForTasksToFinish</langsyntaxhighlight>
Output:
<pre>waiting for event
Line 1,233 ⟶ 1,264:
received event</pre>
Of course, the classic way of writing this is much shorter, but intermingles the tasks:
<langsyntaxhighlight lang="tcl">after 1000 set X signalled
puts "waiting for event"
vwait X
puts "received event"</langsyntaxhighlight>
 
=={{header|Wren}}==
Line 1,242 ⟶ 1,273:
 
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.
<langsyntaxhighlight ecmascriptlang="wren">import "scheduler" for Scheduler
import "timer" for Timer
 
Line 1,258 ⟶ 1,289:
System.print(a) // still 3
Timer.sleep(3000) // wait 3 seconds
System.print(a) // now 3 * 3 + 1 = 10</langsyntaxhighlight>
 
{{out}}
Line 1,265 ⟶ 1,296:
10
</pre>
 
 
=={{header|Yabasic}}==
{{trans|Gambas}}
<syntaxhighlight lang="yabasic">
<lang Yabasic>
sub Timer1_Timer()
print Time$
end sub
</syntaxhighlight>
</lang>
 
 
=={{header|zkl}}==
zkl provides an Atomics library for things like this. Events are async, waiting for an event doesn't poll.
<langsyntaxhighlight lang="zkl">var event=Atomic.Bool(); // False
// create thread waiting for event
fcn(event){event.wait(); println(vm," ping!")}.launch(event);
Atomic.sleep(1);
event.set();
println("done")</langsyntaxhighlight>
{{out}}
<pre>
1,980

edits