Search in sources :

Example 6 with ScheduleItem

use of jmri.jmrit.operations.locations.schedules.ScheduleItem in project JMRI by JMRI.

the class ScheduleManagerTest method testScheduleManager.

public void testScheduleManager() {
    LocationManager lm = LocationManager.instance();
    Location l = lm.newLocation("new test location");
    Track t = l.addTrack("track 1", Track.SPUR);
    ScheduleManager sm = ScheduleManager.instance();
    // clear out any previous schedules
    sm.dispose();
    sm = ScheduleManager.instance();
    Schedule s1 = sm.newSchedule("new schedule");
    Schedule s2 = sm.newSchedule("newer schedule");
    ScheduleItem i1 = s1.addItem("BoxCar");
    i1.setRoadName("new road");
    i1.setReceiveLoadName("new load");
    i1.setShipLoadName("new ship load");
    ScheduleItem i2 = s1.addItem("Caboose");
    i2.setRoadName("road");
    i2.setReceiveLoadName("load");
    i2.setShipLoadName("ship load");
    Assert.assertEquals("1 First schedule name", "new schedule", s1.getName());
    Assert.assertEquals("1 First schedule name", "newer schedule", s2.getName());
    List<Schedule> names = sm.getSchedulesByNameList();
    Assert.assertEquals("There should be 2 schedules", 2, names.size());
    Schedule sch1 = names.get(0);
    Schedule sch2 = names.get(1);
    Assert.assertEquals("2 First schedule name", "new schedule", sch1.getName());
    Assert.assertEquals("2 First schedule name", "newer schedule", sch2.getName());
    Assert.assertEquals("Schedule 1", sch1, sm.getScheduleByName("new schedule"));
    Assert.assertEquals("Schedule 2", sch2, sm.getScheduleByName("newer schedule"));
    // Remove references to swing
    // JComboBox box = sm.getComboBox();
    // Assert.assertEquals("3 First schedule name", "", box.getItemAt(0));
    // Assert.assertEquals("3 First schedule name", sch1, box.getItemAt(1));
    // Assert.assertEquals("3 First schedule name", sch2, box.getItemAt(2));
    //
    // JComboBox box2 = sm.getSidingsByScheduleComboBox(s1);
    // Assert.assertEquals("First siding name", null, box2.getItemAt(0));
    // now add a schedule to siding
    t.setScheduleId(sch1.getId());
    // JComboBox box3 = sm.getSidingsByScheduleComboBox(s1);
    // LocationTrackPair ltp = (LocationTrackPair)box3.getItemAt(0);
    // Assert.assertEquals("Location track pair location", l, ltp.getLocation());
    // Assert.assertEquals("Location track pair track", t, ltp.getTrack());
    Assert.assertEquals("1 Schedule Item 1 type", "BoxCar", i1.getTypeName());
    Assert.assertEquals("1 Schedule Item 1 road", "new road", i1.getRoadName());
    Assert.assertEquals("1 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("1 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("1 Schedule Item 2 type", "Caboose", i2.getTypeName());
    Assert.assertEquals("1 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("1 Schedule Item 2 load", "load", i2.getReceiveLoadName());
    Assert.assertEquals("1 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    sm.replaceRoad("new road", "replaced road");
    Assert.assertEquals("2 Schedule Item 1 type", "BoxCar", i1.getTypeName());
    Assert.assertEquals("2 Schedule Item 1 road", "replaced road", i1.getRoadName());
    Assert.assertEquals("2 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("2 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("2 Schedule Item 2 type", "Caboose", i2.getTypeName());
    Assert.assertEquals("2 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("2 Schedule Item 2 load", "load", i2.getReceiveLoadName());
    Assert.assertEquals("2 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    sm.replaceType("BoxCar", "replaced car type");
    Assert.assertEquals("3 Schedule Item 1 type", "replaced car type", i1.getTypeName());
    Assert.assertEquals("3 Schedule Item 1 road", "replaced road", i1.getRoadName());
    Assert.assertEquals("3 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("3 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("3 Schedule Item 2 type", "Caboose", i2.getTypeName());
    Assert.assertEquals("3 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("3 Schedule Item 2 load", "load", i2.getReceiveLoadName());
    Assert.assertEquals("3 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    sm.replaceType("Caboose", "BoxCar");
    Assert.assertEquals("4 Schedule Item 1 type", "replaced car type", i1.getTypeName());
    Assert.assertEquals("4 Schedule Item 1 road", "replaced road", i1.getRoadName());
    Assert.assertEquals("4 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("4 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("4 Schedule Item 2 type", "BoxCar", i2.getTypeName());
    Assert.assertEquals("4 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("4 Schedule Item 2 load", "load", i2.getReceiveLoadName());
    Assert.assertEquals("4 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    sm.replaceLoad("BoxCar", "load", "new load");
    Assert.assertEquals("5 Schedule Item 1 type", "replaced car type", i1.getTypeName());
    Assert.assertEquals("5 Schedule Item 1 road", "replaced road", i1.getRoadName());
    Assert.assertEquals("5 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("5 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("5 Schedule Item 2 type", "BoxCar", i2.getTypeName());
    Assert.assertEquals("5 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("5 Schedule Item 2 load", "new load", i2.getReceiveLoadName());
    Assert.assertEquals("5 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    sm.replaceLoad("BoxCar", "new load", "next load");
    Assert.assertEquals("6 Schedule Item 1 type", "replaced car type", i1.getTypeName());
    Assert.assertEquals("6 Schedule Item 1 road", "replaced road", i1.getRoadName());
    Assert.assertEquals("6 Schedule Item 1 load", "new load", i1.getReceiveLoadName());
    Assert.assertEquals("6 Schedule Item 1 ship", "new ship load", i1.getShipLoadName());
    Assert.assertEquals("6 Schedule Item 2 type", "BoxCar", i2.getTypeName());
    Assert.assertEquals("6 Schedule Item 2 road", "road", i2.getRoadName());
    Assert.assertEquals("6 Schedule Item 2 load", "next load", i2.getReceiveLoadName());
    Assert.assertEquals("6 Schedule Item 2 ship", "ship load", i2.getShipLoadName());
    // remove all schedules
    sm.dispose();
    names = sm.getSchedulesByNameList();
    Assert.assertEquals("There should be no schedules", 0, names.size());
}
Also used : LocationManager(jmri.jmrit.operations.locations.LocationManager) ScheduleManager(jmri.jmrit.operations.locations.schedules.ScheduleManager) ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem) Schedule(jmri.jmrit.operations.locations.schedules.Schedule) Track(jmri.jmrit.operations.locations.Track) Location(jmri.jmrit.operations.locations.Location)

Example 7 with ScheduleItem

use of jmri.jmrit.operations.locations.schedules.ScheduleItem in project JMRI by JMRI.

the class LocationTest method testRoadNameSupport.

public void testRoadNameSupport() {
    // use LocationManager to allow replace car road to work properly
    Location l = LocationManager.instance().newLocation("Test Name 2");
    Assert.assertEquals("Location Name", "Test Name 2", l.getName());
    Track t = l.addTrack("new track", Track.SPUR);
    Assert.assertEquals("Location", l, t.getLocation());
    t.setRoadOption(Track.INCLUDE_ROADS);
    t.addRoadName("Test Road Name");
    t.addRoadName("Test Road Name 2");
    ScheduleManager sm = ScheduleManager.instance();
    Schedule s = sm.newSchedule("test schedule");
    ScheduleItem i1 = s.addItem("BoxCar");
    ScheduleItem i2 = s.addItem("BoxCar");
    i1.setRoadName("Test Road Name");
    i2.setRoadName("Test Road Name 2");
    Assert.assertTrue("track should accept road Test Road Name", t.acceptsRoadName("Test Road Name"));
    Assert.assertTrue("track should accept road Test Road Name 2", t.acceptsRoadName("Test Road Name 2"));
    Assert.assertFalse("track should Not accept road New Test Road Name", t.acceptsRoadName("New Test Road Name"));
    Assert.assertEquals("ScheudleItem i1 Road Test Road Name", "Test Road Name", i1.getRoadName());
    Assert.assertEquals("ScheudleItem i2 Road Test Road Name", "Test Road Name 2", i2.getRoadName());
    CarRoads cr = CarRoads.instance();
    cr.replaceName("Test Road Name", "New Test Road Name");
    Assert.assertFalse("track should Not accept road Test Road Name", t.acceptsRoadName("Test Road Name"));
    Assert.assertTrue("track should accept road Test Road Name 2", t.acceptsRoadName("Test Road Name 2"));
    Assert.assertTrue("track should accept road New Test Road Name", t.acceptsRoadName("New Test Road Name"));
    Assert.assertEquals("ScheudleItem i1 Road Test Road Name", "New Test Road Name", i1.getRoadName());
    Assert.assertEquals("Check ScheudleItem i2 Road Test Road Name", "Test Road Name 2", i2.getRoadName());
    // remove all schedules
    sm.dispose();
}
Also used : ScheduleManager(jmri.jmrit.operations.locations.schedules.ScheduleManager) ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem) CarRoads(jmri.jmrit.operations.rollingstock.cars.CarRoads) Schedule(jmri.jmrit.operations.locations.schedules.Schedule)

Example 8 with ScheduleItem

use of jmri.jmrit.operations.locations.schedules.ScheduleItem in project JMRI by JMRI.

the class TrainBuilder method findDestinationAndTrack.

/**
     * Find a destination and track for a car, and add the car to the train.
     *
     * @param car The car that is looking for a destination and destination
     *            track.
     * @param rl The current route location for this car.
     * @param routeIndex Where in the train's route to begin a search for a
     *            destination for this car.
     * @param routeEnd Where to stop looking for a destination.
     * @return true if successful, car has destination, track and a train.
     */
private boolean findDestinationAndTrack(Car car, RouteLocation rl, int routeIndex, int routeEnd) throws BuildFailedException {
    if (routeIndex + 1 == routeEnd) {
        log.debug("Car ({}) is at the last location in the train's route", car.toString());
    }
    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildFindDestinationForCar"), new Object[] { car.toString(), car.getTypeName(), car.getLoadName(), (car.getLocationName() + ", " + car.getTrackName()) }));
    if (car.getKernel() != null) {
        addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarLeadKernel"), new Object[] { car.toString(), car.getKernelName(), car.getKernel().getSize(), car.getKernel().getTotalLength(), Setup.getLengthUnit().toLowerCase() }));
    }
    // start looking after car's current location
    int start = routeIndex;
    // the route location destination being checked for the car
    RouteLocation rld = null;
    // holds the best route location destination for the car
    RouteLocation rldSave = null;
    // holds the best track at destination for the car
    Track trackSave = null;
    // used when a spur has an alternate track and no schedule
    Track finalDestinationTrackSave = null;
    // true when car can be picked up from two or more locations in the route
    boolean multiplePickup = false;
    // more than one location in this route?
    if (!_train.isLocalSwitcher()) {
        // being looking for tracks at the next location
        start++;
    }
    // all pick ups to terminal?
    if (_train.isSendCarsToTerminalEnabled() && !splitString(rl.getName()).equals(splitString(_departLocation.getName())) && routeEnd == _routeList.size()) {
        addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildSendToTerminal"), new Object[] { _terminateLocation.getName() }));
        // user could have specified several terminal locations with the "same" name
        start = routeEnd - 1;
        while (start > routeIndex) {
            if (!splitString(_routeList.get(start - 1).getName()).equals(splitString(_terminateLocation.getName()))) {
                break;
            }
            start--;
        }
    }
    for (int k = start; k < routeEnd; k++) {
        rld = _routeList.get(k);
        // if car can be picked up later at same location, set flag
        if (checkForLaterPickUp(rl, rld, car)) {
            multiplePickup = true;
        }
        if (rld.isDropAllowed() || car.hasFred() || car.isCaboose()) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildSearchingLocation"), new Object[] { rld.getName() }));
        } else {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildRouteNoDropLocation"), new Object[] { _train.getRoute().getName(), rld.getId(), rld.getName() }));
            continue;
        }
        if (_train.skipsLocation(rld.getId())) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildLocSkipped"), new Object[] { rld.getName(), rld.getId(), _train.getName() }));
            continue;
        }
        // any moves left at this location?
        if (rld.getCarMoves() >= rld.getMaxCarMoves()) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildNoAvailableMovesDest"), new Object[] { _train.getRoute().getName(), rld.getId(), rld.getName() }));
            continue;
        }
        // get the destination
        Location testDestination = rld.getLocation();
        if (testDestination == null) {
            // code check, should never throw, all locations in the route have been already checked
            throw new BuildFailedException(MessageFormat.format(Bundle.getMessage("buildErrorRouteLoc"), new Object[] { _train.getRoute().getName(), rld.getName() }));
        }
        Track trackTemp = null;
        Track finalDestinationTrackTemp = null;
        // caboose or car with FRED
        if (splitString(rl.getName()).equals(splitString(rld.getName())) && !_train.isLocalSwitcher() && !car.isPassenger() && !car.isCaboose() && !car.hasFred()) {
            // allow cars to return to the same staging location if no other options (tracks) are available
            if ((_train.isAllowReturnToStagingEnabled() || Setup.isAllowReturnToStagingEnabled()) && testDestination.isStaging() && trackSave == null) {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildReturnCarToStaging"), new Object[] { car.toString(), rld.getName() }));
            } else {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarLocEqualDestination"), new Object[] { car.toString(), rld.getName() }));
                continue;
            }
        }
        // check to see if departure track has any restrictions
        if (!car.getTrack().acceptsDestination(testDestination)) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildDestinationNotServiced"), new Object[] { testDestination.getName(), car.getTrackName() }));
            continue;
        }
        if (!testDestination.acceptsTypeName(car.getTypeName())) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropLocation"), new Object[] { car.toString(), car.getTypeName(), testDestination.getName() }));
            continue;
        }
        // can this location service this train's direction
        if (!checkDropTrainDirection(rld)) {
            continue;
        }
        // is the train length okay?
        if (!checkTrainLength(car, rl, rld)) {
            // done with this route
            break;
        }
        // no through traffic from origin to terminal?
        if (!_train.isAllowThroughCarsEnabled() && !_train.isLocalSwitcher() && !car.isCaboose() && !car.hasFred() && !car.isPassenger() && splitString(car.getLocationName()).equals(splitString(_departLocation.getName())) && splitString(rld.getName()).equals(splitString(_terminateLocation.getName()))) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildThroughTrafficNotAllow"), new Object[] { _departLocation.getName(), _terminateLocation.getName() }));
            continue;
        }
        // is there a track assigned for staging cars?
        if (rld == _train.getTrainTerminatesRouteLocation() && _terminateStageTrack != null) {
            // no need to check train and track direction into staging, already done
            String status = car.testDestination(testDestination, _terminateStageTrack);
            if (status.equals(Track.OKAY)) {
                trackTemp = _terminateStageTrack;
            // only generate a new load if there aren't any other tracks available for this car
            } else if (status.startsWith(Track.LOAD) && car.getTrack() == _departStageTrack && car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName()) && rldSave == null && (_departStageTrack.isAddCustomLoadsAnyStagingTrackEnabled() || _departStageTrack.isAddCustomLoadsEnabled() || _departStageTrack.isAddCustomLoadsAnySpurEnabled())) {
                // try and generate a load for this car into staging
                if (generateLoadCarDepartingAndTerminatingIntoStaging(car, _terminateStageTrack)) {
                    trackTemp = _terminateStageTrack;
                } else {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), _terminateStageTrack.getName(), status, _terminateStageTrack.getTrackTypeName() }));
                    // failed to create load
                    continue;
                }
            } else {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), _terminateStageTrack.getName(), status, _terminateStageTrack.getTrackTypeName() }));
                continue;
            }
        // no staging track assigned, start track search
        } else {
            // first report if there are any alternate tracks
            for (Track track : testDestination.getTrackByNameList(null)) {
                if (track.isAlternate()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackIsAlternate"), new Object[] { car.toString(), track.getTrackTypeName(), track.getName() }));
                }
            }
            for (Track testTrack : testDestination.getTrackByMovesList(null)) {
                // dropping to the same track isn't allowed
                if (testTrack == car.getTrack() && !car.isPassenger() && !car.isCaboose() && !car.hasFred()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarSameTrack"), new Object[] { car.toString(), testTrack.getName() }));
                    continue;
                }
                // Can the train service this track?
                if (!checkDropTrainDirection(car, rld, testTrack)) {
                    continue;
                }
                // drop to interchange or spur?
                if (!checkTrainCanDrop(car, testTrack)) {
                    continue;
                }
                // report if track has planned pickups
                if (testTrack.getIgnoreUsedLengthPercentage() > 0) {
                    // calculate the available space
                    //                        int available = testTrack.getLength() - (testTrack.getUsedLength() + testTrack.getReserved());
                    int available = testTrack.getLength() - (testTrack.getUsedLength() * (100 - testTrack.getIgnoreUsedLengthPercentage()) / 100 + testTrack.getReservedLengthDrops());
                    int available3 = testTrack.getLength() + (testTrack.getLength() * testTrack.getIgnoreUsedLengthPercentage() / 100) - (testTrack.getUsedLength() + testTrack.getReserved());
                    //                        }
                    if (available3 < available) {
                        available = available3;
                    }
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackHasPlannedPickups"), new Object[] { testTrack.getName(), testTrack.getIgnoreUsedLengthPercentage(), testTrack.getLength(), Setup.getLengthUnit().toLowerCase(), testTrack.getUsedLength(), testTrack.getReserved(), testTrack.getReservedLengthDrops(), testTrack.getReservedLengthDrops() - testTrack.getReserved(), available }));
                }
                String status = car.testDestination(testDestination, testTrack);
                // is the destination a spur with a schedule demanding this car's custom load?
                if (status.equals(Track.OKAY) && !testTrack.getScheduleId().equals(Track.NONE) && !car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName()) && !car.getLoadName().equals(CarLoads.instance().getDefaultLoadName())) {
                    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildSpurScheduleLoad"), new Object[] { testTrack.getName(), car.getLoadName() }));
                    addCarToTrain(car, rl, rld, testTrack);
                    return true;
                }
                // alternate track isn't checked
                if (!status.equals(Track.OKAY) && // wrong car type for this spur
                !status.startsWith(Track.TYPE) && // can't generate load for spur that is full
                !status.startsWith(Track.LENGTH) && // can't use a spur that is too short
                !status.startsWith(Track.CAPACITY) && testTrack.getTrackType().equals(Track.SPUR) && !testTrack.getScheduleId().equals(Track.NONE) && (car.getTrack().isAddCustomLoadsEnabled() || car.getTrack().isAddCustomLoadsAnySpurEnabled()) && car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName())) {
                    // can we use this track?
                    if (!testTrack.isSpaceAvailable(car)) {
                        addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoDestTrackSpace"), new Object[] { car.toString(), testTrack.getLocation().getName(), testTrack.getName(), testTrack.getNumberOfCarsInRoute(), testTrack.getReservedInRoute(), Setup.getLengthUnit().toLowerCase(), testTrack.getReservationFactor() }));
                        // no
                        continue;
                    }
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildGenerateLoad"), new Object[] { car.toString(), car.getTypeName(), testDestination.getName(), testTrack.getName() }));
                    // save the car's load
                    String carLoad = car.getLoadName();
                    ScheduleItem si = getScheduleItem(car, testTrack);
                    if (si != null) {
                        car.setLoadName(si.getReceiveLoadName());
                        if (car.testDestination(testDestination, testTrack).equals(Track.OKAY)) {
                            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildAddingScheduleLoad"), new Object[] { si.getReceiveLoadName(), car.toString() }));
                            car.setLoadGeneratedFromStaging(true);
                            testTrack.bumpSchedule();
                            addCarToTrain(car, rl, rld, testTrack);
                            return true;
                        }
                    }
                    // restore car's load (default empty)
                    car.setLoadName(carLoad);
                }
                // check to see if alternate track is available if track full and no schedule
                if (status.startsWith(Track.LENGTH) && testTrack.getAlternateTrack() != null && car.getFinalDestination() == null && testTrack.getScheduleId().equals(Track.NONE) && car.getTrack() != testTrack.getAlternateTrack() && car.testDestination(testDestination, testTrack.getAlternateTrack()).equals(Track.OKAY)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackFullHasAlternate"), new Object[] { testDestination.getName(), testTrack.getName(), testTrack.getAlternateTrack().getName() }));
                    finalDestinationTrackTemp = testTrack;
                    // send car to alternate track
                    trackTemp = testTrack.getAlternateTrack();
                    break;
                }
                // okay to drop car?
                if (!status.equals(Track.OKAY)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), testTrack.getName(), status, testTrack.getTrackTypeName() }));
                    continue;
                }
                // No local moves from spur to spur
                if (_train.isLocalSwitcher() && !Setup.isLocalSpurMovesEnabled() && testTrack.getTrackType().equals(Track.SPUR) && car.getTrack().getTrackType().equals(Track.SPUR)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoSpurToSpurMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // No local moves from yard to yard
                if (_train.isLocalSwitcher() && !Setup.isLocalYardMovesEnabled() && testTrack.getTrackType().equals(Track.YARD) && car.getTrack().getTrackType().equals(Track.YARD) && !car.isCaboose() && !car.hasFred()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoYardToYardMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // No local moves from interchange to interchange
                if (_train.isLocalSwitcher() && !Setup.isLocalInterchangeMovesEnabled() && testTrack.getTrackType().equals(Track.INTERCHANGE) && car.getTrack().getTrackType().equals(Track.INTERCHANGE)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoInterchangeToInterchangeMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // not staging, then use (should never be staging TODO throw an exception)
                if (!testTrack.getTrackType().equals(Track.STAGING)) {
                    trackTemp = testTrack;
                    break;
                }
            }
        }
        // did we find a new destination?
        if (trackTemp != null) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarCanDropMoves"), new Object[] { car.toString(), trackTemp.getTrackTypeName(), trackTemp.getLocation().getName(), trackTemp.getName(), +rld.getCarMoves(), rld.getMaxCarMoves() }));
            if (rldSave == null && multiplePickup) {
                addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarHasSecond"), new Object[] { car.toString(), car.getLocationName() }));
                trackSave = null;
                // done
                break;
            }
            // if there's more than one available destination use the one with the least moves
            if (rldSave != null) {
                double saveCarMoves = rldSave.getCarMoves();
                double saveRatio = saveCarMoves / rldSave.getMaxCarMoves();
                double nextCarMoves = rld.getCarMoves();
                double nextRatio = nextCarMoves / rld.getMaxCarMoves();
                // bias cars to the terminal
                if (rld == _train.getTrainTerminatesRouteLocation()) {
                    nextRatio = nextRatio * nextRatio;
                    log.debug("Location ({}) is terminate location, adjusted nextRatio {}", rld.getName(), Double.toString(nextRatio));
                }
                // bias cars with default loads to a track with a schedule
                if (!trackTemp.getScheduleId().equals(Track.NONE)) {
                    nextRatio = nextRatio * nextRatio;
                    log.debug("Track ({}) has schedule ({}), adjusted nextRatio {}", trackTemp.getName(), trackTemp.getScheduleName(), Double.toString(nextRatio));
                }
                // check for an earlier drop in the route
                for (int m = start; m < routeEnd; m++) {
                    RouteLocation rle = _routeList.get(m);
                    if (rle == rld) {
                        // done
                        break;
                    }
                    if (rle.getName().equals(rld.getName()) && (rle.getMaxCarMoves() - rle.getCarMoves() > 0) && rle.isDropAllowed() && checkDropTrainDirection(car, rle, trackTemp)) {
                        log.debug("Found an earlier drop for car ({}) destination ({})", car.toString(), rle.getName());
                        nextCarMoves = rle.getCarMoves();
                        nextRatio = nextCarMoves / rle.getMaxCarMoves();
                        // set car drop to earlier stop
                        rld = rle;
                        break;
                    }
                }
                log.debug("{} = {}, {} = {}", rldSave.getName(), Double.toString(saveRatio), rld.getName(), Double.toString(nextRatio));
                if (saveRatio < nextRatio) {
                    // the saved is better than the last found
                    rld = rldSave;
                    trackTemp = trackSave;
                    finalDestinationTrackTemp = finalDestinationTrackSave;
                } else if (multiplePickup) {
                    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarHasSecond"), new Object[] { car.toString(), car.getLocationName() }));
                    trackSave = null;
                    // done
                    break;
                }
            }
            // every time through, save the best route destination, and track
            rldSave = rld;
            trackSave = trackTemp;
            finalDestinationTrackSave = finalDestinationTrackTemp;
        } else {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCouldNotFindDestForCar"), new Object[] { car.toString(), rld.getName() }));
        }
    }
    // did we find a destination?
    if (trackSave != null) {
        if (finalDestinationTrackSave != null) {
            car.setFinalDestination(finalDestinationTrackSave.getLocation());
            car.setFinalDestinationTrack(finalDestinationTrackSave);
        }
        addCarToTrain(car, rl, rldSave, trackSave);
        return true;
    }
    checkCarOrder(car);
    // no build errors, but car not given destination
    return false;
}
Also used : ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Track(jmri.jmrit.operations.locations.Track) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Location(jmri.jmrit.operations.locations.Location)

