nz.sodium.time.TimerSystem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sodium Show documentation
Show all versions of sodium Show documentation
A Functional Reactive Programming (FRP) system for Java
package nz.sodium.time;
import nz.sodium.*;
import java.util.LinkedList;
import java.util.Optional;
public class TimerSystem {
public TimerSystem(final TimerSystemImpl impl) {
this.impl = impl;
final CellSink timeSnk = new CellSink(impl.now());
time = timeSnk;
Transaction.onStart(new Runnable() {
public void run() {
T t = impl.now();
impl.runTimersTo(t);
while (true) {
Event ev;
// Pop all events earlier than t.
synchronized (eventQueue) {
ev = eventQueue.peekFirst();
if (ev != null && ev.t.compareTo(t) <= 0)
eventQueue.removeFirst();
else
ev = null;
}
if (ev != null) {
timeSnk.send(ev.t);
ev.sAlarm.send(ev.t);
}
else
break;
}
timeSnk.send(t);
}
});
}
private final TimerSystemImpl impl;
/**
* A cell giving the current clock time.
*/
public final Cell time;
private class Event {
Event(T t, StreamSink sAlarm) {
this.t = t;
this.sAlarm = sAlarm;
}
T t;
StreamSink sAlarm;
};
private LinkedList eventQueue = new LinkedList();
private static class CurrentTimer {
Optional oTimer = Optional.empty();
};
/**
* A timer that fires at the specified time.
*/
public Stream at(Cell> tAlarm) {
final StreamSink sAlarm = new StreamSink();
final CurrentTimer current = new CurrentTimer();
Listener l = tAlarm.listen(new Handler>() {
public void run(final Optional oAlarm) {
if (current.oTimer.isPresent())
current.oTimer.get().cancel();
current.oTimer = oAlarm.isPresent()
? Optional.of(
impl.setTimer(oAlarm.get(), new Runnable() {
public void run() {
synchronized (eventQueue) {
eventQueue.add(new Event(oAlarm.get(), sAlarm));
}
// Open and close a transaction to trigger queued
// events to run.
Transaction.runVoid(new Runnable() {
public void run() { }
});
}
}))
: Optional.empty();
}
});
return sAlarm.addCleanup(l);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy