From 2aa40913bb58fdaca2af419b8de61f8657d9daa3 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Fri, 16 Apr 2021 03:36:09 +0200 Subject: [PATCH] bugfixes --- pom.xml | 2 +- resources/js/plan.js | 6 ++--- .../translations/Application.de.translation | 5 +++- .../de/srsoftware/web4rail/LoadCallback.java | 2 +- .../java/de/srsoftware/web4rail/Plan.java | 14 ++++++++--- .../actions/DetermineTrainInBlock.java | 9 +++++-- .../web4rail/conditions/BlockFree.java | 11 ++++---- .../de/srsoftware/web4rail/moving/Car.java | 5 +++- .../de/srsoftware/web4rail/moving/Train.java | 15 +++++++++-- .../web4rail/threads/RoutePrepper.java | 25 +++++++++++-------- .../de/srsoftware/web4rail/tiles/Block.java | 8 +++--- .../de/srsoftware/web4rail/tiles/Tile.java | 15 +++++------ 12 files changed, 76 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index 85811a2..d27c120 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 1.4.23 + 1.4.24 Web4Rail jar Java Model Railway Control diff --git a/resources/js/plan.js b/resources/js/plan.js index 75887cf..0bd30f6 100644 --- a/resources/js/plan.js +++ b/resources/js/plan.js @@ -290,7 +290,7 @@ function runAction(ev){ function stream(ev){ var data = ev.data; - //console.log("received: ",data); + console.log("received: ",data); if (data.startsWith('0) { - messageOpacity = 100; - $('#messages').html(messages.join('
')).css('opacity',messageOpacity/OPAC); + messageOpacity = 1000; + $('#messages').html(messages.slice().reverse().join('
')).css('opacity',messageOpacity/OPAC); } else $('#messages').html(''); } diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index c24938c..c58e623 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -118,7 +118,8 @@ Date/Time : Datum/Zeit Decoder address : Decoder-Adresse decouple : Abkuppeln decoupler : decoupler -Decoupler : Entkuppler +Decoupler : Entkuppler +Default maintenance intervall : Standard-Wartungsintervall DelayedAction : verzögerte Aktion Delay must not be less than zero! : Verzögerung darf nicht kleiner als null sein! delete : entfernen @@ -262,6 +263,7 @@ Origin and destination : Start und Ziel Origin\: {} to {} : Start: {} nach {} parked trains : abgestellte Züge Plan saved as "{}". : Plan als „{}“ gespeichert. +Plan updated. : Plan aktualisiert. Port for state {} : Anschluss für Status {} PreserveRoute : Anschlußroute vorwählen Programming : Programmierung @@ -339,6 +341,7 @@ simplify name : Name vereinfachen Simulating movement of {}... : Simuliere Fahrt von {}... Slower ({} {}) : {} {} langsamer SOUTH : Süden +Speed step : Geschwindigketis-Schritt Speed unit : Geschwindigkeits-Einheit Split behind : Nach SplitTrain : Zug teilen diff --git a/src/main/java/de/srsoftware/web4rail/LoadCallback.java b/src/main/java/de/srsoftware/web4rail/LoadCallback.java index 945262a..c135fb9 100644 --- a/src/main/java/de/srsoftware/web4rail/LoadCallback.java +++ b/src/main/java/de/srsoftware/web4rail/LoadCallback.java @@ -13,6 +13,6 @@ public abstract class LoadCallback { public abstract void afterLoad(); public static void fire() { - for (LoadCallback callback : callbacks) callback.afterLoad(); + while (!callbacks.isEmpty()) callbacks.removeFirst().afterLoad(); } } diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index c764933..2a085e6 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -162,6 +162,8 @@ public class Plan extends BaseClass{ private static final String DISCOVERY_MODE = "discovery_mode"; private static final String DISCOVER_NEW = "discover_new"; private static final String DISCOVER_UPDATE = "discover_update"; + private static final String MAINTENANCE_INTERVAL = "maintenance_interval"; + private String name = DEFAULT_NAME; private ControlUnit controlUnit = new ControlUnit(this); // the control unit, to which the plan is connected @@ -536,6 +538,7 @@ public class Plan extends BaseClass{ .put(FINAL_SPEED, Train.defaultEndSpeed) .put(SPEED_STEP, Train.defaultSpeedStep) .put(FREE_BEHIND_TRAIN, Route.freeBehindTrain) + .put(MAINTENANCE_INTERVAL, Car.defaulMaintenanceDist) .put(LENGTH_UNIT, lengthUnit) .put(SPEED_UNIT, speedUnit) .put(TILE, jTiles); @@ -566,6 +569,7 @@ public class Plan extends BaseClass{ if (json.has(FINAL_SPEED)) Train.defaultEndSpeed = json.getInt(FINAL_SPEED); if (json.has(SPEED_STEP)) Train.defaultSpeedStep = json.getInt(SPEED_STEP); if (json.has(FREE_BEHIND_TRAIN)) Route.freeBehindTrain = json.getBoolean(FREE_BEHIND_TRAIN); + if (json.has(MAINTENANCE_INTERVAL)) Car.defaulMaintenanceDist = json.getLong(MAINTENANCE_INTERVAL); try { Car.loadAll(name+".cars",plan); @@ -747,8 +751,9 @@ public class Plan extends BaseClass{ formInputs.add(null, new Input(ACTION,ACTION_UPDATE)); formInputs.add(t("Length unit"),new Input(LENGTH_UNIT, lengthUnit)); formInputs.add(t("Speed unit"),new Input(SPEED_UNIT, speedUnit)); - formInputs.add(t("Speed step"),new Input(SPEED_STEP, Train.defaultSpeedStep).attr("title", t("Speeds are always increadsed/decreased by this value"))); - formInputs.add(t("Lower speed limit"),new Input(FINAL_SPEED, Train.defaultEndSpeed).attr("title", t("Final speed after breaking, before halting"))); + formInputs.add(t("Speed step"),new Input(SPEED_STEP, Train.defaultSpeedStep).attr("title", t("Speeds are always increadsed/decreased by this value")).addTo(new Tag("span")).content(NBSP+Plan.speedUnit)); + formInputs.add(t("Lower speed limit"),new Input(FINAL_SPEED, Train.defaultEndSpeed).attr("title", t("Final speed after breaking, before halting")).addTo(new Tag("span")).content(NBSP+Plan.speedUnit)); + formInputs.add(t("Default maintenance intervall"),new Input(MAINTENANCE_INTERVAL, Car.defaulMaintenanceDist).numeric().addTo(new Tag("span")).content(NBSP+Plan.lengthUnit)); formInputs.add(t("Free tiles behind train"),new Checkbox(FREE_BEHIND_TRAIN, t("If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished."), Route.freeBehindTrain)); formInputs.add(t("Allow editing JSON of action lists"),new Checkbox(ALLOW_JSON_EDIT, t("Do you know, what you are doing?"), allowJsonEdit )); @@ -1064,10 +1069,13 @@ public class Plan extends BaseClass{ if (params.containsKey(SPEED_UNIT)) speedUnit = params.get(SPEED_UNIT); if (params.containsKey(SPEED_STEP)) Train.defaultSpeedStep = Integer.parseInt(params.get(SPEED_STEP)); if (params.containsKey(FINAL_SPEED)) Train.defaultEndSpeed = Integer.parseInt(params.get(FINAL_SPEED)); + if (params.containsKey(MAINTENANCE_INTERVAL)) try { + Car.defaulMaintenanceDist = Long.parseLong(params.get(MAINTENANCE_INTERVAL)); + } catch(NumberFormatException e) {}; allowJsonEdit = "on".equalsIgnoreCase(params.get(ALLOW_JSON_EDIT)); Route.freeBehindTrain = "on".equalsIgnoreCase(params.get(FREE_BEHIND_TRAIN)); - return t("Plan updated."); + return properties(t("Plan updated.")); } private Object updateTimes(HashMap params) throws IOException { diff --git a/src/main/java/de/srsoftware/web4rail/actions/DetermineTrainInBlock.java b/src/main/java/de/srsoftware/web4rail/actions/DetermineTrainInBlock.java index 74dc651..51232cf 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/DetermineTrainInBlock.java +++ b/src/main/java/de/srsoftware/web4rail/actions/DetermineTrainInBlock.java @@ -8,6 +8,7 @@ import org.json.JSONObject; import de.srsoftware.web4rail.BaseClass; import de.srsoftware.web4rail.LoadCallback; +import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.tags.Fieldset; import de.srsoftware.web4rail.tags.Window; import de.srsoftware.web4rail.tiles.Block; @@ -23,8 +24,12 @@ public class DetermineTrainInBlock extends Action { @Override public boolean fire(Context context,Object cause) { - context.block(block); - context.train(block.occupyingTrain()); + if (isNull(block)) return false; + Train train = block.occupyingTrain(); + if (isSet(train)) { + context.block(block); + context.train(block.occupyingTrain()); + } return true; } diff --git a/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java b/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java index 4784e60..ae68ac2 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/BlockFree.java @@ -64,12 +64,11 @@ public class BlockFree extends Condition { @Override protected Object update(HashMap params) { - if (!params.containsKey(BLOCK)) return t("No block id passed to BlockFree.update()!"); - Tile tile = plan.get(new Id(params.get(BLOCK)), true); - if (tile instanceof Block) { - block = (Block) tile; - } else { - return t("Clicked tile is not a {}!",t("block")); + if (params.containsKey(BLOCK)) { + Tile tile = plan.get(new Id(params.get(BLOCK)), true); + if (tile instanceof Block) { + block = (Block) tile; + } else return t("Clicked tile is not a {}!",t("block")); } return super.update(params); diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java index d216542..8dfec70 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Car.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java @@ -51,6 +51,9 @@ public class Car extends BaseClass implements Comparable{ private static final String DRIVEN_DISTANCE = "driven_distance"; private static final String MAINTENANCE = "maintenance"; + + public static long defaulMaintenanceDist = 1_000_000; + protected HashSet tags = new HashSet<>(); private HashSet tasks = new HashSet<>(); @@ -222,7 +225,7 @@ public class Car extends BaseClass implements Comparable{ new Input(ACTION,ACTION_ADD).hideIn(form); new Input(REALM_CAR,id()).hideIn(form); MaintnanceTask.selector().addTo(new Label(t("Task type")+NBSP)).addTo(form); - new Input(MaintnanceTask.INTERVAL,1_000_000).numeric().addTo(new Label(t("Interval")+NBSP)).content(NBSP+Plan.lengthUnit).addTo(form); + new Input(MaintnanceTask.INTERVAL,Car.defaulMaintenanceDist).numeric().addTo(new Label(t("Interval")+NBSP)).content(NBSP+Plan.lengthUnit).addTo(form); new Button(t("add"), form).addTo(form); return form.addTo(fieldset); } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index b41c691..517aeef 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -432,9 +432,10 @@ public class Train extends BaseClass implements Comparable { } - public void dropTrace() { - trace.forEach(tile -> tile.free(this)); + public void dropTrace(boolean dropStuck) { + while (!trace.isEmpty()) trace.stream().findFirst().get().free(this); trace.clear(); + if (dropStuck) stuckTrace = null; } private BrakeProcess endBrake() { @@ -1103,6 +1104,12 @@ public class Train extends BaseClass implements Comparable { reverse(cars); return reverse(); } + + public void unTrace(Tile tile) { + if (isSet(trace)) trace.remove(tile); + if (isSet(stuckTrace)) stuckTrace.remove(tile); + + } protected Window update(HashMap params) { LOG.debug("update({})",params); @@ -1166,8 +1173,12 @@ public class Train extends BaseClass implements Comparable { trace = newTrace; return context; } + + public boolean usesAutopilot() { return autopilot; } } + + diff --git a/src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java b/src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java index 5dd959d..d862ad2 100644 --- a/src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java +++ b/src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java @@ -68,7 +68,7 @@ public class RoutePrepper extends BaseClass implements Runnable{ Direction startDirection = c.direction(); LOG.debug("RoutePrepper.availableRoutes({},{},{}), dest = {}",startBlock,startDirection,train,destination); - TreeMap> candidates = routesFrom(c); + TreeMap> candidates = routesFrom(c); // map: score → [route] if (isNull(destination)) { LOG.debug("{} has no destination, returning {}",train,candidates); @@ -91,6 +91,7 @@ public class RoutePrepper extends BaseClass implements Runnable{ TreeMap> routesToDest = new TreeMap<>(); int level = 0; + int level2 = 0; while (!candidates.isEmpty()) { LOG.debug("Candidates for level {}:",level); @@ -148,8 +149,9 @@ public class RoutePrepper extends BaseClass implements Runnable{ } } - if (!routesToDest.isEmpty()) return routesToDest; - LOG.debug("No routes to {} found with distance {}!",destination,level); + if (!routesToDest.isEmpty()) { + if (level2++ > 5) return routesToDest; + } else LOG.debug("No routes to {} found with distance {}!",destination,level); level ++; candidates = queue; } @@ -263,14 +265,20 @@ public class RoutePrepper extends BaseClass implements Runnable{ Direction startDirection = c.direction(); - LOG.debug(" RoutePrepper.routesFrom({},{},{}), dest = {}",startBlock,startDirection,train,destination); + LOG.debug(" RoutePrepper.routesFrom({},{},{}), dest = {}:",startBlock,startDirection,train,destination); TreeMap> routes = new TreeMap<>(); for (Route route : startBlock.leavingRoutes()) { - LOG.debug(" - evaluating {}",route); - int score = 0; + + if (isSet(startDirection) && route.startDirection != startDirection) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges + if (!train.pushPull) continue; // Zug kann nicht wenden + if (!startBlock.turnAllowed) continue; // Wenden im Block nicht gestattet + score -= 5; + } + + LOG.debug(" - evaluating {}",route); if (!route.allowed(new Context(train).block(startBlock).direction(startDirection))) { LOG.debug(" - {} not allowed for {}", route, train); @@ -280,11 +288,6 @@ public class RoutePrepper extends BaseClass implements Runnable{ if (route.endBlock() == destination) score = 100_000; - if (isSet(startDirection) && route.startDirection != startDirection) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges - if (!train.pushPull) continue; // Zug kann nicht wenden - if (!startBlock.turnAllowed) continue; // Wenden im Block nicht gestattet - score -= 5; - } LinkedList routesForScore = routes.get(score); if (isNull(routesForScore)) routes.put(score, routesForScore = new LinkedList()); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index e1efd08..05caddc 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -407,7 +407,9 @@ public abstract class Block extends StretchableTile{ protected Window properties(List
preForm, FormInput formInputs, List
postForm,String...errors) { formInputs.add(t("Name"),new Input(NAME, name)); formInputs.add("",new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed)); - formInputs.add(t("Train"),Train.selector(parkedTrains.first(), null)); + Train train = occupyingTrain(); + if (isNull(train)) train = parkedTrains.first(); + formInputs.add(t("Train"),Train.selector(train, null)); postForm.add(contactForm()); postForm.add(waitTimeForm()); if (!parkedTrains.isEmpty()) postForm.add(trainList()); @@ -502,12 +504,12 @@ public abstract class Block extends StretchableTile{ Train newTrain = Train.get(trainId); if (isSet(newTrain) && newTrain != occupyingTrain()) { free(occupyingTrain()); - newTrain.dropTrace(); + newTrain.dropTrace(true); if (connections(newTrain.direction()).isEmpty()) newTrain.heading(null); newTrain.set(this); } if (newTrain.currentBlock() != this) { - newTrain.dropTrace(); + newTrain.dropTrace(true); newTrain.set(this); } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 6e96669..53ec2f0 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -100,12 +100,13 @@ public abstract class Tile extends BaseClass implements Comparable { public boolean free(Train oldTrain) { if (isNull(oldTrain)) return false; - if (isSet(reservingTrain) && reservingTrain != oldTrain) return false; - if (isSet(lockingTrain) && lockingTrain != oldTrain) return false; - if (isSet(occupyingTrain) && occupyingTrain != oldTrain) return false; - reservingTrain = lockingTrain = occupyingTrain = null; - plan.place(this); - return true; + boolean result = false; + if (reservingTrain == oldTrain && (result = true)) reservingTrain = null; + if (lockingTrain == oldTrain && (result = true)) lockingTrain = null; + if (occupyingTrain == oldTrain && (result = true)) occupyingTrain = null; + oldTrain.unTrace(this); + if (result) plan.place(this); + return result; } public int height() { @@ -140,7 +141,7 @@ public abstract class Tile extends BaseClass implements Comparable { } public boolean isFreeFor(Context newTrain) { - LOG.debug("{}.isFreeFor({})", this, newTrain); + //LOG.debug("{}.isFreeFor({})", this, newTrain); if (isDisabled()) { LOG.debug("{} is disabled!", this); return false;