2
import org.jcsp.lang.*;
3
import org.jcsp.util.*;
8
public class AltingBarrierGadget5 implements CSProcess {
10
private final AltingChannelInput in;
11
private final ChannelOutput[] out;
12
private final AltingBarrier bar;
13
private final AltingChannelInput click;
14
private final ChannelOutput configure;
15
private final Color offColour, standbyColour;
16
private final int offInterval, standbyInterval;
17
private final int playInterval, countInterval;
18
private final String[] label;
20
public AltingBarrierGadget5 (
21
AltingChannelInput in, ChannelOutput[] out, AltingBarrier bar,
22
AltingChannelInput click, ChannelOutput configure,
23
Color offColour, Color standbyColour,
24
int offInterval, int standbyInterval,
25
int playInterval, int countInterval,
28
this.in = in; this.out = out; this.bar = bar;
29
this.click = click; this.configure = configure;
30
this.offColour = offColour; this.standbyColour = standbyColour;
31
this.offInterval = offInterval; this.standbyInterval = standbyInterval;
32
this.playInterval = playInterval; this.countInterval = countInterval;
38
CSTimer tim = new CSTimer ();
40
final Random random = new Random ();
42
// make alting barrier and shared variables
43
// for the group this gadget is leading ...
45
final AltingBarrier[] myAltingBarrier = AltingBarrier.create (out.length + 1);
46
final Any2OneChannel myChannel = Channel.any2one (new OverWritingBuffer (1));
47
final Shared myShared = new Shared (myChannel.out());
49
// parallel-I/O distribution of barriers and shared variables
51
final AltingBarrier barDash = bar.expand ();
56
for (int i = 0; i < out.length; i++) {
57
synchronized (out[i]) {
58
out[i].write (myAltingBarrier[i]);
59
out[i].write (myShared);
62
barDash.sync (); // wait for all gadgets to finish output
63
barDash.contract (); // discard no longer needed item
68
ArrayList dump = // temporary storage
69
new ArrayList (2*out.length); // (guessed initial size)
71
Alternative distributeAlt =
72
new Alternative (new Guard[] {in, bar});
74
final int IN = 0, BAR = 1;
80
switch (distributeAlt.priSelect ()) {
82
dump.add (in.read ()); // an AltingBarrier
83
dump.add (in.read ()); // Shared variables
92
distributeAlt = null; // discard no longer needed item
93
bar.contract (); // discard no longer needed item
95
// make receiving arrays for the barrier and shared variables
96
// from the other group leaders
98
final Guard[] standbyGuard = new Guard[count + 2];
100
final int MY_INDEX = count;
101
standbyGuard[MY_INDEX] = myAltingBarrier[out.length];
103
final int TIMEOUT = count + 1;
104
standbyGuard[TIMEOUT] = tim;
106
final Shared[] shared = new Shared[count + 1];
107
shared[MY_INDEX] = myShared;
109
Iterator iterator = dump.iterator ();
110
for (int i = 0; i < count; i++) {
111
standbyGuard[i] = (AltingBarrier) iterator.next ();
112
shared[i] = (Shared) iterator.next ();
115
iterator = null; // discard no longer needed item
116
dump = null; // discard no longer needed item
118
// start real work ...
120
Alternative standbyAlt = new Alternative (standbyGuard);
122
configure.write (Boolean.FALSE); // disable mouse clicks
126
configure.write (offColour);
127
tim.sleep (random.nextInt (offInterval));
129
configure.write (standbyColour);
130
tim.setAlarm (tim.read () + random.nextInt (standbyInterval));
132
int choice = standbyAlt.fairSelect (); // magic synchronisation
134
if (choice == MY_INDEX) {
136
(AltingBarrier) standbyGuard[choice],
137
shared[choice], myChannel.in(), random, tim
140
else if (choice != TIMEOUT) {
141
play ((AltingBarrier) standbyGuard[choice], shared[choice]);
148
private void playLeader (
149
AltingBarrier bar, Shared shared, AltingChannelInput myChannel,
150
Random random, CSTimer tim
153
while (click.pending ()) click.read (); // clear any buffered mouse clicks
154
configure.write (Boolean.TRUE); // enable mouse clicks
156
while (myChannel.pending ()) myChannel.read (); // clear any buffered cancels
159
long countTimeout = 0;
161
Alternative leaderAlt = new Alternative (new Guard[] {click, myChannel, tim});
162
final int CLICK = 0, CANCEL = 1, TIM = 2;
164
count = (playInterval/countInterval) - 1;
166
shared.ok = (count >= 0); // initialise shared variables
167
shared.label = label[count];
168
shared.colour = new Color (random.nextInt (16777216));
169
shared.brighter = shared.colour.brighter ();
171
bar.sync (); // allow inspection of shared variables
173
boolean bright = true;
175
countTimeout = tim.read () + countInterval; // set first timeout
176
tim.setAlarm (countTimeout);
180
configure.write (bright ? shared.brighter : shared.colour);
183
configure.write (shared.label);
185
bar.sync (); // allow update of shared variables
189
shared.ok = false; // game over
191
shared.label = label[count];
194
switch (leaderAlt.priSelect ()) {
195
case CLICK: // our button clicked
197
shared.ok = false; // game over
199
case CANCEL: // someone else's button clicked
200
myChannel.read (); // (they will have set shared.ok)
202
case TIM: // timeout - move on
203
countTimeout += countInterval;
204
tim.setAlarm (countTimeout);
208
bar.sync (); // allow inspection of shared variables
212
configure.write (Boolean.FALSE); // disable mouse clicks
213
configure.write (""); // clear button label
217
private void play (AltingBarrier bar, Shared shared) {
219
while (click.pending ()) click.read (); // clear any buffered mouse clicks
220
configure.write (Boolean.TRUE); // enable mouse clicks
222
Alternative followerAlt = new Alternative (new Guard[] {click, bar});
223
final int CLICK = 0, BAR = 1;
225
bar.sync (); // allow inspection of shared variables
227
boolean bright = true;
231
configure.write (bright ? shared.brighter : shared.colour);
234
configure.write (shared.label);
236
bar.sync (); // allow update of shared variables
238
switch (followerAlt.priSelect ()) {
239
case CLICK: // our button clicked
241
shared.toLeader.write (null); // cancel leader timeout (if any)
242
shared.ok = false; // game over (we must set this)
243
bar.sync (); // allow inspection of shared variables
245
case BAR: // allow inspection of shared variables
251
configure.write (Boolean.FALSE); // disable mouse clicks
252
configure.write (""); // clear button label