@Override
protected void tickImpl(TimeLapse time) {
// Check if we can deliver nearby
final Parcel delivery = getDelivery(time, 5);
final RoadModel rm = roadModel.get();
final PDPModel pm = pdpModel.get();
if (delivery != null) {
if (delivery.getDestination().equals(getPosition())
&& pm.getVehicleState(this) == VehicleState.IDLE) {
pm.deliver(this, delivery, time);
} else {
rm.moveTo(this, delivery.getDestination(), time);
}
return;
}
// Otherwise, Check if we can pickup nearby
final DefaultParcel closest = (DefaultParcel) RoadModels.findClosestObject(
rm.getPosition(this), rm, new Predicate<RoadUser>() {
@Override
public boolean apply(RoadUser input) {
return input instanceof DefaultParcel
&& pm.getParcelState(((DefaultParcel) input)) == ParcelState.AVAILABLE;
}
});
if (closest != null
&& Point.distance(rm.getPosition(closest), getPosition()) < 10) {
if (rm.equalPosition(closest, this)
&& pm.getTimeWindowPolicy().canPickup(closest.getPickupTimeWindow(),
time.getTime(), closest.getPickupDuration())) {
final double newSize = getPDPModel().getContentsSize(this)
+ closest.getMagnitude();
if (newSize <= getCapacity()) {
pm.pickup(this, closest, time);
}
} else {
rm.moveTo(this, rm.getPosition(closest), time);
}
return;
}
if (rm.getObjectsOfType(Parcel.class).isEmpty()) {
rm.moveTo(this, dto.startPosition, time);
return;
}
// If none of the above, let the gradient field guide us!
@Nullable
final Point p = gradientModel.getTargetFor(this);
if (p != null) {
rm.moveTo(this, p, time);
}
}