2
import org.jcsp.lang.*;
3
import org.jcsp.util.*;
6
import java.util.Random;
8
public class AltingBarrierGadget3 implements CSProcess {
10
private final ChannelInput in;
11
private final ChannelOutput[] out;
12
private final AltingChannelInput click;
13
private final ChannelOutput configure;
14
private final Color offColour, standbyColour;
15
private final int offInterval, standbyInterval;
16
private final int playInterval, countInterval;
17
private final String[] label;
19
public AltingBarrierGadget3 (
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;
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
// make receiving arrays for the barrier and shared variables
50
// from the other group leaders
52
final Guard[] standbyGuard = new Guard[out.length + 2];
54
final int MY_INDEX = out.length;
55
standbyGuard[MY_INDEX] = myAltingBarrier[MY_INDEX];
57
final int TIMEOUT = out.length + 1;
58
standbyGuard[TIMEOUT] = tim;
60
final Shared[] shared = new Shared[out.length + 1];
61
shared[MY_INDEX] = myShared;
63
// parallel-I/O distribution of barriers and shared variables
70
for (int i = 0; i < out.length; i++) {
71
synchronized (out[i]) {
72
out[i].write (myAltingBarrier[i]);
73
out[i].write (myShared);
81
for (int i = 0; i < out.length; i++) {
82
standbyGuard[i] = (AltingBarrier) in.read ();
83
shared[i] = (Shared) in.read ();
91
// start real work ...
93
Alternative standbyAlt = new Alternative (standbyGuard);
95
configure.write (Boolean.FALSE); // disable mouse clicks
99
configure.write (offColour);
100
tim.sleep (random.nextInt (offInterval));
102
configure.write (standbyColour);
103
tim.setAlarm (tim.read () + random.nextInt (standbyInterval));
105
int choice = standbyAlt.fairSelect (); // magic synchronisation
107
if (choice == MY_INDEX) {
109
(AltingBarrier) standbyGuard[choice],
110
shared[choice], myChannel.in(), random, tim
113
else if (choice != TIMEOUT) {
114
play ((AltingBarrier) standbyGuard[choice], shared[choice]);
122
private void playLeader (
123
AltingBarrier bar, Shared shared, AltingChannelInput myChannel,
124
Random random, CSTimer tim
127
while (click.pending ()) click.read (); // clear any buffered mouse clicks
128
configure.write (Boolean.TRUE); // enable mouse clicks
130
while (myChannel.pending ()) myChannel.read (); // clear any buffered cancels
133
long countTimeout = 0;
135
Alternative leaderAlt = new Alternative (new Guard[] {click, myChannel, tim});
136
final int CLICK = 0, CANCEL = 1, TIM = 2;
138
count = (playInterval/countInterval) - 1;
140
shared.ok = (count >= 0); // initialise shared variables
141
shared.label = label[count];
142
shared.colour = new Color (random.nextInt ());
143
shared.brighter = shared.colour.brighter ();
145
bar.sync (); // allow inspection of shared variables
147
boolean bright = true;
149
countTimeout = tim.read () + countInterval; // set first timeout
150
tim.setAlarm (countTimeout);
154
configure.write (bright ? shared.brighter : shared.colour);
157
configure.write (shared.label);
159
bar.sync (); // allow update of shared variables
163
shared.ok = false; // game over
165
shared.label = label[count];
168
switch (leaderAlt.priSelect ()) {
169
case CLICK: // our button clicked
171
shared.ok = false; // game over
173
case CANCEL: // someone else's button clicked
174
myChannel.read (); // (they will have set shared.ok)
176
case TIM: // timeout - move on
177
countTimeout += countInterval;
178
tim.setAlarm (countTimeout);
182
bar.sync (); // allow inspection of shared variables
186
configure.write (Boolean.FALSE); // disable mouse clicks
187
configure.write (""); // clear button label
191
private void play (AltingBarrier bar, Shared shared) {
193
while (click.pending ()) click.read (); // clear any buffered mouse clicks
194
configure.write (Boolean.TRUE); // enable mouse clicks
196
Alternative followerAlt = new Alternative (new Guard[] {click, bar});
197
final int CLICK = 0, BAR = 1;
199
bar.sync (); // allow inspection of shared variables
201
boolean bright = true;
205
configure.write (bright ? shared.brighter : shared.colour);
208
configure.write (shared.label);
210
bar.sync (); // allow update of shared variables
212
switch (followerAlt.priSelect ()) {
213
case CLICK: // our button clicked
215
shared.toLeader.write (null); // cancel leader timeout (if any)
216
shared.ok = false; // game over (we must set this)
217
bar.sync (); // allow inspection of shared variables
219
case BAR: // allow inspection of shared variables
225
configure.write (Boolean.FALSE); // disable mouse clicks
226
configure.write (""); // clear button label