Package rinde.sim.examples.demo.factory

Source Code of rinde.sim.examples.demo.factory.AgvModel$BoxHandle

package rinde.sim.examples.demo.factory;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newLinkedHashSet;

import java.math.RoundingMode;
import java.util.List;
import java.util.Set;

import org.apache.commons.math3.random.RandomGenerator;

import rinde.sim.core.Simulator.SimulatorEventType;
import rinde.sim.core.SimulatorAPI;
import rinde.sim.core.SimulatorUser;
import rinde.sim.core.TickListener;
import rinde.sim.core.TimeLapse;
import rinde.sim.core.graph.Point;
import rinde.sim.core.model.Model;
import rinde.sim.core.model.ModelProvider;
import rinde.sim.core.model.ModelReceiver;
import rinde.sim.core.model.pdp.PDPModel;
import rinde.sim.core.model.pdp.PDPModel.PDPModelEventType;
import rinde.sim.core.model.pdp.PDPModelEvent;
import rinde.sim.core.model.road.RoadModel;
import rinde.sim.event.Event;
import rinde.sim.event.Listener;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.math.DoubleMath;

class AgvModel implements TickListener, ModelReceiver, Model<AGV>,
    SimulatorUser, Listener {

  Optional<RoadModel> rm;
  Optional<SimulatorAPI> simulator;
  final RandomGenerator rng;
  Set<Point> occupiedPositions;
  ImmutableList<ImmutableList<Point>> points;
  int currentBox;

  List<BoxHandle> boxes;
  final List<Point> border;

  AgvModel(RandomGenerator r, ImmutableList<ImmutableList<Point>> ps,
      ImmutableList<Point> b) {
    rm = Optional.absent();
    rng = r;
    occupiedPositions = newLinkedHashSet();
    points = ps;
    currentBox = 0;
    boxes = newArrayList();
    border = b;
  }

  @Override
  public void tick(TimeLapse timeLapse) {}

  @Override
  public void afterTick(TimeLapse timeLapse) {}

  @Override
  public void registerModelProvider(ModelProvider mp) {
    rm = Optional.fromNullable(mp.getModel(RoadModel.class));
    Optional
        .fromNullable(mp.getModel(PDPModel.class))
        .get()
        .getEventAPI()
        .addListener(this, PDPModelEventType.END_DELIVERY,
            PDPModelEventType.END_PICKUP);
  }

  @Override
  public void setSimulator(SimulatorAPI api) {
    simulator = Optional.of(api);
    simulator.get().getEventAPI()
        .addListener(this, SimulatorEventType.CONFIGURED);
  }

  void init() {
    if (simulator.isPresent() && rm.isPresent()) {
      int max = 0;
      for (final List<Point> ps : points) {
        max = Math.max(max, ps.size());
      }
      final int num = max;
      for (int i = 0; i < num; i++) {
        final long duration = DoubleMath.roundToLong(
            (FactoryExample.SERVICE_DURATION / 2d)
                + (rng.nextDouble() * FactoryExample.SERVICE_DURATION),
            RoundingMode.CEILING);

        final Point rnd = rndBorder();
        Point dest;
        if (i >= points.get(0).size()) {
          dest = rndBorder();
        } else {
          dest = points.get(0).get(i);
          occupiedPositions.add(dest);
        }

        final BoxHandle bh = new BoxHandle(i);
        final Box b = new Box(rnd, dest, duration, bh);
        bh.box = b;

        boxes.add(bh);
        simulator.get().register(boxes.get(boxes.size() - 1).box);
      }
    }
  }

  @Override
  public boolean register(AGV element) {
    element.registerAgvModel(this);
    return true;
  }

  @Override
  public boolean unregister(AGV element) {
    return false;
  }

  @Override
  public Class<AGV> getSupportedType() {
    return AGV.class;
  }

  @Override
  public void handleEvent(Event e) {
    if (e.getEventType() == SimulatorEventType.CONFIGURED) {
      init();
    } else {
      final PDPModelEvent event = (PDPModelEvent) e;
      if (e.getEventType() == PDPModelEventType.END_PICKUP) {
        occupiedPositions.remove(((Box) event.parcel).origin);
      }
      if (e.getEventType() == PDPModelEventType.END_DELIVERY) {
        final long duration = DoubleMath.roundToLong(
            (FactoryExample.SERVICE_DURATION / 2d)
                + (rng.nextDouble() * FactoryExample.SERVICE_DURATION),
            RoundingMode.CEILING);
        simulator.get().unregister(event.parcel);

        final BoxHandle bh = ((Box) event.parcel).boxHandle;
        bh.wordIndex = (bh.wordIndex + 1) % points.size();

        Point dest;
        if (bh.index >= points.get(bh.wordIndex).size()) {
          dest = rndBorder();
        } else {
          dest = points.get(bh.wordIndex).get(bh.index);
          occupiedPositions.add(dest);
        }

        final Box b = new Box(event.parcel.getDestination(), dest, duration, bh);
        bh.box = b;

        simulator.get().register(b);
      }
    }
  }

  Point rndBorder() {
    return border.get(rng.nextInt(border.size()));
  }

  Point rnd() {
    Point p;
    do {
      p = rm.get().getRandomPosition(rng);
    } while (occupiedPositions.contains(p));
    occupiedPositions.add(p);
    return p;
  }

  Box nextDestination() {
    final Box b = boxes.get(currentBox % boxes.size()).box;
    currentBox++;
    return b;
  }

  static class BoxHandle {
    int wordIndex;
    final int index;
    Box box;

    BoxHandle(int i) {
      index = i;
      wordIndex = 0;
    }
  }
}
TOP

Related Classes of rinde.sim.examples.demo.factory.AgvModel$BoxHandle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.