Browse Source

working on route actions:

start block of route should only be freed, if corresponding action is fired.
  however, train should not be available from previous start block after route has finished.
lookup-tables
Stephan Richter 5 years ago
parent
commit
596317049c
  1. 2
      pom.xml
  2. 8
      src/main/java/de/srsoftware/web4rail/Plan.java
  3. 54
      src/main/java/de/srsoftware/web4rail/Route.java
  4. 8
      src/main/java/de/srsoftware/web4rail/actions/Action.java
  5. 7
      src/main/java/de/srsoftware/web4rail/actions/ActionList.java
  6. 5
      src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
  7. 6
      src/main/java/de/srsoftware/web4rail/actions/FreePreviousBlocks.java
  8. 4
      src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
  9. 129
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  10. 40
      src/main/java/de/srsoftware/web4rail/tiles/Block.java
  11. 6
      src/main/java/de/srsoftware/web4rail/tiles/Relay.java
  12. 8
      src/main/java/de/srsoftware/web4rail/tiles/Signal.java
  13. 15
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java
  14. 6
      src/main/java/de/srsoftware/web4rail/tiles/Turnout.java

2
pom.xml

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

8
src/main/java/de/srsoftware/web4rail/Plan.java

@ -550,8 +550,12 @@ public class Plan implements Constants{ @@ -550,8 +550,12 @@ public class Plan implements Constants{
* @return
* @throws IOException
*/
public Tile place(Tile tile) throws IOException {
stream("place "+tile.tag(null));
public Tile place(Tile tile) {
try {
stream("place "+tile.tag(null));
} catch (IOException e) {
e.printStackTrace();
}
return tile;
}

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

@ -26,7 +26,7 @@ import de.srsoftware.web4rail.actions.Action.Context; @@ -26,7 +26,7 @@ import de.srsoftware.web4rail.actions.Action.Context;
import de.srsoftware.web4rail.actions.ActionList;
import de.srsoftware.web4rail.actions.ActivateRoute;
import de.srsoftware.web4rail.actions.FinishRoute;
import de.srsoftware.web4rail.actions.FreeStartBlock;
import de.srsoftware.web4rail.actions.FreePreviousBlocks;
import de.srsoftware.web4rail.actions.SetSignalsToStop;
import de.srsoftware.web4rail.actions.SetSpeed;
import de.srsoftware.web4rail.conditions.Condition;
@ -43,7 +43,6 @@ import de.srsoftware.web4rail.tiles.Signal; @@ -43,7 +43,6 @@ import de.srsoftware.web4rail.tiles.Signal;
import de.srsoftware.web4rail.tiles.Tile;
import de.srsoftware.web4rail.tiles.Turnout;
import de.srsoftware.web4rail.tiles.Turnout.State;
/**
* A route is a vector of tiles that leads from one block to another.
*
@ -131,8 +130,12 @@ public class Route implements Constants{ @@ -131,8 +130,12 @@ public class Route implements Constants{
* @throws IOException
*/
public void activate() throws IOException {
LOG.debug("{} aktiviert.",this);
for (Tile tile : path) tile.train(train);
for (Tile tile : path) {
if (!(tile instanceof Block)) tile.train(train);
}
train.heading(endDirection.inverse());
endBlock.train(train);
startBlock.trailingTrain(train);
}
/**
@ -301,8 +304,8 @@ public class Route implements Constants{ @@ -301,8 +304,8 @@ public class Route implements Constants{
if (!contacts.isEmpty()) {
Contact lastContact = contacts.lastElement();
add(lastContact.trigger(), new SetSpeed());
add(lastContact.trigger(), new FreeStartBlock());
add(lastContact.trigger(), new FinishRoute());
add(lastContact.trigger(), new FreePreviousBlocks());
}
}
@ -331,16 +334,14 @@ public class Route implements Constants{ @@ -331,16 +334,14 @@ public class Route implements Constants{
return endBlock;
}
public void finish() throws IOException {
train.route = null;
unlock();
endBlock.train(train.heading(endDirection.inverse()));
train = null;
public void finish() {
reset();
train.block(endBlock, false);
train.heading(endDirection.inverse());
}
public void fireSetupActions(Context context) {
setupActions.fire(context);
public boolean fireSetupActions(Context context) {
return setupActions.fire(context);
}
public boolean free() {
@ -350,11 +351,6 @@ public class Route implements Constants{ @@ -350,11 +351,6 @@ public class Route implements Constants{
return true;
}
public Route freeStartBlock() throws IOException {
startBlock.train(null);
return this;
}
private String generateName() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<path.size();i++) {
@ -494,12 +490,8 @@ public class Route implements Constants{ @@ -494,12 +490,8 @@ public class Route implements Constants{
ArrayList<Tile> lockedTiles = new ArrayList<Tile>();
try {
for (Tile tile : path) lockedTiles.add(tile.lock(this));
} catch (IOException e) {
for (Tile tile: lockedTiles) try {
tile.unlock();
} catch (IOException inner) {
LOG.warn("Was not able to unlock {}!",tile,inner);
}
} catch (IllegalStateException e) {
for (Tile tile: lockedTiles) tile.unlock();
return false;
}
return true;
@ -541,6 +533,18 @@ public class Route implements Constants{ @@ -541,6 +533,18 @@ public class Route implements Constants{
return win;
}
public void reset() {
new SetSignalsToStop().fire(new Context(this));
for (Tile tile : path) {
if (!(tile instanceof Block)) tile.unlock();
}
if (endBlock.route() == this) endBlock.lock(null);
if (startBlock.route() == this) startBlock.lock(null);
train.heading(startDirection);
train.block(startBlock, false);
if (train.route == this) train.route = null;
}
public static void saveAll(Collection<Route> routes, String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
file.write("{\""+ROUTES+"\":[\n");
@ -560,7 +564,7 @@ public class Route implements Constants{ @@ -560,7 +564,7 @@ public class Route implements Constants{
if (lastTile instanceof Turnout) addTurnout((Turnout) lastTile,state);
}
public boolean setSignals(String state) throws IOException {
public boolean setSignals(String state) {
for (Signal signal : signals) {
if (!signal.state(state == null ? Signal.GO : state)) return false;
}

8
src/main/java/de/srsoftware/web4rail/actions/Action.java

@ -45,6 +45,11 @@ public abstract class Action implements Constants { @@ -45,6 +45,11 @@ public abstract class Action implements Constants {
public Context(Train train) {
this.train = train;
}
public Context(Route route) {
this.route = route;
train = route.train;
}
}
public Action() {
@ -54,6 +59,7 @@ public abstract class Action implements Constants { @@ -54,6 +59,7 @@ public abstract class Action implements Constants {
public static Action create(String type) {
try {
if (type.equals("FreeStartBlock")) type = FreePreviousBlocks.class.getSimpleName();
return (Action) Class.forName(PREFIX+"."+type).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
@ -86,7 +92,7 @@ public abstract class Action implements Constants { @@ -86,7 +92,7 @@ public abstract class Action implements Constants {
ConditionalAction.class,
SetSpeed.class,
SetSignalsToStop.class,
FreeStartBlock.class,
FreePreviousBlocks.class,
FinishRoute.class,
TurnTrain.class,
StopAuto.class,

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

@ -121,15 +121,16 @@ public class ActionList extends Vector<Action> implements Constants{ @@ -121,15 +121,16 @@ public class ActionList extends Vector<Action> implements Constants{
public boolean fire(Context context) {
LOG.debug("Firing {}",this);
boolean success = true;
for (Action action : this) {
try {
action.fire(context);
success &= action.fire(context);
} catch (IOException e) {
LOG.warn("Action did not fire properly: {}",action,e);
success = false;
}
}
return true;
return success;
}
public int id() {

5
src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java

@ -2,11 +2,14 @@ package de.srsoftware.web4rail.actions; @@ -2,11 +2,14 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException;
import de.srsoftware.web4rail.Route;
public class FinishRoute extends Action {
@Override
public boolean fire(Context context) throws IOException {
context.route.finish();
Route route = context.route;
if (route != null) route.finish();
return true;
}
}

6
src/main/java/de/srsoftware/web4rail/actions/FreeStartBlock.java → src/main/java/de/srsoftware/web4rail/actions/FreePreviousBlocks.java

@ -2,11 +2,11 @@ package de.srsoftware.web4rail.actions; @@ -2,11 +2,11 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException;
public class FreeStartBlock extends Action {
public class FreePreviousBlocks extends Action {
@Override
public boolean fire(Context context) throws IOException {
context.route.freeStartBlock();
return true;
if (context.train != null) context.train.resetPreviousBlocks();
return false;
}
}

4
src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java

@ -1,13 +1,11 @@ @@ -1,13 +1,11 @@
package de.srsoftware.web4rail.actions;
import java.io.IOException;
import de.srsoftware.web4rail.tiles.Signal;
public class SetSignalsToStop extends Action {
@Override
public boolean fire(Context context) throws IOException {
public boolean fire(Context context) {
context.route.setSignals(Signal.STOP);
return true;
}

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

@ -36,7 +36,6 @@ import de.srsoftware.web4rail.tags.Input; @@ -36,7 +36,6 @@ import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Select;
import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.Signal;
public class Train implements Comparable<Train>,Constants {
private static final Logger LOG = LoggerFactory.getLogger(Train.class);
@ -70,6 +69,7 @@ public class Train implements Comparable<Train>,Constants { @@ -70,6 +69,7 @@ public class Train implements Comparable<Train>,Constants {
private Block block = null;
private Vector<Block> previousBlocks = new Vector<Block>();
private class Autopilot extends Thread{
boolean stop = false;
@ -149,6 +149,47 @@ public class Train implements Comparable<Train>,Constants { @@ -149,6 +149,47 @@ public class Train implements Comparable<Train>,Constants {
return t("Unknown action: {}",params.get(ACTION));
}
private Route chooseRoute(Context context) { HashSet<Route> routes = block.routes();
Vector<Route> availableRoutes = new Vector<Route>();
for (Route rt : routes) {
if (rt == route) continue; // andere Route als zuvor wählen
if (rt.path().firstElement() != block) continue; // keine Route wählen, die nicht vom aktuellen Block des Zuges startet
if (direction != null && rt.startDirection != direction) { // Route ist entgegen der Startrichtung des Zuges
if (!pushPull || !block.turnAllowed) { // Zug ist kein Wendezug oder Block erlaubt kein Wenden
continue;
}
}
if (!rt.free()) { // keine belegten Routen wählen
LOG.debug("{} is not free!",rt);
continue;
}
if (!rt.allowed(context)) continue;
availableRoutes.add(rt);
}
Random rand = new Random();
if (availableRoutes.isEmpty()) return null;
return availableRoutes.get(rand.nextInt(availableRoutes.size()));
}
@Override
public int compareTo(Train o) {
return name().compareTo(o.toString());
}
public String directedName() {
String result = name();
if (direction == null) return result;
switch (direction) {
case NORTH:
case WEST:
return '←'+result;
case SOUTH:
case EAST:
return result+'→';
}
return result;
}
private Object dropCar(HashMap<String, String> params) {
String carId = params.get(CAR_ID);
if (carId != null) cars.remove(Car.get(carId));
@ -188,8 +229,16 @@ public class Train implements Comparable<Train>,Constants { @@ -188,8 +229,16 @@ public class Train implements Comparable<Train>,Constants {
return block;
}
public void block(Block block) throws IOException {
public Train block(Block block, boolean resetPreviousBlocks) {
if (this.block == block) return this; // nothing to update
if (this.block != null) {
this.block.trailingTrain(this);
previousBlocks.add(this.block);
}
this.block = block;
block.train(this);
if (resetPreviousBlocks) resetPreviousBlocks();
return this;
}
private Tag carList() {
@ -235,6 +284,7 @@ public class Train implements Comparable<Train>,Constants { @@ -235,6 +284,7 @@ public class Train implements Comparable<Train>,Constants {
public Train heading(Direction dir) {
direction = dir;
if (block != null) plan.place(block);
return this;
}
@ -353,17 +403,7 @@ public class Train implements Comparable<Train>,Constants { @@ -353,17 +403,7 @@ public class Train implements Comparable<Train>,Constants {
}
public String name() {
String result = (name != null ? name : locos.firstElement().name());
if (direction == null) return result;
switch (direction) {
case NORTH:
case WEST:
return '←'+result;
case SOUTH:
case EAST:
return result+'→';
}
return result;
return (name != null ? name : locos.firstElement().name());
}
private Train name(String newName) {
@ -439,6 +479,19 @@ public class Train implements Comparable<Train>,Constants { @@ -439,6 +479,19 @@ public class Train implements Comparable<Train>,Constants {
} else return t("autopilot not active.");
}
public void removeFromBlock(Block block) {
if (block.train() == this) block.train(null);
if (this.block == block) this.block = null;
previousBlocks.remove(block);
}
public void resetPreviousBlocks() {
for (Block block : previousBlocks) {
if (block.train() == this || block.trailingTrain() == this) block.unlock();
}
previousBlocks.clear();
}
public static void saveAll(String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
for (Entry<Integer, Train> entry:trains.entrySet()) {
@ -468,44 +521,25 @@ public class Train implements Comparable<Train>,Constants { @@ -468,44 +521,25 @@ public class Train implements Comparable<Train>,Constants {
public String start() throws IOException {
if (block == null) return t("{} not in a block",this);
if (route != null) route.unlock().setSignals(Signal.STOP);
HashSet<Route> routes = block.routes();
Vector<Route> availableRoutes = new Vector<Route>();
if (route != null) route.reset(); // reset route previously chosen
Context context = new Context(this);
for (Route rt : routes) {
if (rt == route) continue; // andere Route als zuvor wählen
if (rt.path().firstElement() != block) continue; // keine Route wählen, die nicht vom aktuellen Block des Zuges startet
if (direction != null && rt.startDirection != direction) { // Route ist entgegen der Startrichtung des Zuges
if (!pushPull || !block.turnAllowed) { // Zug ist kein Wendezug oder Block erlaubt kein Wenden
continue;
}
}
if (!rt.free()) { // keine belegten Routen wählen
LOG.debug("{} is not free!",rt);
continue;
}
if (!rt.allowed(context)) continue;
availableRoutes.add(rt);
}
Random rand = new Random();
if (availableRoutes.isEmpty()) return t("No free routes from {}",block);
route = availableRoutes.get(rand.nextInt(availableRoutes.size()));
route = chooseRoute(context);
if (route == null) return t("No free routes from {}",block);
if (!route.lock()) return t("Was not able to lock {}",route);
String error = null;
if (direction != route.startDirection) turn();
String error = null;
if (!route.setTurnouts()) error = t("Was not able to set all turnouts!");
route.fireSetupActions(context);
if (error == null && !route.fireSetupActions(context)) error = t("Was not able to fire all setup actions of route!");
if (error == null && !route.setSignals(null)) error = t("Was not able to set all signals!");
if (error == null && !route.train(this)) error = t("Was not able to assign {} to {}!",this,route);
if (error == null) {
setSpeed(128);
return t("Started {}",this);
if (error != null) {
route.reset();
return error;
}
route.unlock();
this.block.train(this); // re-set train on previous block
this.route = null;
return error;
setSpeed(128);
return t("Started {}",this);
}
private Object stopNow() {
@ -537,9 +571,7 @@ public class Train implements Comparable<Train>,Constants { @@ -537,9 +571,7 @@ public class Train implements Comparable<Train>,Constants {
direction = direction.inverse();
for (Locomotive loco : locos) loco.turn();
}
if (block != null) try {
plan.place(block.train(this));
} catch (IOException e) {}
if (block != null) plan.place(block.train(this));
return t("{} turned.",this);
}
@ -559,9 +591,4 @@ public class Train implements Comparable<Train>,Constants { @@ -559,9 +591,4 @@ public class Train implements Comparable<Train>,Constants {
return this;
}
@Override
public int compareTo(Train o) {
return name().compareTo(o.toString());
}
}

40
src/main/java/de/srsoftware/web4rail/tiles/Block.java

@ -22,6 +22,7 @@ public abstract class Block extends StretchableTile{ @@ -22,6 +22,7 @@ public abstract class Block extends StretchableTile{
private static final String ALLOW_TURN = "allowTurn";
public boolean turnAllowed = false;
private Train trailingTrain = null;
private static final String TRAIN = Train.class.getSimpleName();
@ -34,7 +35,7 @@ public abstract class Block extends StretchableTile{ @@ -34,7 +35,7 @@ public abstract class Block extends StretchableTile{
@Override
public boolean free() {
return train == null && super.free();
return super.free() && trailingTrain == null;
}
@Override
@ -53,7 +54,7 @@ public abstract class Block extends StretchableTile{ @@ -53,7 +54,7 @@ public abstract class Block extends StretchableTile{
turnAllowed = json.has(ALLOW_TURN) && json.getBoolean(ALLOW_TURN);
if (json.has(TRAIN)) {
Train tr = Train.get(json.getInt(TRAIN));
train(tr);
train(tr.block(this, false));
}
return this;
}
@ -91,9 +92,11 @@ public abstract class Block extends StretchableTile{ @@ -91,9 +92,11 @@ public abstract class Block extends StretchableTile{
@Override
public Tag tag(Map<String, Object> replacements) throws IOException {
if (replacements == null) replacements = new HashMap<String, Object>();
replacements.put("%text%",train == null ? name : train.name());
replacements.put("%text%",name);
if (trailingTrain != null) replacements.put("%text%","("+trailingTrain.name()+")");
if (train != null) replacements.put("%text%",train.directedName());
Tag tag = super.tag(replacements);
if (train != null) tag.clazz(tag.get("class")+" occupied");
if (train != null || trailingTrain != null) tag.clazz(tag.get("class")+" occupied");
return tag;
}
@ -107,11 +110,20 @@ public abstract class Block extends StretchableTile{ @@ -107,11 +110,20 @@ public abstract class Block extends StretchableTile{
return getClass().getSimpleName()+"("+name+") @ ("+x+","+y+")";
}
public Tile train(Train newTrain) throws IOException {
if (train == newTrain) return this;
if (train != null) train.block(null); // vorherigen Zug rauswerfen
if (newTrain != null) newTrain.block(this);
return super.train(newTrain);
public void trailingTrain(Train train) {
trailingTrain = train;
this.train = null;
plan.place(this);
}
public Train trailingTrain() {
return trailingTrain;
}
@Override
public void unlock() {
trailingTrain = null;
super.unlock();
}
@Override
@ -119,11 +131,11 @@ public abstract class Block extends StretchableTile{ @@ -119,11 +131,11 @@ public abstract class Block extends StretchableTile{
if (params.containsKey(NAME)) name=params.get(NAME);
if (params.containsKey(TRAIN)) {
int trainId = Integer.parseInt(params.get(TRAIN));
Train t = Train.get(trainId);
if (t != null) {
Block oldBlock = t.block();
if (oldBlock != null) oldBlock.train(null);
train(t);
if (trainId == 0) {
train(null);
} else {
Train t = Train.get(trainId);
if (t != null) train = t.block(this,true);
}
}
turnAllowed = params.containsKey(ALLOW_TURN) && params.get(ALLOW_TURN).equals("on");

6
src/main/java/de/srsoftware/web4rail/tiles/Relay.java

@ -181,10 +181,8 @@ public class Relay extends Tile implements Device{ @@ -181,10 +181,8 @@ public class Relay extends Tile implements Device{
@Override
public void onSuccess() {
super.onSuccess();
try {
Relay.this.state = newState;
plan.place(Relay.this);
} catch (IOException e) {}
Relay.this.state = newState;
plan.place(Relay.this);
}
@Override

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

@ -26,9 +26,13 @@ public abstract class Signal extends Tile{ @@ -26,9 +26,13 @@ public abstract class Signal extends Tile{
public abstract boolean isAffectedFrom(Direction dir);
public boolean state(String state) throws IOException {
public boolean state(String state) {
this.state = state;
plan.stream("place "+tag(null));
try {
plan.stream("place "+tag(null));
} catch (IOException e) {
e.printStackTrace();
}
return true;
}

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

@ -95,7 +95,10 @@ public abstract class Tile implements Constants{ @@ -95,7 +95,10 @@ public abstract class Tile implements Constants{
}
public boolean free() {
return (!disabled) && route == null;
if (disabled) return false;
if (route != null) return false;
if (train != null) return false;
return true;
}
public int height() {
@ -160,8 +163,9 @@ public abstract class Tile implements Constants{ @@ -160,8 +163,9 @@ public abstract class Tile implements Constants{
return this;
}
public Tile lock(Route lockingRoute) throws IOException {
if (route != null && route != lockingRoute) throw new IllegalStateException(this.toString());
public Tile lock(Route lockingRoute) {
if (route == lockingRoute) return this;
if (route != null && lockingRoute != null) throw new IllegalStateException(this.toString());
route = lockingRoute;
return plan.place(this);
}
@ -353,12 +357,13 @@ public abstract class Tile implements Constants{ @@ -353,12 +357,13 @@ public abstract class Tile implements Constants{
return train;
}
public Tile train(Train train) throws IOException {
public Tile train(Train train) {
if (this.train == train) return this; // nothing to update
this.train = train;
return plan.place(this);
}
public void unlock() throws IOException {
public void unlock() {
route = null;
train = null;
plan.place(this);

6
src/main/java/de/srsoftware/web4rail/tiles/Turnout.java

@ -149,10 +149,8 @@ public abstract class Turnout extends Tile implements Device{ @@ -149,10 +149,8 @@ public abstract class Turnout extends Tile implements Device{
@Override
public void onSuccess() {
super.onSuccess();
try {
Turnout.this.state = newState;
plan.place(Turnout.this);
} catch (IOException e) {}
Turnout.this.state = newState;
plan.place(Turnout.this);
}
@Override

Loading…
Cancel
Save