Newer
Older
package nloc;
import java.util.List;
import java.util.ArrayList;

Peter Wagenhuber
committed
import java.lang.Math;
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);

Peter Wagenhuber
committed
public Droplet(DropletType type) {
this.position = null;
this.type = type;
this.pumpOutlet = null;
}
public Droplet(DropletType type, String name) {
this.position = null;
this.type = type;
this.pumpOutlet = null;
this.name = name;
}
public void move() {
position.increment(this);
}
public DropletType getType() {
return type;
}
public Channel getPumpOutlet() {
return pumpOutlet;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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;

Peter Wagenhuber
committed
int normStep;
if (this.position.getSteps() == 1) {
return this.position.getSteps();
} else {
if (pSteps < hSteps && this.type == DropletType.HEADER) {
factor = (float)pSteps / hSteps;
normStep = (int)Math.ceil((this.position.getSteps() - 1) * factor);

Peter Wagenhuber
committed
} else if (pSteps > hSteps && this.type == DropletType.PAYLOAD) {
factor = (float)hSteps / pSteps;
normStep = (int)Math.ceil((this.position.getSteps() - 1) * factor);
} else {
normStep = this.position.getSteps();
}

Peter Wagenhuber
committed
}
return normStep;
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;

Peter Wagenhuber
committed
// if this droplet is a PAYLOAD droplet and the following is a
// HEADER Droplet and is in a Module (or the other way round)
// they don't coalesce
} else if (childChanList.size() == 1 &&
childChanList.get(0) instanceof Module &&
!childChanList.get(0).getNormalizedSortedDropletList().isEmpty() &&
(this.type !=
childChanList.get(0).getNormalizedSortedDropletList().get(0).getType())) {
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 and no module with different type of droplet next
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;
public void setPosition(Position position) {

Peter Wagenhuber
committed
if (this.position != null) {

Peter Wagenhuber
committed
this.position.getChannel().removeDroplet(this);
}
this.position = position;
this.position.getChannel().addDroplet(this);
}
public boolean isInSink() {
return this.position.getChannel() instanceof Sink;
}