diff --git a/pom.xml b/pom.xml
index c457cde..4a85f24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 1.2.50
+ 1.2.51
Web4Rail
jar
Java Model Railway Control
diff --git a/src/main/java/de/srsoftware/web4rail/BaseClass.java b/src/main/java/de/srsoftware/web4rail/BaseClass.java
index c8c884e..bd68abb 100644
--- a/src/main/java/de/srsoftware/web4rail/BaseClass.java
+++ b/src/main/java/de/srsoftware/web4rail/BaseClass.java
@@ -77,6 +77,7 @@ public abstract class BaseClass implements Constants{
}
public Context block(Block newBlock) {
+ LOG.debug("{}.block({})",this,newBlock);
block = newBlock;
return this;
}
@@ -130,6 +131,7 @@ public abstract class BaseClass implements Constants{
}
public Context direction(Direction newDirection) {
+ LOG.debug("{}.direction({})",this,newDirection);
direction = newDirection;
return this;
}
@@ -140,6 +142,7 @@ public abstract class BaseClass implements Constants{
public Context setMain(BaseClass object) {
main = object;
+ LOG.debug("{}.setMain({})",this,object);
if (main instanceof Tile) this.tile = (Tile) main;
if (main instanceof Contact) this.contact = (Contact) main;
if (main instanceof Block) this.block = (Block) main;
@@ -183,6 +186,7 @@ public abstract class BaseClass implements Constants{
}
public Context train(Train newTrain) {
+ LOG.debug("{}.train({})",this,newTrain);
train = newTrain;
return this;
}
diff --git a/src/main/java/de/srsoftware/web4rail/PathFinder.java b/src/main/java/de/srsoftware/web4rail/PathFinder.java
index b8ec8f7..08f3cb0 100644
--- a/src/main/java/de/srsoftware/web4rail/PathFinder.java
+++ b/src/main/java/de/srsoftware/web4rail/PathFinder.java
@@ -17,6 +17,7 @@ public class PathFinder extends BaseClass{
private static final Logger LOG = LoggerFactory.getLogger(PathFinder.class);
private static TreeMap> availableRoutes(Context context,HashSet visitedRoutes){
+ LOG.debug("PathFinder.availableRoutes({})",context);
TreeMap> availableRoutes = new TreeMap>();
String inset = "";
@@ -53,7 +54,7 @@ public class PathFinder extends BaseClass{
continue;
}
if (!routeCandidate.allowed(context)) continue; // Zug darf auf Grund einer nicht erfüllten Bedingung nicht auf die Route
- if (!routeCandidate.isFreeFor(train)) continue; // Route ist nicht frei
+ if (!routeCandidate.isFreeFor(context.route(routeCandidate))) continue; // Route ist nicht frei
int priority = 0;
if (isSet(direction) && routeCandidate.startDirection != direction) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges
if (!train.pushPull) continue; // Zug kann nicht wenden
@@ -99,6 +100,7 @@ public class PathFinder extends BaseClass{
}
public static Route chooseRoute(Context context) {
+ LOG.debug("PathFinder.chooseRoute({})",context);
TreeMap> availableRoutes = PathFinder.availableRoutes(context,new HashSet());
if (availableRoutes.isEmpty()) return null;
Entry> entry = availableRoutes.lastEntry();
diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java
index f23ac59..7d024c9 100644
--- a/src/main/java/de/srsoftware/web4rail/Plan.java
+++ b/src/main/java/de/srsoftware/web4rail/Plan.java
@@ -33,7 +33,6 @@ import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Table;
import de.srsoftware.web4rail.tiles.Block;
-import de.srsoftware.web4rail.tiles.BlockContact;
import de.srsoftware.web4rail.tiles.BlockH;
import de.srsoftware.web4rail.tiles.BlockV;
import de.srsoftware.web4rail.tiles.Bridge;
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index b5dae03..b8ceaeb 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -423,10 +423,10 @@ public class Route extends BaseClass {
public void finish() {
context.clear(); // prevent delayed actions from firing after route has finished
setSignals(Signal.STOP);
- for (Tile tile : path) tile.setRoute(null);
+ for (Tile tile : path) tile.unset(this);
Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) {
- lastTile.set(null);
+ lastTile.setTrain(null);
if (isSet(train)) train.removeChild(lastTile);
}
if (isSet(train)) {
@@ -445,6 +445,7 @@ public class Route extends BaseClass {
}
public boolean fireSetupActions() {
+ LOG.debug("{}.firesSetupActions({})",this);
ActionList setupActions = triggeredActions.get(ROUTE_SETUP);
if (isSet(setupActions) && !setupActions.fire(context)) return false;
state = State.PREPARED;
@@ -475,9 +476,13 @@ public class Route extends BaseClass {
return disabled;
}
- public boolean isFreeFor(Train newTrain) {
- for (int i=1; i alreadyLocked = new Vector();
HashSet ignoredPath = new HashSet();
if (isSet(ignoredRoute)) ignoredPath.addAll(ignoredRoute.path);
boolean success = true;
for (Tile tile : path) {
if (ignoredPath.contains(tile)) continue;
try {
- alreadyLocked.add(tile.setRoute(this));
+ tile.setRoute(this);
} catch (IllegalStateException e) {
+ LOG.debug("{}.lockIgnoring(...) failed at {}, rolling back",this,tile);
success = false;
break;
}
}
- if (success) {
- state = State.LOCKED;
- } else for (Tile tile :alreadyLocked) tile.setRoute(null);
+ if (success) state = State.LOCKED;
return success;
}
@@ -795,11 +799,16 @@ public class Route extends BaseClass {
}
public boolean reset() {
+ LOG.debug("{}.reset()",this);
setSignals(Signal.STOP);
- for (Tile tile : path) tile.setRoute(null);
+ for (Tile tile : path) {
+ try {
+ tile.unset(this);
+ } catch (IllegalArgumentException e) {}
+ }
Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) {
- lastTile.set(null);
+ lastTile.setTrain(null);
if (isSet(train)) train.removeChild(lastTile);
}
if (isSet(train)) {
@@ -807,7 +816,8 @@ public class Route extends BaseClass {
train.heading(startDirection);
if (train.route == this) train.route = null;
train = null;
- }
+ }
+ LOG.debug("chlearing triggeredContacts of {}",this);
triggeredContacts.clear();
state = State.FREE;
return true;
@@ -840,6 +850,7 @@ public class Route extends BaseClass {
}
public boolean setSignals(String state) {
+ LOG.debug("{}.setSignals({})",this,state);
for (Signal signal : signals) {
if (!signal.state(isNull(state) ? Signal.GO : state)) return false;
}
@@ -861,6 +872,7 @@ public class Route extends BaseClass {
}
public boolean start(Train newTrain) {
+ LOG.debug("{}.start({})",this,newTrain);
if (isNull(newTrain)) return false; // can't set route's train to null
if (isSet(train)) {
if (newTrain != train) return false; // can't alter route's train
diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java
index ae169ec..5502a79 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java
@@ -67,6 +67,7 @@ public class ActionList extends Action implements Iterable{
}
public boolean fire(Context context) {
+ LOG.debug("{}.fire({})",this,context);
if (context.invalidated()) {
LOG.debug("Context has been invalidated, aborting {}",this);
return false;
diff --git a/src/main/java/de/srsoftware/web4rail/actions/PreserveRoute.java b/src/main/java/de/srsoftware/web4rail/actions/PreserveRoute.java
index 0161d50..ecf8135 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/PreserveRoute.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/PreserveRoute.java
@@ -25,7 +25,10 @@ public class PreserveRoute extends Action {
if (train.destination() == route.endBlock()) return true;
Range waitTime = route.endBlock().getWaitTime(train,route.endDirection);
- if (waitTime.max > 0) return true; // train is expected to wait in next block.
+ if (waitTime.max > 0) {
+ LOG.debug("Not preserving route, as train needs to stop in following block!");
+ return true; // train is expected to wait in next block.
+ }
train.reserveNext();
return true;
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java
index fb97106..8034022 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Car.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java
@@ -309,6 +309,7 @@ public class Car extends BaseClass implements Comparable{
}
public Object turn() {
+ LOG.debug("{}.turn()",this);
orientation = !orientation;
return t("Reversed {}.",this);
}
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java
index 8504dc5..6f1ab76 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Train.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java
@@ -100,8 +100,11 @@ public class Train extends BaseClass implements Comparable {
if (stop) return;
if (isNull(route)) { // may have been set by start action in between
Object o = Train.this.start();
- if (o instanceof String) plan.stream((String)o);
- if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder
+ LOG.debug("Train.start called, route now is {}",route);
+ if (isSet(route)) {
+ if (o instanceof String) plan.stream((String)o);
+ //if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder
+ } else Thread.sleep(1000); // limit load on PathFinder
}
} else Thread.sleep(250);
}
@@ -306,15 +309,15 @@ public class Train extends BaseClass implements Comparable {
public String directedName() {
String result = name();
- if (isSet(autopilot)) result="℗"+result;
+ String mark = isSet(autopilot) ? "ⓐ" : "";
if (isNull(direction)) return result;
switch (direction) {
case NORTH:
case WEST:
- return '←'+result;
+ return '←'+mark+result;
case SOUTH:
case EAST:
- return result+'→';
+ return result+mark+'→';
}
return result;
}
@@ -335,7 +338,7 @@ public class Train extends BaseClass implements Comparable {
}
public void dropTrace() {
- while (!trace.isEmpty()) trace.removeFirst().set(null);
+ while (!trace.isEmpty()) trace.removeFirst().setTrain(null);
}
private Tag faster(int steps) {
@@ -348,6 +351,7 @@ public class Train extends BaseClass implements Comparable {
}
public Train heading(Direction dir) {
+ LOG.debug("{}.heading({})",this,dir);
direction = dir;
if (isSet(currentBlock)) plan.place(currentBlock);
return this;
@@ -411,8 +415,8 @@ public class Train extends BaseClass implements Comparable {
if (json.has(DIRECTION)) direction = Direction.valueOf(json.getString(DIRECTION));
if (json.has(NAME)) name = json.getString(NAME);
if (json.has(TAGS)) json.getJSONArray(TAGS ).forEach(elem -> { tags.add(elem.toString()); });
- if (json.has(TRACE)) json.getJSONArray(TRACE).forEach(elem -> { trace.add(plan.get(new Id(elem.toString()), false).set(this)); });
- if (json.has(BLOCK)) currentBlock = (Block) plan.get(new Id(json.getString(BLOCK)), false).set(this); // do not move this up! during set, other fields will be referenced!
+ if (json.has(TRACE)) json.getJSONArray(TRACE).forEach(elem -> { trace.add(plan.get(new Id(elem.toString()), false).setTrain(this)); });
+ if (json.has(BLOCK)) currentBlock = (Block) plan.get(new Id(json.getString(BLOCK)), false).setTrain(this); // do not move this up! during set, other fields will be referenced!
if (json.has(LOCOS)) { // for downward compatibility
for (Object id : json.getJSONArray(LOCOS)) add(BaseClass.get(new Id(""+id)));
}
@@ -568,6 +572,7 @@ public class Train extends BaseClass implements Comparable {
@Override
public void removeChild(BaseClass child) {
+ LOG.debug("{}.removeChild({})",this,child);
if (child == route) route = null;
if (child == nextRoute) nextRoute = null;
if (child == currentBlock) currentBlock = null;
@@ -578,9 +583,13 @@ public class Train extends BaseClass implements Comparable {
}
public void reserveNext() {
+ LOG.debug("{}.reserveNext()",this);
Context context = new Context(this).route(route).block(route.endBlock()).direction(route.endDirection);
Route nextRoute = PathFinder.chooseRoute(context);
- if (isNull(nextRoute)) return;
+ if (isNull(nextRoute)) {
+ LOG.debug("{}.reserveNext() found no available route!",this);
+ return;
+ }
nextRoute.set(context);
boolean error = !nextRoute.lockIgnoring(route);
error = error || !nextRoute.fireSetupActions();
@@ -644,8 +653,9 @@ public class Train extends BaseClass implements Comparable {
}
public void set(Block newBlock) {
+ LOG.debug("{}.set({})",this,newBlock);
currentBlock = newBlock;
- if (isSet(currentBlock)) currentBlock.set(this);
+ if (isSet(currentBlock)) currentBlock.setTrain(this);
}
private String setDestination(HashMap params) {
@@ -692,6 +702,7 @@ public class Train extends BaseClass implements Comparable {
}
public void setSpeed(int newSpeed) {
+ LOG.debug("{}.setSpeed({})",this,newSpeed);
speed = Math.min(newSpeed,maxSpeed());
if (speed < 0) speed = 0;
cars.stream().filter(c -> c instanceof Locomotive).forEach(car -> ((Locomotive)car).setSpeed(speed));
@@ -714,9 +725,9 @@ public class Train extends BaseClass implements Comparable {
Tile tile = trace.get(i);
if (remainingLength>0) {
remainingLength-=tile.length();
- tile.set(this);
+ tile.setTrain(this);
} else {
- tile.set(null);
+ tile.setTrain(null);
trace.remove(i);
i--; // do not move to next index: remove shifted the next index towards us
}
@@ -729,18 +740,20 @@ public class Train extends BaseClass implements Comparable {
}
public Object start() throws IOException {
+ LOG.debug("{}.start()",this);
if (isNull(currentBlock)) return t("{} not in a block",this);
if (maxSpeed() == 0) return t("Train has maximum speed of 0 {}, cannot go!",speedUnit);
if (isSet(route)) route.reset(); // reset route previously chosen
String error = null;
if (isSet(nextRoute)) {
+ LOG.debug("{}.nextRoute = {}",this,nextRoute);
route = nextRoute;
if (!route.lock()) return t("Was not able to lock {}",route);
nextRoute = null;
route.set(new Context(this).block(currentBlock).direction(direction));
} else {
- Context context = new Context(this).block(currentBlock).direction(direction).train(this);
+ Context context = new Context(this).block(currentBlock).direction(direction);
route = PathFinder.chooseRoute(context);
if (isNull(route)) return t("No free routes from {}",currentBlock);
if (!route.lock()) error = t("Was not able to lock {}",route);
@@ -751,6 +764,7 @@ public class Train extends BaseClass implements Comparable {
if (isNull(error) && !route.start(this)) error = t("Was not able to assign {} to {}!",this,route);
if (isSet(error)) {
+ LOG.debug("{}.start:error = {}",this,error);
route.reset();
route = null;
return error;
@@ -766,8 +780,12 @@ public class Train extends BaseClass implements Comparable {
}
private void startSimulation() {
+ LOG.debug("{}.startSimulation({})",this);
for (Contact contact : route.contacts()) {
- if (contact.addr() != 0) return; // simulate train only when all contacts are non-physical
+ if (contact.addr() != 0) {
+ LOG.debug("{}.startSimulation aborted!",this);
+ return; // simulate train only when all contacts are non-physical
+ }
}
try {
Thread.sleep(1000);
@@ -844,7 +862,7 @@ public class Train extends BaseClass implements Comparable {
* @return
*/
public Tag turn() {
- LOG.debug("train.turn()");
+ LOG.debug("{}.turn()",this);
for (Car car : cars) car.turn();
Collections.reverse(cars);
return reverse();
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Bridge.java b/src/main/java/de/srsoftware/web4rail/tiles/Bridge.java
index 0abc950..85d8fd8 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Bridge.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Bridge.java
@@ -66,12 +66,6 @@ public abstract class Bridge extends Tile {
return super.load(json);
}
- public Tile set(Train train) {
- super.set(train);
- if (isSet(counterpart) && counterpart.train != train) counterpart.set(train);
- return this;
- }
-
@Override
public Tile setRoute(Route route) {
super.setRoute(route);
@@ -79,6 +73,12 @@ public abstract class Bridge extends Tile {
return this;
}
+ public Tile setTrain(Train train) {
+ super.setTrain(train);
+ if (isSet(counterpart) && counterpart.train != train) counterpart.setTrain(train);
+ return this;
+ }
+
@Override
protected Window properties(List