Skip to content
Snippets Groups Projects
Droplet.java 3.7 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;

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

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