diff --git a/wash/src/wash/control/SpinController.java b/wash/src/wash/control/SpinController.java index c81b54d..64ec2e6 100644 --- a/wash/src/wash/control/SpinController.java +++ b/wash/src/wash/control/SpinController.java @@ -2,41 +2,71 @@ package wash.control; import actor.ActorThread; import wash.io.WashingIO; -import wash.io.WashingIO.Spin; +import wash.control.WashingMessage.Order; -public class SpinController extends ActorThread { - - // TODO: add attributes +public final class SpinController extends ActorThread { + private WashingIO io; + private Spin spin = new Spin(); + private WashingMessage m; public SpinController(WashingIO io) { - // TODO + this.io = io; + } + + protected void sendAck() { + m.sendAck(this); } @Override public void run() { + spin.start(); + listener(); // Drop into a recursive listener method + } - // this is to demonstrate how to control the barrel spin: - // io.setSpinMode(Spin.IDLE); + /** Recursive listener method */ + public void listener() { + m = poll(60000 / Settings.SPEEDUP).orElse(new WashingMessage(this, Order.NOOP)); - try { - - // ... TODO ... - - while (true) { - // wait for up to a (simulated) minute for a WashingMessage - WashingMessage m = receiveWithTimeout(60000 / Settings.SPEEDUP); - - // if m is null, it means a minute passed and no message was received - if (m != null) { - System.out.println("got " + m); - } - - // ... TODO ... + switch (m.order()) { + case Order.SPIN_OFF -> spin.setMode(WashingIO.Spin.IDLE); + case Order.SPIN_FAST -> spin.setMode(WashingIO.Spin.FAST); + case Order.SPIN_SLOW -> spin.setMode(WashingIO.Spin.LEFT); + default -> { + listener(); } - } catch (InterruptedException unexpected) { - // we don't expect this thread to be interrupted, - // so throw an error if it happens anyway - throw new Error(unexpected); + } + + listener(); + } + + private final class Spin extends Thread { + private WashingIO.Spin spinMode; + boolean changed = false; + + public Spin() { + spinMode = WashingIO.Spin.IDLE; + } + + public synchronized void setMode(WashingIO.Spin m) { + spinMode = m; + changed = true; + } + + private void loop() { + io.setSpinMode(spinMode); + + if (changed) { + sendAck(); + changed = false; + } + + usleep(60000 / Settings.SPEEDUP); + loop(); + } + + @Override + public void run() { + loop(); } } }