Browse Source

bugfixes, added debug output

lookup-tables
Stephan Richter 5 years ago
parent
commit
6d9a4d9120
  1. 2
      pom.xml
  2. 4
      src/main/java/de/srsoftware/web4rail/BaseClass.java
  3. 4
      src/main/java/de/srsoftware/web4rail/PathFinder.java
  4. 1
      src/main/java/de/srsoftware/web4rail/Plan.java
  5. 34
      src/main/java/de/srsoftware/web4rail/Route.java
  6. 1
      src/main/java/de/srsoftware/web4rail/actions/ActionList.java
  7. 5
      src/main/java/de/srsoftware/web4rail/actions/PreserveRoute.java
  8. 1
      src/main/java/de/srsoftware/web4rail/moving/Car.java
  9. 46
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  10. 19
      src/main/java/de/srsoftware/web4rail/tiles/Bridge.java
  11. 1
      src/main/java/de/srsoftware/web4rail/tiles/Signal.java
  12. 87
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

2
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId> <groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId> <artifactId>web4rail</artifactId>
<version>1.2.50</version> <version>1.2.51</version>
<name>Web4Rail</name> <name>Web4Rail</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>Java Model Railway Control</description> <description>Java Model Railway Control</description>

4
src/main/java/de/srsoftware/web4rail/BaseClass.java

