Skip to content
Snippets Groups Projects
Droplet.java 4.56 KiB
Newer Older
import java.util.List;
import java.util.ArrayList;
public class Droplet {
  private Position position;
  private DropletType type;
  private String name;

  public Droplet(DropletType type, Position position) {
    this.position = position;
    this.type = type;
    this.position.getChannel().addDroplet(this);
  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;

    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);
      } 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();
      }
  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;
          // 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() 
      } 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) {
      this.position.getChannel().removeDroplet(this);
    }
    this.position = position;
    this.position.getChannel().addDroplet(this);
  }

  public boolean isInSink() {
    return this.position.getChannel() instanceof Sink; 
  }