Search in sources :

Example 1 with TransitSection

use of jmri.TransitSection in project JMRI by JMRI.

the class DispatcherFrame method allocateSection.

/**
     * Allocates a Section to an Active Train according to the information in an
     * AllocationRequest.
     *
     * If successful, returns an AllocatedSection and removes the
     * AllocationRequest from the queue. If not successful, returns null and
     * leaves the AllocationRequest in the queue.
     *
     * To be allocatable, a Section must be FREE and UNOCCUPIED. If a Section is
     * OCCUPIED, the allocation is rejected unless the dispatcher chooses to
     * override this restriction. To be allocatable, the Active Train must not
     * be waiting for its start time. If the start time has not been reached,
     * the allocation is rejected, unless the dispatcher chooses to override the
     * start time.
     *
     * @param ar the request containing the section to allocate
     * @param ns the next section; use null to allow the next section to be
     *           automatically determined, if the next section is the last
     *           section, of if an extra section is being allocated
     * @return the allocated section or null if not successful
     */
public AllocatedSection allocateSection(AllocationRequest ar, Section ns) {
    AllocatedSection as = null;
    Section nextSection = null;
    int nextSectionSeqNo = 0;
    if (ar != null) {
        ActiveTrain at = ar.getActiveTrain();
        if (at.holdAllocation() || at.reachedRestartPoint()) {
            return null;
        }
        Section s = ar.getSection();
        if (s.getState() != Section.FREE) {
            return null;
        }
        // skip occupancy check if this is the first allocation and the train is occupying the Section
        boolean checkOccupancy = true;
        if ((at.getLastAllocatedSection() == null) && (s.containsBlock(at.getStartBlock()))) {
            checkOccupancy = false;
        }
        // check if section is occupied
        if (checkOccupancy && (s.getOccupancy() == Section.OCCUPIED)) {
            if (_AutoAllocate) {
                // autoAllocate never overrides occupancy
                return null;
            }
            int selectedValue = JOptionPane.showOptionDialog(dispatcherFrame, Bundle.getMessage("Question1"), Bundle.getMessage("WarningTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { Bundle.getMessage("ButtonYes"), Bundle.getMessage("ButtonNo") }, Bundle.getMessage("ButtonNo"));
            if (selectedValue == 1) {
                // return without allocating if "No" response
                return null;
            }
        }
        // check if train has reached its start time if delayed start
        if (checkOccupancy && (!at.getStarted()) && at.getDelayedStart() != ActiveTrain.NODELAY) {
            if (_AutoAllocate) {
                // autoAllocate never overrides start time
                return null;
            }
            int selectedValue = JOptionPane.showOptionDialog(dispatcherFrame, Bundle.getMessage("Question4"), Bundle.getMessage("WarningTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { Bundle.getMessage("ButtonYes"), Bundle.getMessage("ButtonNo") }, Bundle.getMessage("ButtonNo"));
            if (selectedValue == 1) {
                return null;
            } else {
                at.setStarted();
                for (int i = delayedTrains.size() - 1; i >= 0; i--) {
                    if (delayedTrains.get(i) == at) {
                        delayedTrains.remove(i);
                    }
                }
            }
        }
        //check here to see if block is already assigned to an allocated section;
        if (getSignalType() == SIGNALMAST && checkBlocksNotInAllocatedSection(s, ar) != null) {
            return null;
        }
        //  code must do all validity checks on a non-null ns.
        if (ns != null) {
            nextSection = ns;
        } else if ((ar.getSectionSeqNumber() != -99) && (at.getNextSectionSeqNumber() == ar.getSectionSeqNumber()) && (!((s == at.getEndBlockSection()) && (ar.getSectionSeqNumber() == at.getEndBlockSectionSequenceNumber()))) && (!(at.isAllocationReversed() && (ar.getSectionSeqNumber() == 1)))) {
            // not at either end - determine the next section 
            int seqNum = ar.getSectionSeqNumber();
            if (at.isAllocationReversed()) {
                seqNum -= 1;
            } else {
                seqNum += 1;
            }
            ArrayList<Section> secList = at.getTransit().getSectionListBySeq(seqNum);
            if (secList.size() == 1) {
                nextSection = secList.get(0);
            } else if (secList.size() > 1) {
                if (_AutoAllocate) {
                    nextSection = autoChoice(secList, ar);
                } else {
                    nextSection = dispatcherChoice(secList, ar);
                }
            }
            nextSectionSeqNo = seqNum;
        } else if (at.getReverseAtEnd() && (!at.isAllocationReversed()) && (s == at.getEndBlockSection()) && (ar.getSectionSeqNumber() == at.getEndBlockSectionSequenceNumber())) {
            // need to reverse Transit direction when train is in the last Section, set next section.
            nextSectionSeqNo = at.getEndBlockSectionSequenceNumber() - 1;
            at.setAllocationReversed(true);
            ArrayList<Section> secList = at.getTransit().getSectionListBySeq(nextSectionSeqNo);
            if (secList.size() == 1) {
                nextSection = secList.get(0);
            } else if (secList.size() > 1) {
                if (_AutoAllocate) {
                    nextSection = autoChoice(secList, ar);
                } else {
                    nextSection = dispatcherChoice(secList, ar);
                }
            }
        } else if (((!at.isAllocationReversed()) && (s == at.getEndBlockSection()) && (ar.getSectionSeqNumber() == at.getEndBlockSectionSequenceNumber())) || (at.isAllocationReversed() && (ar.getSectionSeqNumber() == 1))) {
            //      has reached the beginning of the Transit--check for automatic restart
            if (at.getResetWhenDone()) {
                if (at.getDelayedRestart() != ActiveTrain.NODELAY) {
                    at.holdAllocation(true);
                }
                nextSection = at.getSecondAllocatedSection();
                nextSectionSeqNo = 2;
                at.setAllocationReversed(false);
            }
        }
        //This might be the location to check to see if we have an intermediate section that we then need to perform extra checks on.
        //Working on the basis that if the nextsection is not null, then we are not at the end of the transit.
        ArrayList<Section> intermediateSections = new ArrayList<>();
        Section mastHeldAtSection = null;
        if (nextSection != null && ar.getSection().getProperty("intermediateSection") != null && ((Boolean) ar.getSection().getProperty("intermediateSection")).booleanValue()) {
            String property = "forwardMast";
            if (at.isAllocationReversed()) {
                property = "reverseMast";
            }
            if (ar.getSection().getProperty(property) != null) {
                SignalMast endMast = InstanceManager.getDefault(jmri.SignalMastManager.class).getSignalMast(ar.getSection().getProperty(property).toString());
                if (endMast != null) {
                    if (endMast.getHeld()) {
                        mastHeldAtSection = ar.getSection();
                    }
                }
            }
            ArrayList<TransitSection> tsList = ar.getActiveTrain().getTransit().getTransitSectionList();
            boolean found = false;
            if (at.isAllocationReversed()) {
                for (int i = tsList.size() - 1; i > 0; i--) {
                    TransitSection ts = tsList.get(i);
                    if (ts.getSection() == ar.getSection() && ts.getSequenceNumber() == ar.getSectionSeqNumber()) {
                        found = true;
                    } else if (found) {
                        if (ts.getSection().getProperty("intermediateSection") != null && ((Boolean) ts.getSection().getProperty("intermediateSection")).booleanValue()) {
                            intermediateSections.add(ts.getSection());
                        } else {
                            //we add the section after the last intermediate in, so that the last allocation request can be built correctly
                            intermediateSections.add(ts.getSection());
                            break;
                        }
                    }
                }
            } else {
                for (int i = 0; i <= tsList.size() - 1; i++) {
                    TransitSection ts = tsList.get(i);
                    if (ts.getSection() == ar.getSection() && ts.getSequenceNumber() == ar.getSectionSeqNumber()) {
                        found = true;
                    } else if (found) {
                        if (ts.getSection().getProperty("intermediateSection") != null && ((Boolean) ts.getSection().getProperty("intermediateSection")).booleanValue()) {
                            intermediateSections.add(ts.getSection());
                        } else {
                            //we add the section after the last intermediate in, so that the last allocation request can be built correctly
                            intermediateSections.add(ts.getSection());
                            break;
                        }
                    }
                }
            }
            boolean intermediatesOccupied = false;
            for (int i = 0; i < intermediateSections.size() - 1; i++) {
                // ie do not check last section which is not an intermediate section
                Section se = intermediateSections.get(i);
                if (se.getState() == Section.FREE) {
                    //If the section state is free, we need to look to see if any of the blocks are used else where
                    Section conflict = checkBlocksNotInAllocatedSection(se, null);
                    if (conflict != null) {
                        //We might need to find out if the section which the block is allocated to is one in our transit, and if so is it running in the same direction.
                        return null;
                    } else {
                        if (mastHeldAtSection == null) {
                            if (se.getProperty(property) != null) {
                                SignalMast endMast = InstanceManager.getDefault(jmri.SignalMastManager.class).getSignalMast(se.getProperty(property).toString());
                                if (endMast != null && endMast.getHeld()) {
                                    mastHeldAtSection = se;
                                }
                            }
                        }
                    }
                } else if (at.getLastAllocatedSection() != null && se.getState() != at.getLastAllocatedSection().getState()) {
                    //Last allocated section and the checking section direction are not the same
                    return null;
                } else {
                    intermediatesOccupied = true;
                }
            }
            //If the intermediate sections are already occupied or allocated then we clear the intermediate list and only allocate the original request.
            if (intermediatesOccupied) {
                intermediateSections = new ArrayList<>();
            }
        }
        // Note: Turnout checking and/or setting is not performed when allocating an extra section.
        if ((_UseConnectivity) && (ar.getSectionSeqNumber() != -99)) {
            if (!checkTurnoutStates(s, ar.getSectionSeqNumber(), nextSection, at, at.getLastAllocatedSection())) {
                return null;
            }
            Section preSec = s;
            Section tmpcur = nextSection;
            int tmpSeqNo = nextSectionSeqNo;
            //The first section in the list will be the same as the nextSection, so we skip that.
            for (int i = 1; i < intermediateSections.size(); i++) {
                Section se = intermediateSections.get(i);
                if (preSec == mastHeldAtSection) {
                    log.debug("Section is beyond held mast do not set turnouts " + (tmpcur != null ? tmpcur.getDisplayName() : "null"));
                    break;
                }
                if (!checkTurnoutStates(tmpcur, tmpSeqNo, se, at, preSec)) {
                    return null;
                }
                preSec = tmpcur;
                tmpcur = se;
                if (at.isAllocationReversed()) {
                    tmpSeqNo -= 1;
                } else {
                    tmpSeqNo += 1;
                }
            }
        }
        as = allocateSection(at, s, ar.getSectionSeqNumber(), nextSection, nextSectionSeqNo, ar.getSectionDirection());
        if (intermediateSections.size() > 1 && mastHeldAtSection != s) {
            Section tmpcur = nextSection;
            int tmpSeqNo = nextSectionSeqNo;
            int tmpNxtSeqNo = tmpSeqNo;
            if (at.isAllocationReversed()) {
                tmpNxtSeqNo -= 1;
            } else {
                tmpNxtSeqNo += 1;
            }
            //The first section in the list will be the same as the nextSection, so we skip that.
            for (int i = 1; i < intermediateSections.size(); i++) {
                if (tmpcur == mastHeldAtSection) {
                    log.debug("Section is beyond held mast do not allocate any more sections " + (tmpcur != null ? tmpcur.getDisplayName() : "null"));
                    break;
                }
                Section se = intermediateSections.get(i);
                as = allocateSection(at, tmpcur, tmpSeqNo, se, tmpNxtSeqNo, ar.getSectionDirection());
                tmpcur = se;
                if (at.isAllocationReversed()) {
                    tmpSeqNo -= 1;
                    tmpNxtSeqNo -= 1;
                } else {
                    tmpSeqNo += 1;
                    tmpNxtSeqNo += 1;
                }
            }
        }
        int ix = -1;
        for (int i = 0; i < allocationRequests.size(); i++) {
            if (ar == allocationRequests.get(i)) {
                ix = i;
            }
        }
        allocationRequests.remove(ix);
        ar.dispose();
        allocationRequestTableModel.fireTableDataChanged();
        activeTrainsTableModel.fireTableDataChanged();
        if (allocatedSectionTableModel != null) {
            allocatedSectionTableModel.fireTableDataChanged();
        }
        if (extraFrame != null) {
            cancelExtraRequested(null);
        }
        if (_AutoAllocate) {
            requestNextAllocation(at);
            autoAllocate.scanAllocationRequestList(allocationRequests);
        }
    } else {
        log.error("Null Allocation Request provided in request to allocate a section");
    }
    return as;
}
Also used : TransitSection(jmri.TransitSection) ArrayList(java.util.ArrayList) Section(jmri.Section) TransitSection(jmri.TransitSection) EntryPoint(jmri.EntryPoint) SignalMast(jmri.SignalMast)

Example 2 with TransitSection

use of jmri.TransitSection in project JMRI by JMRI.

the class TransitTableAction method initializeEditInformation.

private void initializeEditInformation() {
    sectionList.clear();
    curSection = null;
    curSectionDirection = 0;
    curSequenceNum = 0;
    prevSection = null;
    prevSectionDirection = 0;
    if (curTransit != null) {
        userName.setText(curTransit.getUserName());
        ArrayList<TransitSection> tsList = curTransit.getTransitSectionList();
        for (int i = 0; i < tsList.size(); i++) {
            TransitSection ts = tsList.get(i);
            if (ts != null) {
                sectionList.add(ts.getSection());
                sequence[i] = ts.getSequenceNumber();
                direction[i] = ts.getDirection();
                action[i] = ts.getTransitSectionActionList();
                alternate[i] = ts.isAlternate();
            }
        }
        int index = sectionList.size() - 1;
        while (alternate[index] && (index > 0)) {
            index--;
        }
        if (index >= 0) {
            curSection = sectionList.get(index);
            curSequenceNum = sequence[index];
            if (index > 0) {
                curSectionDirection = direction[index];
            }
            index--;
            while ((index >= 0) && alternate[index]) {
                index--;
            }
            if (index >= 0) {
                prevSection = sectionList.get(index);
                prevSectionDirection = direction[index];
            }
        }
    }
    sectionTableModel.fireTableDataChanged();
}
Also used : TransitSection(jmri.TransitSection) EntryPoint(jmri.EntryPoint)

Example 3 with TransitSection

use of jmri.TransitSection in project JMRI by JMRI.

the class TransitTableAction method setTransitInformation.

private boolean setTransitInformation() {
    if (curTransit == null) {
        return false;
    }
    curTransit.removeAllSections();
    for (int i = 0; i < sectionList.size(); i++) {
        TransitSection ts = new TransitSection(sectionList.get(i), sequence[i], direction[i], alternate[i]);
        ArrayList<TransitSectionAction> list = action[i];
        if (list != null) {
            for (int j = 0; j < list.size(); j++) {
                ts.addAction(list.get(j));
            }
        }
        curTransit.addTransitSection(ts);
    }
    return true;
}
Also used : TransitSection(jmri.TransitSection) TransitSectionAction(jmri.TransitSectionAction) EntryPoint(jmri.EntryPoint)

Example 4 with TransitSection

use of jmri.TransitSection in project JMRI by JMRI.

the class AutoAllocate method firstTrainLeadsSecond.

private boolean firstTrainLeadsSecond(ActiveTrain at, ActiveTrain nt) {
    int aSeq = getCurrentSequenceNumber(at);
    Section aSec = getCurSection();
    int nSeq = getCurrentSequenceNumber(nt);
    Section nSec = getCurSection();
    ArrayList<TransitSection> atsList = at.getTransit().getTransitSectionList();
    if (!at.isTransitReversed()) {
        for (int i = 0; i < atsList.size(); i++) {
            if (atsList.get(i).getSequenceNumber() > aSeq) {
                if (atsList.get(i).getSection() == nSec) {
                    // first train has not yet reached second train position
                    return false;
                }
            }
        }
    } else {
        for (int i = atsList.size() - 1; i <= 0; i--) {
            if (atsList.get(i).getSequenceNumber() < aSeq) {
                if (atsList.get(i).getSection() == nSec) {
                    // first train has not yet reached second train position
                    return false;
                }
            }
        }
    }
    ArrayList<TransitSection> ntsList = nt.getTransit().getTransitSectionList();
    if (!nt.isTransitReversed()) {
        for (int i = 0; i < ntsList.size(); i++) {
            if (ntsList.get(i).getSequenceNumber() > nSeq) {
                if (ntsList.get(i).getSection() == aSec) {
                    // second train has found first train in its on coming Sections
                    return true;
                }
            }
        }
    } else {
        for (int i = ntsList.size() - 1; i <= 0; i--) {
            if (ntsList.get(i).getSequenceNumber() < nSeq) {
                if (ntsList.get(i).getSection() == aSec) {
                    // second train has found first train in its on coming Sections
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : TransitSection(jmri.TransitSection) Section(jmri.Section) TransitSection(jmri.TransitSection)

Example 5 with TransitSection

use of jmri.TransitSection in project JMRI by JMRI.

the class AutoAllocate method willTrainsCross.

private boolean willTrainsCross(ActiveTrain at, ActiveTrain nt) {
    // returns true if both trains will eventually reach the others position
    int aSeq = getCurrentSequenceNumber(at);
    Section aSec = getCurSection();
    int nSeq = getCurrentSequenceNumber(nt);
    Section nSec = getCurSection();
    ArrayList<TransitSection> atsList = at.getTransit().getTransitSectionList();
    boolean found = false;
    if (!at.isTransitReversed()) {
        for (int i = 0; (i < atsList.size()) && (!found); i++) {
            if (atsList.get(i).getSequenceNumber() > aSeq) {
                if (atsList.get(i).getSection() == nSec) {
                    // first train has reached second train position
                    found = true;
                }
            }
        }
    } else {
        for (int i = atsList.size() - 1; (i <= 0) && (!found); i--) {
            if (atsList.get(i).getSequenceNumber() < aSeq) {
                if (atsList.get(i).getSection() == nSec) {
                    // first train has reached second train position
                    found = true;
                }
            }
        }
    }
    if (!found) {
        return false;
    }
    ArrayList<TransitSection> ntsList = nt.getTransit().getTransitSectionList();
    if (!nt.isTransitReversed()) {
        for (int i = 0; i < ntsList.size(); i++) {
            if (ntsList.get(i).getSequenceNumber() > nSeq) {
                if (ntsList.get(i).getSection() == aSec) {
                    // second train has found first train in its on coming Sections
                    return true;
                }
            }
        }
    } else {
        for (int i = ntsList.size() - 1; i <= 0; i--) {
            if (ntsList.get(i).getSequenceNumber() < nSeq) {
                if (ntsList.get(i).getSection() == aSec) {
                    // second train has found first train in its on coming Sections
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : TransitSection(jmri.TransitSection) Section(jmri.Section) TransitSection(jmri.TransitSection)

Aggregations

TransitSection (jmri.TransitSection)9 Section (jmri.Section)6 EntryPoint (jmri.EntryPoint)3 TransitSectionAction (jmri.TransitSectionAction)3 Transit (jmri.Transit)2 TransitManager (jmri.TransitManager)2 Element (org.jdom2.Element)2 ArrayList (java.util.ArrayList)1 SignalMast (jmri.SignalMast)1