@ -77,6 +77,7 @@ public abstract class BaseClass implements Constants{
} }
public Context block(Block newBlock) { public Context block(Block newBlock) {
LOG.debug("{}.block({})",this,newBlock);
block = newBlock; block = newBlock;
return this; return this;
} }
@ -130,6 +131,7 @@ public abstract class BaseClass implements Constants{
} }
public Context direction(Direction newDirection) { public Context direction(Direction newDirection) {
LOG.debug("{}.direction({})",this,newDirection);
direction = newDirection; direction = newDirection;
return this; return this;
} }
@ -140,6 +142,7 @@ public abstract class BaseClass implements Constants{
public Context setMain(BaseClass object) { public Context setMain(BaseClass object) {
main = object; main = object;
LOG.debug("{}.setMain({})",this,object);
if (main instanceof Tile) this.tile = (Tile) main; if (main instanceof Tile) this.tile = (Tile) main;
if (main instanceof Contact) this.contact = (Contact) main; if (main instanceof Contact) this.contact = (Contact) main;
if (main instanceof Block) this.block = (Block) main; if (main instanceof Block) this.block = (Block) main;
@ -183,6 +186,7 @@ public abstract class BaseClass implements Constants{
} }
public Context train(Train newTrain) { public Context train(Train newTrain) {
LOG.debug("{}.train({})",this,newTrain);
train = newTrain; train = newTrain;
return this; return this;
} }

4
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 final Logger LOG = LoggerFactory.getLogger(PathFinder.class);
private static TreeMap<Integer,List<Route>> availableRoutes(Context context,HashSet<Route> visitedRoutes){ private static TreeMap<Integer,List<Route>> availableRoutes(Context context,HashSet<Route> visitedRoutes){
LOG.debug("PathFinder.availableRoutes({})",context);
TreeMap<Integer,List<Route>> availableRoutes = new TreeMap<Integer, List<Route>>(); TreeMap<Integer,List<Route>> availableRoutes = new TreeMap<Integer, List<Route>>();
String inset = ""; String inset = "";
@ -53,7 +54,7 @@ public class PathFinder extends BaseClass{
continue; continue;
} }
if (!routeCandidate.allowed(context)) continue; // Zug darf auf Grund einer nicht erfüllten Bedingung nicht auf die Route 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; int priority = 0;
if (isSet(direction) && routeCandidate.startDirection != direction) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges if (isSet(direction) && routeCandidate.startDirection != direction) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges
if (!train.pushPull) continue; // Zug kann nicht wenden if (!train.pushPull) continue; // Zug kann nicht wenden
@ -99,6 +100,7 @@ public class PathFinder extends BaseClass{
} }
public static Route chooseRoute(Context context) { public static Route chooseRoute(Context context) {
LOG.debug("PathFinder.chooseRoute({})",context);
TreeMap<Integer, List<Route>> availableRoutes = PathFinder.availableRoutes(context,new HashSet<Route>()); TreeMap<Integer, List<Route>> availableRoutes = PathFinder.availableRoutes(context,new HashSet<Route>());
if (availableRoutes.isEmpty()) return null; if (availableRoutes.isEmpty()) return null;
Entry<Integer, List<Route>> entry = availableRoutes.lastEntry(); Entry<Integer, List<Route>> entry = availableRoutes.lastEntry();

1
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.Label;
import de.srsoftware.web4rail.tags.Table; import de.srsoftware.web4rail.tags.Table;
import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.BlockContact;
import de.srsoftware.web4rail.tiles.BlockH; import de.srsoftware.web4rail.tiles.BlockH;
import de.srsoftware.web4rail.tiles.BlockV; import de.srsoftware.web4rail.tiles.BlockV;
import de.srsoftware.web4rail.tiles.Bridge; import de.srsoftware.web4rail.tiles.Bridge;

34
src/main/java/de/srsoftware/web4rail/Route.java

@ -423,10 +423,10 @@ public class Route extends BaseClass {
public void finish() { public void finish() {
context.clear(); // prevent delayed actions from firing after route has finished context.clear(); // prevent delayed actions from firing after route has finished
setSignals(Signal.STOP); setSignals(Signal.STOP);
for (Tile tile : path) tile.setRoute(null); for (Tile tile : path) tile.unset(this);
Tile lastTile = path.lastElement(); Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) { if (lastTile instanceof Contact) {
lastTile.set(null); lastTile.setTrain(null);
if (isSet(train)) train.removeChild(lastTile); if (isSet(train)) train.removeChild(lastTile);
} }
if (isSet(train)) { if (isSet(train)) {
@ -445,6 +445,7 @@ public class Route extends BaseClass {
} }
public boolean fireSetupActions() { public boolean fireSetupActions() {
LOG.debug("{}.firesSetupActions({})",this);
ActionList setupActions = triggeredActions.get(ROUTE_SETUP); ActionList setupActions = triggeredActions.get(ROUTE_SETUP);
if (isSet(setupActions) && !setupActions.fire(context)) return false; if (isSet(setupActions) && !setupActions.fire(context)) return false;
state = State.PREPARED; state = State.PREPARED;
@ -475,9 +476,13 @@ public class Route extends BaseClass {
return disabled; return disabled;
} }
public boolean isFreeFor(Train newTrain) { public boolean isFreeFor(Context context) {
LOG.debug("{}.isFreeFor({})",this,context);
for (int i=1; i<path.size(); i++) { for (int i=1; i<path.size(); i++) {
if (!path.get(i).isFreeFor(newTrain)) return false; if (!path.get(i).isFreeFor(context)) {
LOG.debug("{}.isFreeFor(...) → false",this);
return false;
}
} }
return true; return true;
} }
@ -684,26 +689,25 @@ public class Route extends BaseClass {
} }
public boolean lock() { public boolean lock() {
LOG.debug("{}.lock({})",this);
return lockIgnoring(null); return lockIgnoring(null);
} }
public boolean lockIgnoring(Route ignoredRoute) { public boolean lockIgnoring(Route ignoredRoute) {
Vector<Tile> alreadyLocked = new Vector<Tile>();
HashSet<Tile> ignoredPath = new HashSet<Tile>(); HashSet<Tile> ignoredPath = new HashSet<Tile>();
if (isSet(ignoredRoute)) ignoredPath.addAll(ignoredRoute.path); if (isSet(ignoredRoute)) ignoredPath.addAll(ignoredRoute.path);
boolean success = true; boolean success = true;
for (Tile tile : path) { for (Tile tile : path) {
if (ignoredPath.contains(tile)) continue; if (ignoredPath.contains(tile)) continue;
try { try {
alreadyLocked.add(tile.setRoute(this)); tile.setRoute(this);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
LOG.debug("{}.lockIgnoring(...) failed at {}, rolling back",this,tile);
success = false; success = false;
break; break;
} }
} }
if (success) { if (success) state = State.LOCKED;
state = State.LOCKED;
} else for (Tile tile :alreadyLocked) tile.setRoute(null);
return success; return success;
} }
@ -795,11 +799,16 @@ public class Route extends BaseClass {
} }
public boolean reset() { public boolean reset() {
LOG.debug("{}.reset()",this);
setSignals(Signal.STOP); 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(); Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) { if (lastTile instanceof Contact) {
lastTile.set(null); lastTile.setTrain(null);
if (isSet(train)) train.removeChild(lastTile); if (isSet(train)) train.removeChild(lastTile);
} }
if (isSet(train)) { if (isSet(train)) {
@ -808,6 +817,7 @@ public class Route extends BaseClass {
if (train.route == this) train.route = null; if (train.route == this) train.route = null;
train = null; train = null;
} }
LOG.debug("chlearing triggeredContacts of {}",this);
triggeredContacts.clear(); triggeredContacts.clear();
state = State.FREE; state = State.FREE;
return true; return true;
@ -840,6 +850,7 @@ public class Route extends BaseClass {
} }
public boolean setSignals(String state) { public boolean setSignals(String state) {
LOG.debug("{}.setSignals({})",this,state);
for (Signal signal : signals) { for (Signal signal : signals) {
if (!signal.state(isNull(state) ? Signal.GO : state)) return false; if (!signal.state(isNull(state) ? Signal.GO : state)) return false;
} }
@ -861,6 +872,7 @@ public class Route extends BaseClass {
} }
public boolean start(Train newTrain) { public boolean start(Train newTrain) {
LOG.debug("{}.start({})",this,newTrain);
if (isNull(newTrain)) return false; // can't set route's train to null if (isNull(newTrain)) return false; // can't set route's train to null
if (isSet(train)) { if (isSet(train)) {
if (newTrain != train) return false; // can't alter route's train if (newTrain != train) return false; // can't alter route's train

1
src/main/java/de/srsoftware/web4rail/actions/ActionList.java

@ -67,6 +67,7 @@ public class ActionList extends Action implements Iterable<Action>{
} }
public boolean fire(Context context) { public boolean fire(Context context) {
LOG.debug("{}.fire({})",this,context);
if (context.invalidated()) { if (context.invalidated()) {
LOG.debug("Context has been invalidated, aborting {}",this); LOG.debug("Context has been invalidated, aborting {}",this);
return false; return false;

5
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; if (train.destination() == route.endBlock()) return true;
Range waitTime = route.endBlock().getWaitTime(train,route.endDirection); 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(); train.reserveNext();
return true; return true;

1
src/main/java/de/srsoftware/web4rail/moving/Car.java

@ -309,6 +309,7 @@ public class Car extends BaseClass implements Comparable<Car>{
} }
public Object turn() { public Object turn() {
LOG.debug("{}.turn()",this);
orientation = !orientation; orientation = !orientation;
return t("Reversed {}.",this); return t("Reversed {}.",this);
} }

46
src/main/java/de/srsoftware/web4rail/moving/Train.java

@ -100,8 +100,11 @@ public class Train extends BaseClass implements Comparable<Train> {
if (stop) return; if (stop) return;
if (isNull(route)) { // may have been set by start action in between if (isNull(route)) { // may have been set by start action in between
Object o = Train.this.start(); Object o = Train.this.start();
LOG.debug("Train.start called, route now is {}",route);
if (isSet(route)) {
if (o instanceof String) plan.stream((String)o); if (o instanceof String) plan.stream((String)o);
if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder //if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder
} else Thread.sleep(1000); // limit load on PathFinder
} }
} else Thread.sleep(250); } else Thread.sleep(250);
} }
@ -306,15 +309,15 @@ public class Train extends BaseClass implements Comparable<Train> {
public String directedName() { public String directedName() {
String result = name(); String result = name();
if (isSet(autopilot)) result="℗"+result; String mark = isSet(autopilot) ? "ⓐ" : "";
if (isNull(direction)) return result; if (isNull(direction)) return result;
switch (direction) { switch (direction) {
case NORTH: case NORTH:
case WEST: case WEST:
return '←'+result; return '←'+mark+result;
case SOUTH: case SOUTH:
case EAST: case EAST:
return result+'→'; return result+mark+'→';
} }
return result; return result;
} }
@ -335,7 +338,7 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
public void dropTrace() { public void dropTrace() {
while (!trace.isEmpty()) trace.removeFirst().set(null); while (!trace.isEmpty()) trace.removeFirst().setTrain(null);
} }
private Tag faster(int steps) { private Tag faster(int steps) {
@ -348,6 +351,7 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
public Train heading(Direction dir) { public Train heading(Direction dir) {
LOG.debug("{}.heading({})",this,dir);
direction = dir; direction = dir;
if (isSet(currentBlock)) plan.place(currentBlock); if (isSet(currentBlock)) plan.place(currentBlock);
return this; return this;
@ -411,8 +415,8 @@ public class Train extends BaseClass implements Comparable<Train> {
if (json.has(DIRECTION)) direction = Direction.valueOf(json.getString(DIRECTION)); if (json.has(DIRECTION)) direction = Direction.valueOf(json.getString(DIRECTION));
if (json.has(NAME)) name = json.getString(NAME); if (json.has(NAME)) name = json.getString(NAME);
if (json.has(TAGS)) json.getJSONArray(TAGS ).forEach(elem -> { tags.add(elem.toString()); }); 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(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).set(this); // do not move this up! during set, other fields will be referenced! 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 if (json.has(LOCOS)) { // for downward compatibility
for (Object id : json.getJSONArray(LOCOS)) add(BaseClass.get(new Id(""+id))); for (Object id : json.getJSONArray(LOCOS)) add(BaseClass.get(new Id(""+id)));
} }
@ -568,6 +572,7 @@ public class Train extends BaseClass implements Comparable<Train> {
@Override @Override
public void removeChild(BaseClass child) { public void removeChild(BaseClass child) {
LOG.debug("{}.removeChild({})",this,child);
if (child == route) route = null; if (child == route) route = null;
if (child == nextRoute) nextRoute = null; if (child == nextRoute) nextRoute = null;
if (child == currentBlock) currentBlock = null; if (child == currentBlock) currentBlock = null;
@ -578,9 +583,13 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
public void reserveNext() { public void reserveNext() {
LOG.debug("{}.reserveNext()",this);
Context context = new Context(this).route(route).block(route.endBlock()).direction(route.endDirection); Context context = new Context(this).route(route).block(route.endBlock()).direction(route.endDirection);
Route nextRoute = PathFinder.chooseRoute(context); Route nextRoute = PathFinder.chooseRoute(context);
if (isNull(nextRoute)) return; if (isNull(nextRoute)) {
LOG.debug("{}.reserveNext() found no available route!",this);
return;
}
nextRoute.set(context); nextRoute.set(context);
boolean error = !nextRoute.lockIgnoring(route); boolean error = !nextRoute.lockIgnoring(route);
error = error || !nextRoute.fireSetupActions(); error = error || !nextRoute.fireSetupActions();
@ -644,8 +653,9 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
public void set(Block newBlock) { public void set(Block newBlock) {
LOG.debug("{}.set({})",this,newBlock);
currentBlock = newBlock; currentBlock = newBlock;
if (isSet(currentBlock)) currentBlock.set(this); if (isSet(currentBlock)) currentBlock.setTrain(this);
} }
private String setDestination(HashMap<String, String> params) { private String setDestination(HashMap<String, String> params) {
@ -692,6 +702,7 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
public void setSpeed(int newSpeed) { public void setSpeed(int newSpeed) {
LOG.debug("{}.setSpeed({})",this,newSpeed);
speed = Math.min(newSpeed,maxSpeed()); speed = Math.min(newSpeed,maxSpeed());
if (speed < 0) speed = 0; if (speed < 0) speed = 0;
cars.stream().filter(c -> c instanceof Locomotive).forEach(car -> ((Locomotive)car).setSpeed(speed)); cars.stream().filter(c -> c instanceof Locomotive).forEach(car -> ((Locomotive)car).setSpeed(speed));
@ -714,9 +725,9 @@ public class Train extends BaseClass implements Comparable<Train> {
Tile tile = trace.get(i); Tile tile = trace.get(i);
if (remainingLength>0) { if (remainingLength>0) {
remainingLength-=tile.length(); remainingLength-=tile.length();
tile.set(this); tile.setTrain(this);
} else { } else {
tile.set(null); tile.setTrain(null);
trace.remove(i); trace.remove(i);
i--; // do not move to next index: remove shifted the next index towards us 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<Train> {
} }
public Object start() throws IOException { public Object start() throws IOException {
LOG.debug("{}.start()",this);
if (isNull(currentBlock)) return t("{} not in a block",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 (maxSpeed() == 0) return t("Train has maximum speed of 0 {}, cannot go!",speedUnit);
if (isSet(route)) route.reset(); // reset route previously chosen if (isSet(route)) route.reset(); // reset route previously chosen
String error = null; String error = null;
if (isSet(nextRoute)) { if (isSet(nextRoute)) {
LOG.debug("{}.nextRoute = {}",this,nextRoute);
route = nextRoute; route = nextRoute;
if (!route.lock()) return t("Was not able to lock {}",route); if (!route.lock()) return t("Was not able to lock {}",route);
nextRoute = null; nextRoute = null;
route.set(new Context(this).block(currentBlock).direction(direction)); route.set(new Context(this).block(currentBlock).direction(direction));
} else { } 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); route = PathFinder.chooseRoute(context);
if (isNull(route)) return t("No free routes from {}",currentBlock); if (isNull(route)) return t("No free routes from {}",currentBlock);
if (!route.lock()) error = t("Was not able to lock {}",route); if (!route.lock()) error = t("Was not able to lock {}",route);
@ -751,6 +764,7 @@ public class Train extends BaseClass implements Comparable<Train> {
if (isNull(error) && !route.start(this)) error = t("Was not able to assign {} to {}!",this,route); if (isNull(error) && !route.start(this)) error = t("Was not able to assign {} to {}!",this,route);
if (isSet(error)) { if (isSet(error)) {
LOG.debug("{}.start:error = {}",this,error);
route.reset(); route.reset();
route = null; route = null;
return error; return error;
@ -766,8 +780,12 @@ public class Train extends BaseClass implements Comparable<Train> {
} }
private void startSimulation() { private void startSimulation() {
LOG.debug("{}.startSimulation({})",this);
for (Contact contact : route.contacts()) { 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 { try {
Thread.sleep(1000); Thread.sleep(1000);
@ -844,7 +862,7 @@ public class Train extends BaseClass implements Comparable<Train> {
* @return * @return
*/ */
public Tag turn() { public Tag turn() {
LOG.debug("train.turn()"); LOG.debug("{}.turn()",this);
for (Car car : cars) car.turn(); for (Car car : cars) car.turn();
Collections.reverse(cars); Collections.reverse(cars);
return reverse(); return reverse();

19
src/main/java/de/srsoftware/web4rail/tiles/Bridge.java

@ -66,12 +66,6 @@ public abstract class Bridge extends Tile {
return super.load(json); return super.load(json);
} }
public Tile set(Train train) {
super.set(train);
if (isSet(counterpart) && counterpart.train != train) counterpart.set(train);
return this;
}
@Override @Override
public Tile setRoute(Route route) { public Tile setRoute(Route route) {
super.setRoute(route); super.setRoute(route);
@ -79,6 +73,12 @@ public abstract class Bridge extends Tile {
return this; return this;
} }
public Tile setTrain(Train train) {
super.setTrain(train);
if (isSet(counterpart) && counterpart.train != train) counterpart.setTrain(train);
return this;
}
@Override @Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) { protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
Fieldset fieldset = new Fieldset(t("Counterpart")); Fieldset fieldset = new Fieldset(t("Counterpart"));
@ -113,4 +113,11 @@ public abstract class Bridge extends Tile {
if (isNull(counterpart)) tag.clazz(tag.get("class")+" disconnected"); if (isNull(counterpart)) tag.clazz(tag.get("class")+" disconnected");
return tag; return tag;
} }
@Override
public Tile unset(Route oldRoute) {
super.unset(oldRoute);
if (isSet(counterpart) && isSet(counterpart.route)) counterpart.unset(oldRoute);
return this;
}
} }

1
src/main/java/de/srsoftware/web4rail/tiles/Signal.java

@ -32,6 +32,7 @@ public abstract class Signal extends Tile {
public abstract boolean isAffectedFrom(Direction dir); public abstract boolean isAffectedFrom(Direction dir);
public boolean state(String state) { public boolean state(String state) {
LOG.debug("{}.state({})",this,state);
this.state = state; this.state = state;
plan.place(this); plan.place(this);
return true; return true;

87
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -112,10 +112,46 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
plan.place(tile); plan.place(tile);
} }
public boolean isFreeFor(Train newTrain) { public boolean isFreeFor(Context context) {
if (disabled) return false; LOG.debug("{}.isFreeFor({})",this,context);
if (isSet(route) && isSet(route.train()) && route.train() != newTrain) return false; if (disabled) {
if (isSet(train) && train != newTrain) return false; LOG.debug("{} is disabled!",this);
return false;
}
if (isNull(context)) {
if (isSet(train)) {
LOG.debug("{} is occupied by {}",this,train);
return false;
}
if (isSet(route)) {
LOG.debug("{} is occupied by {}",this,route);
return false;
}
}
if (isSet(train)) {
boolean free = train == context.train(); // during train.reserveNext, we may encounter, parts, that are already reserved by the respective train, but having another route. do not compare routes in that case!
if (free) {
LOG.debug("already reserved by {} → true",train);
} else {
LOG.debug("occupied by {} → false",train);
}
return free;
}
// if we get here, the tile is not occupied by a train, but reserved by a route, yet. thus, the tile is not available for another route
if (isSet(route) && route != context.route()) {
LOG.debug("reserved by other route: {}",route);
if (isSet(route.train())) {
if (route.train() == context.train()) {
LOG.debug("that route is used by {}, which is also requesting this tile → true",route.train());
return true;
}
}
LOG.debug("{}.route.train = {} → false",this,route.train());
return false;
}
LOG.debug("free");
return true; return true;
} }
@ -179,6 +215,19 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
return this; return this;
} }
public boolean move(int dx, int dy) {
int destX = x+(dx > 0 ? width() : dx);
int destY = y+(dy > 0 ? height() : dy);
if (destX < 0 || destY < 0) return false;
Tile tileAtDestination = plan.get(id(destX, destY),true);
if (isSet(tileAtDestination) && !tileAtDestination.move(dx, dy)) return false;
plan.drop(this);
position(x+dx, y+dy);
plan.place(this);
return true;
}
protected void noTrack() { protected void noTrack() {
isTrack = false; isTrack = false;
} }
@ -310,15 +359,20 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
file.close(); file.close();
} }
public Tile set(Train newTrain) { public Tile setTrain(Train newTrain) {
LOG.debug("{}.set({})",this,newTrain);
if (newTrain == train) return this; // nothing to update if (newTrain == train) return this; // nothing to update
this.train = newTrain; this.train = newTrain;
return plan.place(this); return plan.place(this);
} }
public Tile setRoute(Route lockingRoute) { public Tile setRoute(Route lockingRoute) {
LOG.debug("{}.setRoute({})",this,lockingRoute);
if (isNull(lockingRoute)) throw new NullPointerException();
if (isSet(route)) {
if (route == lockingRoute) return this; // nothing changed if (route == lockingRoute) return this; // nothing changed
if (isSet(route) && isSet(lockingRoute)) throw new IllegalStateException(this.toString()); // tile already locked by other route throw new IllegalStateException(this.toString()); // tile already locked by other route
}
route = lockingRoute; route = lockingRoute;
return plan.place(this); return plan.place(this);
} }
@ -427,6 +481,16 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
plan.place(this); plan.place(this);
} }
public Tile unset(Route oldRoute) {
LOG.debug("{}.unset({})",this,oldRoute);
if (route == null) return this;
if (route == oldRoute) {
route = null;
return plan.place(this);
}
throw new IllegalArgumentException(t("{} not occupied by {}!",this,oldRoute));
}
public Tile update(HashMap<String, String> params) { public Tile update(HashMap<String, String> params) {
LOG.debug("{}.update({})",getClass().getSimpleName(),params); LOG.debug("{}.update({})",getClass().getSimpleName(),params);
String oneWayDir = params.get("oneway"); String oneWayDir = params.get("oneway");
@ -449,16 +513,5 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
return 1; return 1;
} }
public boolean move(int dx, int dy) {
int destX = x+(dx > 0 ? width() : dx);
int destY = y+(dy > 0 ? height() : dy);
if (destX < 0 || destY < 0) return false;
Tile tileAtDestination = plan.get(id(destX, destY),true);
if (isSet(tileAtDestination) && !tileAtDestination.move(dx, dy)) return false;
plan.drop(this);
position(x+dx, y+dy);
plan.place(this);
return true;
}
} }

Loading…
Cancel
Save