8 | 8 |
events. Reactors are similar to event handlers in Javascript, or to
|
9 | 9 |
processes in Erlang.
|
10 | 10 |
|
11 | |
In Robin 0.3, a reactor is installed by a top-level form with the syntax
|
12 | |
`(reactor TRANSDUCER)`.
|
13 | |
|
14 | |
The first argument of the `reactor` form is evaluated to obtain a
|
|
11 |
In Robin 0.3, a reactor is installed by giving a top-level form with the
|
|
12 |
following syntax:
|
|
13 |
|
|
14 |
(reactor SUBSCRIPTIONS INITIAL-STATE-EXPR TRANSDUCER)
|
|
15 |
|
|
16 |
The first argument of the `reactor` form is a literal (unevaluated) list
|
|
17 |
of symbols, called the _subscriptions_ for the reactor. Each symbol names
|
|
18 |
a _facility_ with which the reactor wishes to be able to interact.
|
|
19 |
|
|
20 |
The second argument is evaluated, and becomes the _initial state_ of the
|
|
21 |
reactor.
|
|
22 |
|
|
23 |
The third argument of the `reactor` form is evaluated to obtain a
|
15 | 24 |
macro. This is called the _transducer_ of the reactor.
|
16 | 25 |
|
17 | 26 |
Whenever an event of interest to the reactor occurs, the transducer is
|
18 | |
evaluated, being passed three (pre-evaluated) arguments:
|
19 | |
|
20 | |
* A literal symbol called the _event type_, specifying what kind of event
|
21 | |
happened;
|
22 | |
* An arbitrary value called the _event payload_ containing more data about
|
23 | |
the event, in a format specific to that kind of event; and
|
24 | |
* The current state of the reactor. (This value is undefined
|
25 | |
if the transducer has never before been evaluated.)
|
|
27 |
evaluated, being passed two (pre-evaluated) arguments:
|
|
28 |
|
|
29 |
* A two-element list called the _event_. The elements are:
|
|
30 |
* A literal symbol called the _event type_, specifying what kind of event
|
|
31 |
happened.
|
|
32 |
* An arbitrary value called the _event payload_ containing more data about
|
|
33 |
the event, in a format specific to the type of event.
|
|
34 |
* The current state of the reactor. (This will be the initial state
|
|
35 |
if the reactor body has never before been evaluated.)
|
26 | 36 |
|
27 | 37 |
Given these things, the transducer is expected to evaluate to a list where the
|
28 | 38 |
first element is the new state of the reactor, and each of the subsequent
|
|
33 | 43 |
* An arbitrary value called the _command payload_ containing more data
|
34 | 44 |
about the command, in a format specific to that type of command.
|
35 | 45 |
|
36 | |
There may of course be zero commands in the returned list. It is an
|
|
46 |
There may of course be zero commands in the returned list, but it is an
|
37 | 47 |
error if the returned value is not a list containing at least one element.
|
38 | 48 |
|
39 | 49 |
If the transducer throws an error, no commands will be executed, and
|
40 | 50 |
the state of the transducer will remain unchanged. Implementations
|
41 | 51 |
should allow such occurrences to be visible and/or logged.
|
42 | 52 |
|
43 | |
In fact commands and events may in fact be the same thing.
|
|
53 |
In fact, commands _are_ events. We just call them commands when it is
|
|
54 |
a reactor producing them, and events when a reactor is receiving them.
|
44 | 55 |
|
45 | 56 |
Standard Events
|
46 | 57 |
---------------
|
|
69 | 80 |
|
70 | 81 |
### `stop` ###
|
71 | 82 |
|
72 | |
Stops everything. This command is provisional.
|
|
83 |
Stops the current reactor, and removes it from the list of active
|
|
84 |
reactors. It will no longer receive any events.
|
|
85 |
|
|
86 |
Note: not correctly implemented currently.
|
73 | 87 |
|
74 | 88 |
Standard Facilities
|
75 | 89 |
-------------------
|
|
207 | 221 |
= B
|
208 | 222 |
= C
|
209 | 223 |
|
210 | |
This leaves some open questions about reactors (and so their semantics
|
211 | |
will definitely change slightly in a subsequent 0.x version of Robin.)
|
212 | |
Namely:
|
213 | |
|
214 | |
* Can a reactor respond with a `close` to a facility other than the
|
215 | |
facility that sent it the event it is currently handling?
|
216 | |
* Currently reactors cannot communicate with each other at all.
|
217 | |
How can reactors communicate with each other? (Our idea is to have
|
218 | |
a "reactor bus" facility which can relay responses from one reactor
|
219 | |
into an event for another reactor.)
|
|
224 |
Subscribing and unsubscribing to facilities
|
|
225 |
-------------------------------------------
|
|
226 |
|
|
227 |
TODO.
|
|
228 |
|
|
229 |
Listing a facility in the SUBSCRIPTIONS of the reactor isn't the
|
|
230 |
only way for a reactor to be notified of events from the facility.
|
|
231 |
The reactor can also subscribe to the facility at some point after the
|
|
232 |
reactor has started, and later even unsubscribe from it as well.
|
|
233 |
|
|
234 |
Communicating between reactors
|
|
235 |
------------------------------
|
|
236 |
|
|
237 |
It is not really recommended to implement a system with multiple
|
|
238 |
reactors. It is better to compose a single large reactor out of
|
|
239 |
multiple macros.
|
|
240 |
|
|
241 |
But currently we allow it, so we should say some words about it.
|
|
242 |
|
|
243 |
When a reactor issues a command, all other reactors see it as an
|
|
244 |
event.
|