Example 9 with ScheduleItem

use of jmri.jmrit.operations.locations.schedules.ScheduleItem in project JMRI by JMRI.

the class Track method checkScheduleValid.

/**
     * Check to see if schedule is valid for the track at this location.
     *
     * @return SCHEDULE_OKAY if schedule okay, otherwise an error message.
     */
public String checkScheduleValid() {
    String status = SCHEDULE_OKAY;
    if (getScheduleId().equals(NONE)) {
        return status;
    }
    Schedule schedule = getSchedule();
    if (schedule == null) {
        return MessageFormat.format(Bundle.getMessage("CanNotFindSchedule"), new Object[] { getScheduleId() });
    }
    List<ScheduleItem> scheduleItems = schedule.getItemsBySequenceList();
    if (scheduleItems.size() == 0) {
        return Bundle.getMessage("empty");
    }
    for (ScheduleItem si : scheduleItems) {
        // check train schedules
        if (!si.getSetoutTrainScheduleId().equals(ScheduleItem.NONE) && TrainScheduleManager.instance().getScheduleById(si.getSetoutTrainScheduleId()) == null) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getSetoutTrainScheduleId() });
            break;
        }
        if (!si.getPickupTrainScheduleId().equals(ScheduleItem.NONE) && TrainScheduleManager.instance().getScheduleById(si.getPickupTrainScheduleId()) == null) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getPickupTrainScheduleId() });
            break;
        }
        if (!_location.acceptsTypeName(si.getTypeName())) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getTypeName() });
            break;
        }
        if (!acceptsTypeName(si.getTypeName())) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getTypeName() });
            break;
        }
        // check roads, accepted by track, valid road, and there's at least one car with that road
        if (!si.getRoadName().equals(ScheduleItem.NONE) && (!acceptsRoadName(si.getRoadName()) || !CarRoads.instance().containsName(si.getRoadName()) || CarManager.instance().getByTypeAndRoad(si.getTypeName(), si.getRoadName()) == null)) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getRoadName() });
            break;
        }
        // check loads
        List<String> loads = CarLoads.instance().getNames(si.getTypeName());
        if (!si.getReceiveLoadName().equals(ScheduleItem.NONE) && (!acceptsLoad(si.getReceiveLoadName(), si.getTypeName()) || !loads.contains(si.getReceiveLoadName()))) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getReceiveLoadName() });
            break;
        }
        if (!si.getShipLoadName().equals(ScheduleItem.NONE) && !loads.contains(si.getShipLoadName())) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getShipLoadName() });
            break;
        }
        // check destination
        if (si.getDestination() != null && (!si.getDestination().acceptsTypeName(si.getTypeName()) || LocationManager.instance().getLocationById(si.getDestination().getId()) == null)) {
            status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getDestination() });
            break;
        }
        // check destination track
        if (si.getDestination() != null && si.getDestinationTrack() != null) {
            if (!si.getDestination().isTrackAtLocation(si.getDestinationTrack())) {
                status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getDestinationTrack() + " (" + Bundle.getMessage("Track") + ")" });
                break;
            }
            if (!si.getDestinationTrack().acceptsTypeName(si.getTypeName())) {
                status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getDestinationTrack() + " (" + Bundle.getMessage("Type") + ")" });
                break;
            }
            if (!si.getRoadName().equals(ScheduleItem.NONE) && !si.getDestinationTrack().acceptsRoadName(si.getRoadName())) {
                status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getDestinationTrack() + " (" + Bundle.getMessage("Road") + ")" });
                break;
            }
            if (!si.getShipLoadName().equals(ScheduleItem.NONE) && !si.getDestinationTrack().acceptsLoad(si.getShipLoadName(), si.getTypeName())) {
                status = MessageFormat.format(Bundle.getMessage("NotValid"), new Object[] { si.getDestinationTrack() + " (" + Bundle.getMessage("Load") + ")" });
                break;
            }
        }
    }
    return status;
}
Also used : ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem) Schedule(jmri.jmrit.operations.locations.schedules.Schedule) TrainSchedule(jmri.jmrit.operations.trains.timetable.TrainSchedule)

