package nloc; import java.util.List; import java.util.ArrayList; public class Droplet { private Position position; private DropletType type; private Channel pumpOutlet; public Droplet(DropletType type, Position position) { this.position = position; this.type = type; this.pumpOutlet = null; this.position.getChannel().addDroplet(this); } public Droplet(DropletType type) { this.position = null; this.type = type; this.pumpOutlet = null; } public void move() { position.increment(this); } public DropletType getType() { return type; } public Channel getPumpOutlet() { return pumpOutlet; } public void setPumpOutlet(Channel pumpOutlet) { this.pumpOutlet = pumpOutlet; } /* * Unify the position using the faster channel * TODO: range from 1 to size or 0 to size - 1? */ public int getNormalizedSteps() { Channel chan = this.position.getChannel(); int pSteps = chan.getPSteps(); int hSteps = chan.getHSteps(); float factor = 1; if (pSteps < hSteps && this.type == DropletType.HEADER) { factor = (float)pSteps / hSteps; } else if (pSteps > hSteps && this.type == DropletType.PAYLOAD) { factor = (float)hSteps / pSteps; } return (int)(this.position.getSteps() * factor); } public Position getPosition() { return position; } public boolean coalesce() { boolean coalesce = false; if (this.position.getChannel() instanceof Module || this.position.getChannel() instanceof Sink || this.position.getChannel() instanceof Pump) { coalesce = false; } else { List<Droplet> drlist = this.position.getChannel().getNormalizedSortedDropletList(); // Check if we are the last droplet in the channel if (drlist.indexOf(this) + 1 == drlist.size()) { List<Channel> childChanList = this.position.getChannel().getChildrenList(); int minChanTs = this.position.getChannel().getMinSteps(); // Check if the following channel is a sink if (childChanList.size() == 1 && childChanList.get(0) instanceof Sink) { coalesce = false; } else if (minChanTs - this.getNormalizedSteps() > Nloc.MIN_TIMEDIFF) { // droplet is last in channel and remaining time in channel is // greater than MIN_TIMEDIFF coalesce = false; } else { // Next is no sink for (Channel chan : childChanList) { List<Droplet> childDrList = chan.getNormalizedSortedDropletList(); if (!childDrList.isEmpty()) { coalesce |= (this.position.getChannel().getMinSteps() + childDrList.get(0).getNormalizedSteps() - this.getNormalizedSteps() ) <= Nloc.MIN_TIMEDIFF; } } } } else { // not last droplet in channel Droplet followingDroplet = drlist.get(drlist.indexOf(this) + 1); coalesce = (followingDroplet.getNormalizedSteps() - this.getNormalizedSteps()) <= Nloc.MIN_TIMEDIFF; } } return coalesce; } public void setPosition(Position position) { if (position != null) { this.position.getChannel().removeDroplet(this); } this.position = position; this.position.getChannel().addDroplet(this); } public boolean isInSink() { return this.position.getChannel() instanceof Sink; } }