com.github.rinde.rinsim.central.GlobalStateObject.java Source code

Java tutorial

Introduction

Here is the source code for com.github.rinde.rinsim.central.GlobalStateObject.java

Source

/*
 * Copyright (C) 2011-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.rinsim.central;

import static com.google.common.base.Preconditions.checkArgument;

import javax.annotation.Nullable;
import javax.measure.quantity.Duration;
import javax.measure.quantity.Length;
import javax.measure.quantity.Velocity;
import javax.measure.unit.Unit;

import com.github.rinde.rinsim.core.model.pdp.Parcel;
import com.github.rinde.rinsim.core.model.pdp.VehicleDTO;
import com.github.rinde.rinsim.geom.Point;
import com.google.auto.value.AutoValue;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

/**
 * An immutable state object representing the state of an entire
 * {@link com.github.rinde.rinsim.core.Simulator}.
 * @author Rinde van Lon
 */
@AutoValue
public abstract class GlobalStateObject {
    // TODO add generic way for storing travel distances based on shortest path
    // in road model

    GlobalStateObject() {
    }

    /**
     * @return All known parcels which require both a pickup and a delivery. They
     *         are not in the inventory of a vehicle.
     */
    public abstract ImmutableSet<Parcel> getAvailableParcels();

    /**
     * @return All vehicles.
     */
    public abstract ImmutableList<VehicleStateObject> getVehicles();

    /**
     * @return The current time.
     */
    public abstract long getTime();

    /**
     * @return The unit of time.
     */
    public abstract Unit<Duration> getTimeUnit();

    /**
     * @return The unit of (vehicle) speed.
     */
    public abstract Unit<Velocity> getSpeedUnit();

    /**
     * @return The unit of distances.
     */
    public abstract Unit<Length> getDistUnit();

    static GlobalStateObject create(ImmutableSet<Parcel> availableParcels,
            ImmutableList<VehicleStateObject> vehicles, long time, Unit<Duration> timeUnit,
            Unit<Velocity> speedUnit, Unit<Length> distUnit) {
        return new AutoValue_GlobalStateObject(availableParcels, vehicles, time, timeUnit, speedUnit, distUnit);
    }

    /**
     * Constructs a new {@link GlobalStateObject} with only the selected vehicle.
     * The current instance remains unchanged.
     * @param index The index of the vehicle to select.
     * @return A new object containing only the selected vehicle, all other values
     *         are copied from this instance.
     */
    public GlobalStateObject withSingleVehicle(int index) {
        checkArgument(index >= 0 && index < getVehicles().size(),
                "Invalid vehicle index (%s) must be >= 0 and < %s.", index, getVehicles().size());
        return create(getAvailableParcels(), ImmutableList.of(getVehicles().get(index)), getTime(), getTimeUnit(),
                getSpeedUnit(), getDistUnit());
    }

    /**
     * Constructs a new {@link GlobalStateObject} using the routes specified.
     * @param routes The routes to use, this will replace any existing routes in
     *          the vehicles. Exactly one route must be specified for each
     *          vehicle.
     * @return A newly constructed {@link GlobalStateObject} that only differs
     *         from the current object in the vehicles' routes.
     */
    public GlobalStateObject withRoutes(ImmutableList<ImmutableList<Parcel>> routes) {
        checkArgument(routes.size() == getVehicles().size());
        final ImmutableList.Builder<VehicleStateObject> b = ImmutableList.builder();
        for (int i = 0; i < getVehicles().size(); i++) {
            b.add(getVehicles().get(i).withRoute(routes.get(i)));
        }
        return create(getAvailableParcels(), b.build(), getTime(), getTimeUnit(), getSpeedUnit(), getDistUnit());
    }

    /**
     * Immutable state object of a vehicle.
     * @author Rinde van Lon
     */
    @AutoValue
    public abstract static class VehicleStateObject {

        VehicleStateObject() {
        }

        /**
         * @return The {@link VehicleDTO}.
         */
        public abstract VehicleDTO getDto();

        /**
         * @return Location of the vehicle.
         */
        public abstract Point getLocation();

        /**
         * @return The contents of the vehicle. This excludes parcels which are
         *         currently being picked up and includes parcels which are
         *         currently being delivered.
         */
        public abstract ImmutableSet<Parcel> getContents();

        /**
         * @return The remaining time the vehicle needs for completion of its
         *         current servicing operation.
         */
        public abstract long getRemainingServiceTime();

        /**
         * Destination is present in two situations:
         * <ol>
         * <li>In case all of the following holds:
         * <ul>
         * <li>Vehicles are not allowed to divert from their previously started
         * routes.</li>
         * <li>The vehicle is moving to a parcel (either pickup or delivery
         * location).</li>
         * <li>The vehicle has not yet started servicing.</li>
         * </ul>
         * In this case it indicates the current destination of the vehicle. When a
         * vehicle has a destination it <b>must</b> first move to and service this
         * destination.</li>
         * <li>In case the vehicle is servicing a parcel. In this case the
         * {@link Parcel} as specified by this field is the one being serviced. In
         * this case servicing <b>must</b> first complete before the vehicle can do
         * something else. When this {@link Parcel} also occurs in
         * {@link #getContents()} this parcel is currently being delivered,
         * otherwise it is being picked up.</li>
         * </ol>
         * @return The destination.
         */
        public abstract Optional<Parcel> getDestination();

        /**
         * @return If present the route the vehicle is currently following is
         *         returned. If no route is being followed {@link Optional#absent()}
         *         is returned.
         */
        public abstract Optional<ImmutableList<Parcel>> getRoute();

        @SuppressWarnings("unchecked")
        static VehicleStateObject create(VehicleDTO dto, Point location, ImmutableSet<Parcel> contents,
                long remainingServiceTime, @Nullable Parcel destination,
                @Nullable ImmutableList<? extends Parcel> route) {
            return new AutoValue_GlobalStateObject_VehicleStateObject(dto, location, contents, remainingServiceTime,
                    Optional.fromNullable(destination), Optional.fromNullable((ImmutableList<Parcel>) route));
        }

        VehicleStateObject withRoute(ImmutableList<Parcel> route) {
            return create(getDto(), getLocation(), getContents(), getRemainingServiceTime(),
                    getDestination().orNull(), route);
        }

        @Override
        public int hashCode() {
            return System.identityHashCode(this);
        }

        @Override
        public boolean equals(@Nullable Object other) {
            return this == other;
        }
    }
}