diff --git a/pom.xml b/pom.xml
index 0603c2f..b374879 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.11.3
+ 0.11.4
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 e5e424b..70c11c2 100644
--- a/src/main/java/de/srsoftware/web4rail/BaseClass.java
+++ b/src/main/java/de/srsoftware/web4rail/BaseClass.java
@@ -2,12 +2,15 @@ package de.srsoftware.web4rail;
import java.util.HashMap;
import java.util.Map;
+import java.util.Random;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
-public class BaseClass implements Constants{
+public abstract class BaseClass implements Constants{
+
+ public static final Random random = new Random();
public static Tag link(String tagClass,Map params,Object caption) {
String json = new JSONObject(params).toString().replace("\"", "'");
diff --git a/src/main/java/de/srsoftware/web4rail/Range.java b/src/main/java/de/srsoftware/web4rail/Range.java
index 2d31f59..9f7539c 100644
--- a/src/main/java/de/srsoftware/web4rail/Range.java
+++ b/src/main/java/de/srsoftware/web4rail/Range.java
@@ -1,7 +1,6 @@
package de.srsoftware.web4rail;
import java.util.Map;
-import java.util.Random;
import org.json.JSONObject;
@@ -9,8 +8,7 @@ import org.json.JSONObject;
* Class for integer ranges (min…max)
* @author Stephan Richter
*/
-public class Range {
- private static final Random random = new Random();
+public class Range extends BaseClass{
private static final String MAX = "max";
private static final String MIN = "min";
diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java
index 667650f..62373b0 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/Action.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java
@@ -20,6 +20,7 @@ import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Select;
+import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.Contact;
/**
@@ -38,25 +39,48 @@ public abstract class Action extends BaseClass {
public Contact contact = null;
public Route route = null;
public Train train = null;
+ public Block block = null;
public Context(Contact c) {
contact = c;
- plan = contact.plan();
- route = contact.route();
- if (route == null) return;
- train = route.train;
+ setPlan(contact.plan());
+ setRoute(contact.route());
}
-
+
public Context(Train train) {
- this.train = train;
- if (isSet(train)) plan = train.locos().get(0).plan();
+ setTrain(train);
}
-
+
public Context(Route route) {
+ setRoute(route);
+ }
+
+ private void setRoute(Route route) {
this.route = route;
- if (isSet(route)) plan = route.path().firstElement().plan();
- train = route.train;
+ if (isSet(route)) setTrain(route.train);
+
+ }
+
+ private void setTrain(Train train) {
+ this.train = train;
+ if (isSet(train)) {
+ if (isNull(route)) route = train.route;
+ setBlock(train.currentBlock());
+ }
+
+ }
+
+ private void setBlock(Block block) {
+ this.block = block;
+ }
+
+ private void setPlan(Plan plan) {
+ this.plan = plan;
}
+
+
+
+
@Override
public String toString() {
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java
index ce37280..bee5f4b 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Train.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java
@@ -12,8 +12,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Random;
import java.util.SortedSet;
+import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
@@ -76,7 +76,7 @@ public class Train extends BaseClass implements Comparable {
private HashSet tags = new HashSet();
- private Block block,destination = null;
+ private Block currentBlock,destination = null;
LinkedList trace = new LinkedList();
private class Autopilot extends Thread{
@@ -171,28 +171,55 @@ public class Train extends BaseClass implements Comparable {
}
showTrace();
}
-
- private Route chooseRoute(Context context) {
- HashSet routes = block.routes();
- Vector availableRoutes = new Vector();
+
+ private static Route chooseRoute(Context context) {
+ TreeMap> availableRoutes = availableRoutes(context);
+ if (availableRoutes.isEmpty()) return null;
+ Entry> entry = availableRoutes.firstEntry();
+ List preferredRoutes = entry.getValue();
+ Route selectetRoute = preferredRoutes.get(random.nextInt(preferredRoutes.size()));
+ LOG.debug("Chose \"{}\" with priority {}.",selectetRoute,entry.getKey());
+
+ return selectetRoute;
+ }
+
+ private static TreeMap> availableRoutes(Context context){
+ TreeMap> availableRoutes = new TreeMap>();
+
+ boolean error = false;
+ if (isNull(context.block)) {
+ LOG.warn("{}.availableRoutes called without context.block!",Train.class.getSimpleName());
+ error = true;
+ }
+ if (isNull(context.train)) {
+ LOG.warn("{}.availableRoutes called without context.train!",Train.class.getSimpleName());
+ error = true;
+ }
+ if (error) return availableRoutes;
+
+ Collection routes = context.block.routes();
+
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 (isSet(direction) && 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.path().firstElement() != context.block) continue; // routen, die nicht vom aktuellen Block starten sind bubu
+ int priority = 0;
+ if (rt == context.route) priority-=10; // möglichst andere Route als zuvor wählen // TODO: den Routen einen "last-used" Zeitstempel hinzufügen, und diesen mit in die Priorisierung einbeziehen
+ if (isSet(context.train.direction) && rt.startDirection != context.train.direction) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges
+ if (!context.train.pushPull) continue; // Zug kann nicht wenden
+ if (!context.block.turnAllowed) continue; // Wenden im Block nicht gestattet
+ priority -= 5;
}
- if (!rt.isFreeFor(this)) { // keine belegten Routen wählen
-// LOG.debug("{} is not free!",rt);
- continue;
+ if (!rt.isFreeFor(context.train)) continue; // Route ist nicht frei
+ if (!rt.allowed(context)) continue; // Zug darf auf Grund einer nicht erfüllten Bedingung nicht auf die Route
+
+ List routeSet = availableRoutes.get(priority);
+ if (isNull(routeSet)) {
+ routeSet = new Vector();
+ availableRoutes.put(priority, routeSet);
}
- if (!rt.allowed(context)) continue;
- availableRoutes.add(rt);
+ routeSet.add(rt);
}
- Random rand = new Random();
- if (availableRoutes.isEmpty()) return null;
- return availableRoutes.get(rand.nextInt(availableRoutes.size()));
+
+ return availableRoutes;
}
@Override
@@ -303,7 +330,7 @@ public class Train extends BaseClass implements Comparable {
public Train heading(Direction dir) {
direction = dir;
- if (isSet(block)) plan.place(block);
+ if (isSet(currentBlock)) plan.place(currentBlock);
return this;
}
@@ -316,7 +343,7 @@ public class Train extends BaseClass implements Comparable {
json.put(ID, id);
json.put(PUSH_PULL, pushPull);
- if (isSet(block)) json.put(BLOCK, block.id());
+ if (isSet(currentBlock)) json.put(BLOCK, currentBlock.id());
if (isSet(name))json.put(NAME, name);
if (isSet(route)) json.put(ROUTE, route.id());
if (isSet(direction)) json.put(DIRECTION, direction);
@@ -374,7 +401,7 @@ public class Train extends BaseClass implements Comparable {
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(elem.toString(), false).set(this)); });
- if (json.has(BLOCK)) block = (Block) plan.get(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(json.getString(BLOCK), false).set(this); // do not move this up! during set, other fields will be referenced!
for (Object id : json.getJSONArray(CARS)) add(Car.get(id));
for (Object id : json.getJSONArray(LOCOS)) add((Locomotive) Car.get(id));
return this;
@@ -494,8 +521,8 @@ public class Train extends BaseClass implements Comparable {
}
dest.addTo(propList);
- if (isSet(block)) {
- link("li",Map.of(REALM,REALM_PLAN,ID,block.id(),ACTION,ACTION_CLICK),t("Current location: {}",block)).addTo(propList);
+ if (isSet(currentBlock)) {
+ link("li",Map.of(REALM,REALM_PLAN,ID,currentBlock.id(),ACTION,ACTION_CLICK),t("Current location: {}",currentBlock)).addTo(propList);
Tag actions = new Tag("li").clazz().content(t("Actions:")+NBSP);
props.put(ACTION, ACTION_START);
new Button(t("start"),props).addTo(actions);
@@ -556,8 +583,8 @@ public class Train extends BaseClass implements Comparable {
}
public void set(Block newBlock) {
- block = newBlock;
- if (isSet(block)) block.set(this);
+ currentBlock = newBlock;
+ if (isSet(currentBlock)) currentBlock.set(this);
}
private String setDestination(HashMap params) {
@@ -594,13 +621,12 @@ public class Train extends BaseClass implements Comparable {
}
public String start() throws IOException {
- if (isNull(block)) return t("{} not in a block",this);
+ if (isNull(currentBlock)) return t("{} not in a block",this);
Context context = isSet(route) ? new Context( route ) : new Context( this);
-
if (isSet(context.route)) context.route.reset(); // reset route previously chosen
route = chooseRoute(context);
- if (isNull(route)) return t("No free routes from {}",block);
+ if (isNull(route)) return t("No free routes from {}",currentBlock);
if (!route.lock()) return t("Was not able to lock {}",route);
if (direction != route.startDirection) turn();
@@ -648,7 +674,7 @@ public class Train extends BaseClass implements Comparable {
direction = direction.inverse();
for (Locomotive loco : locos) loco.turn();
reverseTrace();
- if (isSet(block)) plan.place(block);
+ if (isSet(currentBlock)) plan.place(currentBlock);
}
return t("{} turned.",this);
}
@@ -676,4 +702,8 @@ public class Train extends BaseClass implements Comparable {
public void setWaitTime(Range waitTime) {
if (autopilot != null) autopilot.waitTime = waitTime.random();
}
+
+ public Block currentBlock() {
+ return currentBlock;
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
index cdda81f..f1cc716 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
@@ -44,7 +44,7 @@ import de.srsoftware.web4rail.tags.Radio;
*/
public abstract class Tile extends BaseClass{
protected static Logger LOG = LoggerFactory.getLogger(Tile.class);
- private static int DEFAUT_LENGTH = 5;
+ private static int DEFAUT_LENGTH = 100; // 10cm
private static final String LENGTH = "length";
private static final String LOCKED = "locked";