Example 10 with ScheduleItem

use of jmri.jmrit.operations.locations.schedules.ScheduleItem in project JMRI by JMRI.

the class Track method checkSchedule.

/**
     * Checks to see if car can be placed on this spur using this schedule.
     * Returns OKAY if the schedule can service the car.
     * @param car The Car to be tested.
     *
     * @return Track.OKAY track.CUSTOM track.SCHEDULE
     */
public String checkSchedule(Car car) {
    // does car already have this destination?
    if (car.getDestinationTrack() == this) {
        return OKAY;
    }
    // only spurs can have a schedule
    if (!getTrackType().equals(SPUR)) {
        return OKAY;
    }
    if (getScheduleId().equals(NONE)) {
        // does car have a scheduled load?
        if (car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName()) || car.getLoadName().equals(CarLoads.instance().getDefaultLoadName())) {
            // no
            return OKAY;
        }
        return MessageFormat.format(Bundle.getMessage("carHasA"), new Object[] { CUSTOM, LOAD, car.getLoadName() });
    }
    log.debug("Track ({}) has schedule ({}) mode {} ({})", getName(), getScheduleName(), getScheduleMode(), // NOI18N
    getScheduleMode() == SEQUENTIAL ? "Sequential" : "Match");
    ScheduleItem si = getCurrentScheduleItem();
    if (si == null) {
        log.error("Could not find schedule item id: ({}) for schedule ({})", getScheduleItemId(), // NOI18N
        getScheduleName());
        // NOI18N
        return SCHEDULE + " ERROR";
    }
    if (getScheduleMode() == SEQUENTIAL) {
        return checkScheduleItem(si, car);
    }
    // schedule in is match mode search entire schedule for a match
    return searchSchedule(car);
}
Also used : ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem)

