use of jmri.Block in project JMRI by JMRI.
the class DispatcherFrame method connected.
private boolean connected(Section s1, Section s2) {
if ((s1 != null) && (s2 != null)) {
ArrayList<EntryPoint> s1Entries = (ArrayList<EntryPoint>) s1.getEntryPointList();
ArrayList<EntryPoint> s2Entries = (ArrayList<EntryPoint>) s2.getEntryPointList();
for (int i = 0; i < s1Entries.size(); i++) {
Block b = s1Entries.get(i).getFromBlock();
for (int j = 0; j < s2Entries.size(); j++) {
if (b == s2Entries.get(j).getBlock()) {
return true;
}
}
}
}
return false;
}
use of jmri.Block in project JMRI by JMRI.
the class AutoTrainAction method handleBlockStateChange.
// this method is called when the state of a Block in an Allocated Section changes
protected synchronized void handleBlockStateChange(AllocatedSection as, Block b) {
// Ignore call if not waiting on Block state change
for (int i = 0; i < _activeActionList.size(); i++) {
if (_activeActionList.get(i).getWaitingForBlock()) {
TransitSectionAction tsa = _activeActionList.get(i);
Block target = InstanceManager.getDefault(jmri.BlockManager.class).getBlock(tsa.getStringWhen());
if (b == target) {
// waiting on state change for this block
if (((b.getState() == Block.OCCUPIED) && (tsa.getWhenCode() == TransitSectionAction.BLOCKENTRY)) || ((b.getState() == Block.UNOCCUPIED) && (tsa.getWhenCode() == TransitSectionAction.BLOCKEXIT))) {
checkDelay(tsa);
}
}
}
}
}
use of jmri.Block in project JMRI by JMRI.
the class LayoutBlock method updateRoutingInfo.
void updateRoutingInfo(Routes route) {
if (route.getHopCount() >= 254) {
return;
}
Block destBlock = route.getDestBlock();
RoutingPacket update = new RoutingPacket(UPDATE, destBlock, getBestRouteByHop(destBlock).getHopCount() + 1, ((getBestRouteByMetric(destBlock).getMetric()) + metric), ((getBestRouteByMetric(destBlock).getMetric()) + block.getLengthMm()), -1, getNextPacketID());
firePropertyChange("routing", null, update);
}
use of jmri.Block in project JMRI by JMRI.
the class LayoutBlock method updateRoutingInfo.
//This lot might need changing to only forward on the best route details.
@SuppressFBWarnings(value = "FE_FLOATING_POINT_EQUALITY", justification = "checking against a error value of -1; bad practice to use values for errors, but not an FFPE")
void updateRoutingInfo(LayoutBlock src, RoutingPacket update) {
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " src: " + src.getDisplayName() + ", block: " + update.getBlock().getDisplayName() + ", hopCount: " + update.getHopCount() + ", metric: " + update.getMetric() + ", status: " + update.getBlockState() + ", packetID: " + update.getPacketId());
}
Block srcblk = src.getBlock();
Adjacencies adj = getAdjacency(srcblk);
if (adj == null) {
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " packet is from a src that is not registered " + srcblk.getDisplayName());
}
//Then we will simply reject it.
return;
}
if (updatePacketActedUpon(update.getPacketId())) {
if (adj.updatePacketActedUpon(update.getPacketId())) {
if (enableUpdateRouteLogging) {
log.info("Reject packet update as we have already acted up on it from this neighbour");
}
return;
}
}
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " an Update packet from neighbour " + src.getDisplayName());
}
Block updateBlock = update.getBlock();
//for the block that they are referring too.
if (updateBlock == this.getBlock()) {
if (enableUpdateRouteLogging) {
log.info("Reject packet update as it is a route advertised by our selves");
}
return;
}
Routes ro = null;
boolean neighbour = false;
if (updateBlock == srcblk) {
//Very likely that this update is from a neighbour about its own status.
ro = getValidRoute(this.getBlock(), updateBlock);
neighbour = true;
} else {
ro = getValidRoute(srcblk, updateBlock);
}
if (ro == null) {
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " update is from a source that we do not have listed as a route to the destination");
log.info("From " + this.getDisplayName() + " update packet is for a block that we do not have route registered for " + updateBlock.getDisplayName());
}
//Then we will simply reject it.
return;
}
/*This prevents us from entering into an update loop.
We only add it to our list once it has passed through as being a valid
packet, otherwise we may get the same packet id back, but from a valid source
which would end up be rejected*/
actedUponUpdates.add(update.getPacketId());
adj.addPacketRecievedFromNeighbour(update.getPacketId());
int hopCount = update.getHopCount();
int packetmetric = update.getMetric();
int blockstate = update.getBlockState();
float length = update.getLength();
//Need to add in a check for a block that is directly connected.
if (hopCount != -1) {
//int oldHop = ro.getHopCount();
if (ro.getHopCount() != hopCount) {
if (enableUpdateRouteLogging) {
log.info(this.getDisplayName() + " Hop counts to " + ro.getDestBlock().getDisplayName() + " not the same so will change from " + ro.getHopCount() + " to " + hopCount);
}
ro.setHopCount(hopCount);
hopCount++;
} else {
//No point in forwarding on the update if the hopcount hasn't changed
hopCount = -1;
}
}
//bad to use values as errors, but it's pre-existing code, and code wins
if ((int) length != -1) {
//Length is added at source
float oldLength = ro.getLength();
if (oldLength != length) {
ro.setLength(length);
boolean forwardUpdate = true;
if (ro != getBestRouteByLength(update.getBlock())) {
forwardUpdate = false;
}
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " updating length from " + oldLength + " to " + length);
}
if (neighbour) {
length = srcblk.getLengthMm();
adj.setLength(length);
//Also if neighbour we need to update the cost of the routes via it to reflect the new metric 02/20/2011
if (forwardUpdate) {
ArrayList<Routes> neighbourRoute = getNextRoutes(srcblk);
//that will need to have their metric updated to reflect the change.
for (int i = 0; i < neighbourRoute.size(); i++) {
Routes nRo = neighbourRoute.get(i);
//Need to remove old metric to the neigbour, then add the new one on
float updateLength = nRo.getLength();
updateLength = (updateLength - oldLength) + length;
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " update metric for route " + nRo.getDestBlock().getDisplayName() + " from " + nRo.getLength() + " to " + updateLength);
}
nRo.setLength(updateLength);
ArrayList<Block> messageRecipients = getThroughPathDestinationBySource(srcblk);
RoutingPacket newUpdate = new RoutingPacket(UPDATE, nRo.getDestBlock(), -1, -1, updateLength + block.getLengthMm(), -1, getNextPacketID());
updateRoutesToNeighbours(messageRecipients, nRo, newUpdate);
}
}
} else if (forwardUpdate) {
//This can cause a loop, if the layout is in a loop, so we send out the same packetID.
ArrayList<Block> messageRecipients = getThroughPathSourceByDestination(srcblk);
RoutingPacket newUpdate = new RoutingPacket(UPDATE, updateBlock, -1, -1, length + block.getLengthMm(), -1, update.getPacketId());
updateRoutesToNeighbours(messageRecipients, ro, newUpdate);
}
length = length + metric;
} else {
length = -1;
}
}
if (packetmetric != -1) {
//Metric is added at source
//Keep a reference of the old metric.
int oldmetric = ro.getMetric();
if (oldmetric != packetmetric) {
ro.setMetric(packetmetric);
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " updating metric from " + oldmetric + " to " + packetmetric);
}
boolean forwardUpdate = true;
if (ro != getBestRouteByMetric(update.getBlock())) {
forwardUpdate = false;
}
//rather than trust what is in the message at this stage.
if (neighbour) {
packetmetric = src.getBlockMetric();
adj.setMetric(packetmetric);
if (forwardUpdate) {
//ro.setMetric(packetmetric);
//Also if neighbour we need to update the cost of the routes via it to
//reflect the new metric 02/20/2011
ArrayList<Routes> neighbourRoute = getNextRoutes(srcblk);
//will need to have their metric updated to reflect the change.
for (int i = 0; i < neighbourRoute.size(); i++) {
Routes nRo = neighbourRoute.get(i);
//Need to remove old metric to the neigbour, then add the new one on
int updatemet = nRo.getMetric();
updatemet = (updatemet - oldmetric) + packetmetric;
if (enableUpdateRouteLogging) {
log.info("From " + this.getDisplayName() + " update metric for route " + nRo.getDestBlock().getDisplayName() + " from " + nRo.getMetric() + " to " + updatemet);
}
nRo.setMetric(updatemet);
ArrayList<Block> messageRecipients = getThroughPathDestinationBySource(srcblk);
RoutingPacket newUpdate = new RoutingPacket(UPDATE, nRo.getDestBlock(), hopCount, updatemet + metric, -1, -1, getNextPacketID());
updateRoutesToNeighbours(messageRecipients, nRo, newUpdate);
}
}
} else if (forwardUpdate) {
//This can cause a loop, if the layout is in a loop, so we send out the same packetID.
ArrayList<Block> messageRecipients = getThroughPathSourceByDestination(srcblk);
RoutingPacket newUpdate = new RoutingPacket(UPDATE, updateBlock, hopCount, packetmetric + metric, -1, -1, update.getPacketId());
updateRoutesToNeighbours(messageRecipients, ro, newUpdate);
}
packetmetric = packetmetric + metric;
//Think we need a list of routes that originate from this source neighbour
} else {
//No point in forwarding on the update if the metric hasn't changed
packetmetric = -1;
//Potentially when we do this we need to update all the routes that go via this block, not just this route.
}
}
if (blockstate != -1) {
//We will update all the destination blocks with the new state, it
//saves re-firing off new updates block status
boolean stateUpdated = false;
ArrayList<Routes> rtr = getDestRoutes(updateBlock);
for (Routes rt : rtr) {
if (rt.getState() != blockstate) {
stateUpdated = true;
rt.stateChange();
}
}
if (stateUpdated) {
RoutingPacket newUpdate = new RoutingPacket(UPDATE, updateBlock, -1, -1, -1, blockstate, getNextPacketID());
firePropertyChange("routing", null, newUpdate);
}
}
//We need to expand on this so that any update to routing metric is propergated correctly
if ((packetmetric != -1) || (hopCount != -1) || (length != -1)) {
//We only want to send the update on to neighbours that we have advertised the route to.
ArrayList<Block> messageRecipients = getThroughPathSourceByDestination(srcblk);
RoutingPacket newUpdate = new RoutingPacket(UPDATE, updateBlock, hopCount, packetmetric, length, blockstate, update.getPacketId());
updateRoutesToNeighbours(messageRecipients, ro, newUpdate);
}
//Was just pass on hop count
}
use of jmri.Block in project JMRI by JMRI.
the class LayoutBlock method updateNeighbourPacketFlow.
protected void updateNeighbourPacketFlow(Adjacencies neighbour, final int flow) {
if (neighbour.getPacketFlow() == flow) {
return;
}
final LayoutBlock neighLBlock = neighbour.getLayoutBlock();
Runnable r = () -> {
neighLBlock.updateNeighbourPacketFlow(block, flow);
};
Block neighBlock = neighbour.getBlock();
int oldPacketFlow = neighbour.getPacketFlow();
neighbour.setPacketFlow(flow);
javax.swing.SwingUtilities.invokeLater(r);
if (flow == TXONLY) {
neighBlock.addBlockDenyList(this.block);
neighLBlock.removePropertyChangeListener(this);
//This should remove routes learned from our neighbour
ArrayList<Routes> tmpBlock = removeRouteRecievedFromNeighbour(neighBlock);
notifyNeighboursOfRemoval(tmpBlock, neighBlock);
//Need to also remove all through paths to this neighbour
for (int i = throughPaths.size() - 1; i > -1; i--) {
if (throughPaths.get(i).getDestinationBlock() == neighBlock) {
throughPaths.remove(i);
firePropertyChange("through-path-removed", null, null);
}
}
//We potentially will need to re-advertise routes to this neighbour
if (oldPacketFlow == RXONLY) {
addThroughPath(neighbour);
}
} else if (flow == RXONLY) {
neighLBlock.addPropertyChangeListener(this);
neighBlock.removeBlockDenyList(this.block);
this.block.addBlockDenyList(neighBlock);
for (int i = throughPaths.size() - 1; i > -1; i--) {
if (throughPaths.get(i).getSourceBlock() == neighBlock) {
throughPaths.remove(i);
firePropertyChange("through-path-removed", null, null);
}
}
//Might need to rebuild through paths.
if (oldPacketFlow == TXONLY) {
routes.add(new Routes(neighBlock, this.getBlock(), 1, neighbour.getDirection(), neighLBlock.getBlockMetric(), neighBlock.getLengthMm()));
addThroughPath(neighbour);
}
//We would need to withdraw the routes that we advertise to the neighbour
} else if (flow == RXTX) {
neighBlock.removeBlockDenyList(this.block);
this.block.removeBlockDenyList(neighBlock);
neighLBlock.addPropertyChangeListener(this);
//Might need to rebuild through paths.
if (oldPacketFlow == TXONLY) {
routes.add(new Routes(neighBlock, this.getBlock(), 1, neighbour.getDirection(), neighLBlock.getBlockMetric(), neighBlock.getLengthMm()));
}
addThroughPath(neighbour);
}
}
Aggregations