-
Notifications
You must be signed in to change notification settings - Fork 0
/
Clock.jr
85 lines (76 loc) · 2.14 KB
/
Clock.jr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.util.*;
import edu.ucdavis.jr.*;
public class Clock {
public op MyTime getTime();
public op void setAlarm(cap void() ch, MyTime t);
public op void setAlarmEndTime(cap void() ch);
public op void shutdown();
private op void tick();
private MyTime currentTime;
private int ms;
private Map<MyTime, Set<cap void()>> alarms = new HashMap<MyTime, Set<cap void()>>();
public MyTime endTime;
private op void stopTicker();
public Clock(int ms, MyTime endTime) {
currentTime = new MyTime(0, 0 ,0);
this.ms = ms;
this.endTime = endTime;
alarms.put(endTime, new HashSet<cap void()>());
}
private process loop {
boolean run = true;
while (run) {
inni void tick() {
// Send current alarms
Set<cap void()> chs = alarms.remove(currentTime);
if (chs!=null)
for(Object ch : chs)
send ((cap void())ch)();
// Increment time
currentTime.increment();
}
[] MyTime getTime() {
return ((MyTime)currentTime.clone());
}
[] void setAlarm(cap void() ch, MyTime t) {
MyTime at = ((MyTime)currentTime.clone()).add(t);
Set<cap void()> chs = alarms.remove(at);
if (chs == null)
chs = new HashSet<cap void()>();
chs.add(ch);
alarms.put(at, chs);
}
[] void setAlarmEndTime(cap void() ch) {
Set<cap void()> chs = alarms.remove(endTime);
if (chs == null)
send ch();
else {
chs.add(ch);
alarms.put(endTime, chs);
}
}
[] void shutdown() {
run = false;
}
}
send stopTicker();
if (alarms.size() > 0)
System.err.println("Some alarms left: "+alarms);
}
private process ticker {
boolean run = true;
long next = System.currentTimeMillis();
long w;
do {
inni void stopTicker() {
run = false;
}
else {
next += ms;
w = Math.max(0,next-System.currentTimeMillis());
edu.ucdavis.jr.JR.nap(w);
send tick();
}
} while (run);
}
}