Aggregations

ScheduleItem (jmri.jmrit.operations.locations.schedules.ScheduleItem)23 Schedule (jmri.jmrit.operations.locations.schedules.Schedule)17 Track (jmri.jmrit.operations.locations.Track)10 ScheduleManager (jmri.jmrit.operations.locations.schedules.ScheduleManager)10 Location (jmri.jmrit.operations.locations.Location)9 RouteLocation (jmri.jmrit.operations.routes.RouteLocation)8 LocationManager (jmri.jmrit.operations.locations.LocationManager)7 Car (jmri.jmrit.operations.rollingstock.cars.Car)7 CarManager (jmri.jmrit.operations.rollingstock.cars.CarManager)6 Train (jmri.jmrit.operations.trains.Train)5 TrainManager (jmri.jmrit.operations.trains.TrainManager)5 TrainSchedule (jmri.jmrit.operations.trains.timetable.TrainSchedule)4 CarTypes (jmri.jmrit.operations.rollingstock.cars.CarTypes)3 Route (jmri.jmrit.operations.routes.Route)3 Kernel (jmri.jmrit.operations.rollingstock.cars.Kernel)2 CarRoads (jmri.jmrit.operations.rollingstock.cars.CarRoads)1 RouteManager (jmri.jmrit.operations.routes.RouteManager)1