implemented small delay between setting signal to go and start of train. various GUI improvements
This commit is contained in:
2
pom.xml
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.3.2</version>
|
<version>1.3.3</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>
|
||||||
|
|||||||
@@ -261,11 +261,15 @@ h4,ul{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.window .disabled{
|
.window .disabled{
|
||||||
background: red;
|
background: orange;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window tr.disabled {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
|
||||||
svg.disabled circle,
|
svg.disabled circle,
|
||||||
svg.disabled line,
|
svg.disabled line,
|
||||||
svg.disabled polygon,
|
svg.disabled polygon,
|
||||||
@@ -309,6 +313,10 @@ table tr:hover td{
|
|||||||
background: #cadbdb;
|
background: #cadbdb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table tr.disabled:hover td {
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
table.brake-times tr > *{
|
table.brake-times tr > *{
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: black;
|
border-color: black;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
abort : abbrechen
|
abort : abbrechen
|
||||||
|
Accessory : Zubehör
|
||||||
Actions : Aktionen
|
Actions : Aktionen
|
||||||
Actions\: : Aktionen:
|
Actions\: : Aktionen:
|
||||||
Actions and contacts : Aktionen und Kontakte
|
Actions and contacts : Aktionen und Kontakte
|
||||||
@@ -26,6 +27,7 @@ Address\: : Adresse:
|
|||||||
analyze : analysieren
|
analyze : analysieren
|
||||||
Analyze : analysieren
|
Analyze : analysieren
|
||||||
Analyze may overwrite these routes! : Durch die Analyse können diese Fahrstraßen überschrieben werden!
|
Analyze may overwrite these routes! : Durch die Analyse können diese Fahrstraßen überschrieben werden!
|
||||||
|
Analyzing plan... : Plan wird analysiert...
|
||||||
and : und
|
and : und
|
||||||
AndCondition : Und-Bedingung
|
AndCondition : Und-Bedingung
|
||||||
Apply : Übernehmen
|
Apply : Übernehmen
|
||||||
@@ -83,7 +85,6 @@ Current location\: {} : Aufenthaltsort: {}
|
|||||||
Current velocity\: {} {} : Aktuelle Geschwindigkeit: {} {}
|
Current velocity\: {} {} : Aktuelle Geschwindigkeit: {} {}
|
||||||
custom fields : benutzerdefinierte Felder
|
custom fields : benutzerdefinierte Felder
|
||||||
Decoder address : Decoder-Adresse
|
Decoder address : Decoder-Adresse
|
||||||
Delay : Verzögerung
|
|
||||||
DelayedAction : verzögerte Aktion
|
DelayedAction : verzögerte Aktion
|
||||||
delete : entfernen
|
delete : entfernen
|
||||||
delete route : Route löschen
|
delete route : Route löschen
|
||||||
@@ -152,8 +153,10 @@ Lower speed limit : Minimale Geschwindigkeit
|
|||||||
Manage cars : Waggons verwalten
|
Manage cars : Waggons verwalten
|
||||||
Manage locos : Lokomotiven verwalten
|
Manage locos : Lokomotiven verwalten
|
||||||
Manage trains : Züge verwalten
|
Manage trains : Züge verwalten
|
||||||
|
Maximum delay : maximale Verzögerung
|
||||||
Maximum Speed : Höchstgeschwindigkeit
|
Maximum Speed : Höchstgeschwindigkeit
|
||||||
Maximum train length : maximale Zug-Länge
|
Maximum train length : maximale Zug-Länge
|
||||||
|
Minimum delay : minimale Verzögerung
|
||||||
Minimum and maximum times (in Miliseconds) trains with the respective tag have to wait in this block. : Minamle und maximale Block-Haltezeit (in Millisekunden) für Züge mit der entsprchender Markierung.
|
Minimum and maximum times (in Miliseconds) trains with the respective tag have to wait in this block. : Minamle und maximale Block-Haltezeit (in Millisekunden) für Züge mit der entsprchender Markierung.
|
||||||
Move tiles : Kacheln verschieben
|
Move tiles : Kacheln verschieben
|
||||||
name\: : Name:
|
name\: : Name:
|
||||||
@@ -194,9 +197,9 @@ quit autopilot : Autopilot beenden
|
|||||||
{} reached it`s destination! : {} ist am Ziel angekommen!
|
{} reached it`s destination! : {} ist am Ziel angekommen!
|
||||||
ReactivateContact : Kontakt reaktivieren
|
ReactivateContact : Kontakt reaktivieren
|
||||||
Relay : Relais
|
Relay : Relais
|
||||||
Relays and Turnouts : Relais und Weichen
|
Relay/Signal/Turnout : Relais/Signal/Weiche
|
||||||
Relay/Turnout : Relais/Weiche
|
|
||||||
Remove tag "{}" from train : Markierung "{}" von Zug entfernen
|
Remove tag "{}" from train : Markierung "{}" von Zug entfernen
|
||||||
|
Removed {} : {} gelöscht
|
||||||
Report Issue : Problem melden
|
Report Issue : Problem melden
|
||||||
reverse : wenden
|
reverse : wenden
|
||||||
Reversed {}. : {} umgedreht.
|
Reversed {}. : {} umgedreht.
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package de.srsoftware.web4rail;
|
package de.srsoftware.web4rail;
|
||||||
|
|
||||||
|
import de.srsoftware.tools.Tag;
|
||||||
|
|
||||||
public interface Device {
|
public interface Device {
|
||||||
public static final String ADDRESS = "address";
|
public static final String ADDRESS = "address";
|
||||||
public static final String PORT = "port";
|
public static final String PORT = "port";
|
||||||
public static final String PROTOCOL = "proto";
|
public static final String PROTOCOL = "proto";
|
||||||
|
|
||||||
public int address();
|
public int address();
|
||||||
|
|
||||||
|
public Tag link(String...args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -650,7 +650,7 @@ public class Plan extends BaseClass{
|
|||||||
return actions.addTo(actionMenu);
|
return actions.addTo(actionMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Window properties(HashMap<String, String> params) {
|
public Window properties(HashMap<String, String> params) {
|
||||||
if (params.containsKey(ID)) {
|
if (params.containsKey(ID)) {
|
||||||
Tile tile = get(Id.from(params), true);
|
Tile tile = get(Id.from(params), true);
|
||||||
if (isSet(tile)) return tile.properties();
|
if (isSet(tile)) return tile.properties();
|
||||||
@@ -689,18 +689,41 @@ public class Plan extends BaseClass{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Fieldset relayProperties() {
|
private Fieldset relayProperties() {
|
||||||
Fieldset fieldset = new Fieldset(t("Relays and Turnouts"));
|
Fieldset fieldset = new Fieldset(t("Accessory"));
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.addHead(t("Address"),t("Relay/Turnout"));
|
table.addHead(t("Address"),t("Relay/Signal/Turnout"));
|
||||||
|
|
||||||
List<Device> devices = BaseClass.listElements(Tile.class)
|
List<Device> devices = BaseClass.listElements(Tile.class)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(tile -> tile instanceof Device )
|
.filter(tile -> tile instanceof Device )
|
||||||
.map(tile -> (Device) tile)
|
.map(tile -> (Device) tile)
|
||||||
.sorted(Comparator.comparing(Device::address))
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
for (Signal signal : BaseClass.listElements(Signal.class)) {
|
||||||
|
for (int addr : signal.addresses()) {
|
||||||
|
devices.add(new Device() {
|
||||||
|
@Override
|
||||||
|
public int address() {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tag link(String... args) {
|
||||||
|
return signal.link(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return signal.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(devices, (d1,d2) -> d1.address() - d2.address());
|
||||||
|
|
||||||
for (Device device : devices) {
|
for (Device device : devices) {
|
||||||
Tile tile = (Tile) device;
|
table.addRow(device.address(),device.link(device.toString()));
|
||||||
table.addRow(device.address(),tile.link(tile.toString()));
|
|
||||||
if (device.address() % 4 == 1) table.children().lastElement().clazz("group");
|
if (device.address() % 4 == 1) table.children().lastElement().clazz("group");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -719,8 +742,17 @@ public class Plan extends BaseClass{
|
|||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.addHead(t("Name"),t("Start"),t("End"),t("Actions"));
|
table.addHead(t("Name"),t("Start"),t("End"),t("Actions"));
|
||||||
List<Route> routes = BaseClass.listElements(Route.class);
|
List<Route> routes = BaseClass.listElements(Route.class);
|
||||||
|
Collections.sort(routes, (r1,r2) -> r1.name().compareTo(r2.name()));
|
||||||
for (Route route : routes) {
|
for (Route route : routes) {
|
||||||
table.addRow(route.link("span",route.name()),route.link("span", route.startBlock()),route.link("span", route.endBlock()),plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())));
|
Tag actions = new Tag("div");
|
||||||
|
plan.button(t("simplify name"), Map.of(ACTION,ACTION_AUTO,ROUTE,route.id().toString())).addTo(actions);
|
||||||
|
route.button(t("delete"), Map.of(ACTION,ACTION_DROP)).addTo(actions);
|
||||||
|
Tag row = table.addRow(
|
||||||
|
route.link("span",route.name()),
|
||||||
|
route.link("span", route.startBlock()),
|
||||||
|
route.link("span", route.endBlock()),
|
||||||
|
actions);
|
||||||
|
if (route.isDisabled()) row.clazz("disabled");
|
||||||
}
|
}
|
||||||
table.clazz("turnouts").addTo(fieldset);
|
table.clazz("turnouts").addTo(fieldset);
|
||||||
return fieldset;
|
return fieldset;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import de.srsoftware.web4rail.Plan.Direction;
|
|||||||
import de.srsoftware.web4rail.actions.Action;
|
import de.srsoftware.web4rail.actions.Action;
|
||||||
import de.srsoftware.web4rail.actions.ActionList;
|
import de.srsoftware.web4rail.actions.ActionList;
|
||||||
import de.srsoftware.web4rail.actions.BrakeStart;
|
import de.srsoftware.web4rail.actions.BrakeStart;
|
||||||
import de.srsoftware.web4rail.actions.BrakeStop;
|
import de.srsoftware.web4rail.actions.DelayedAction;
|
||||||
import de.srsoftware.web4rail.actions.FinishRoute;
|
import de.srsoftware.web4rail.actions.FinishRoute;
|
||||||
import de.srsoftware.web4rail.actions.PreserveRoute;
|
import de.srsoftware.web4rail.actions.PreserveRoute;
|
||||||
import de.srsoftware.web4rail.actions.SetSignal;
|
import de.srsoftware.web4rail.actions.SetSignal;
|
||||||
@@ -177,7 +177,8 @@ public class Route extends BaseClass {
|
|||||||
switch (params.get(ACTION)) {
|
switch (params.get(ACTION)) {
|
||||||
case ACTION_DROP:
|
case ACTION_DROP:
|
||||||
route.remove();
|
route.remove();
|
||||||
return t("Removed {}.",route);
|
plan.stream(t("Removed {}.",route));
|
||||||
|
return plan.properties(new HashMap<String,String>());
|
||||||
case ACTION_PROPS:
|
case ACTION_PROPS:
|
||||||
return route.properties();
|
return route.properties();
|
||||||
case ACTION_UPDATE:
|
case ACTION_UPDATE:
|
||||||
@@ -319,11 +320,6 @@ public class Route extends BaseClass {
|
|||||||
brakeProcessor = new BrakeProcessor(this,train);
|
brakeProcessor = new BrakeProcessor(this,train);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void brakeStop() {
|
|
||||||
train.setSpeed(0);
|
|
||||||
if (isSet(brakeProcessor)) brakeProcessor.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Route clone() {
|
protected Route clone() {
|
||||||
Route clone = new Route();
|
Route clone = new Route();
|
||||||
clone.startBlock = startBlock;
|
clone.startBlock = startBlock;
|
||||||
@@ -349,18 +345,19 @@ public class Route extends BaseClass {
|
|||||||
trigger = secondContact.trigger();
|
trigger = secondContact.trigger();
|
||||||
for (Signal signal : signals) add(trigger,new SetSignal(this).set(signal).to(Signal.RED));
|
for (Signal signal : signals) add(trigger,new SetSignal(this).set(signal).to(Signal.RED));
|
||||||
}
|
}
|
||||||
if (!contacts.isEmpty()) {
|
if (!contacts.isEmpty()) add(contacts.lastElement().trigger(), new FinishRoute(this));
|
||||||
Contact lastContact = contacts.lastElement();
|
|
||||||
add(lastContact.trigger(), new BrakeStop(this));
|
|
||||||
add(lastContact.trigger(), new FinishRoute(this));
|
|
||||||
}
|
|
||||||
for (Entry<Turnout, Turnout.State> entry : turnouts.entrySet()) {
|
for (Entry<Turnout, Turnout.State> entry : turnouts.entrySet()) {
|
||||||
Turnout turnout = entry.getKey();
|
Turnout turnout = entry.getKey();
|
||||||
Turnout.State state = entry.getValue();
|
Turnout.State state = entry.getValue();
|
||||||
add(ROUTE_SETUP,new SetTurnout(this).setTurnout(turnout).setState(state));
|
add(ROUTE_SETUP,new SetTurnout(this).setTurnout(turnout).setState(state));
|
||||||
}
|
}
|
||||||
for (Signal signal : signals) add(ROUTE_START,new SetSignal(this).set(signal).to(Signal.GREEN));
|
for (Signal signal : signals) add(ROUTE_SETUP,new SetSignal(this).set(signal).to(Signal.GREEN));
|
||||||
add(ROUTE_START,new SetSpeed(this).to(999));
|
if (signals.isEmpty()) {
|
||||||
|
add(ROUTE_START,new SetSpeed(this).to(999));
|
||||||
|
} else {
|
||||||
|
DelayedAction da = new DelayedAction(this).setMinDelay(1000).setMaxDelay(7500);
|
||||||
|
add(ROUTE_START,da.add(new SetSpeed(this).to(999)));
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,11 +424,21 @@ public class Route extends BaseClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void finish() {
|
public void finish() {
|
||||||
|
if (isSet(train)) {
|
||||||
|
if (train.nextRoutePrepared()) {
|
||||||
|
if (isSet(brakeProcessor)) brakeProcessor.abort();
|
||||||
|
} else {
|
||||||
|
train.setSpeed(0);
|
||||||
|
if (isSet(brakeProcessor)) brakeProcessor.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.RED);
|
setSignals(Signal.RED);
|
||||||
for (Tile tile : path) try {
|
for (Tile tile : path) try { // remove route from tiles on path
|
||||||
tile.unset(this);
|
tile.unset(this);
|
||||||
} catch (IllegalArgumentException e) {}
|
} catch (IllegalArgumentException e) {}
|
||||||
|
|
||||||
Tile lastTile = path.lastElement();
|
Tile lastTile = path.lastElement();
|
||||||
if (lastTile instanceof Contact) {
|
if (lastTile instanceof Contact) {
|
||||||
lastTile.setTrain(null);
|
lastTile.setTrain(null);
|
||||||
@@ -447,7 +454,7 @@ public class Route extends BaseClass {
|
|||||||
train.setWaitTime(endBlock.getWaitTime(train,train.direction()));
|
train.setWaitTime(endBlock.getWaitTime(train,train.direction()));
|
||||||
}
|
}
|
||||||
if (train.route == this) train.route = null;
|
if (train.route == this) train.route = null;
|
||||||
if (!train.onTrace(startBlock) && startBlock.train() == train) startBlock.setTrain(null);
|
if (startBlock.train() == train && !train.onTrace(startBlock)) startBlock.setTrain(null); // withdraw train from start block only if trace does not go back there
|
||||||
}
|
}
|
||||||
train = null;
|
train = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ public abstract class Action extends BaseClass {
|
|||||||
AddRemoveTag.class,
|
AddRemoveTag.class,
|
||||||
BrakeCancel.class,
|
BrakeCancel.class,
|
||||||
BrakeStart.class,
|
BrakeStart.class,
|
||||||
BrakeStop.class,
|
|
||||||
ConditionalAction.class,
|
ConditionalAction.class,
|
||||||
DelayedAction.class,
|
DelayedAction.class,
|
||||||
DetermineTrainInBlock.class,
|
DetermineTrainInBlock.class,
|
||||||
|
|||||||
@@ -61,6 +61,20 @@ public class ActionList extends Action implements Iterable<Action>{
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
while (!actions.isEmpty()) actions.firstElement().remove();
|
while (!actions.isEmpty()) actions.firstElement().remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean correspondsTo(Action other) {
|
||||||
|
if (other instanceof ActionList) {
|
||||||
|
ActionList otherAL = (ActionList) other;
|
||||||
|
if (actions.size() != otherAL.actions.size()) return false;
|
||||||
|
for (int i=0; i<actions.size(); i++) {
|
||||||
|
if (!actions.get(i).correspondsTo(otherAL.actions.get(i))) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean drop(Action action) {
|
public boolean drop(Action action) {
|
||||||
return actions.remove(action);
|
return actions.remove(action);
|
||||||
@@ -125,7 +139,7 @@ public class ActionList extends Action implements Iterable<Action>{
|
|||||||
if (o instanceof JSONObject) {
|
if (o instanceof JSONObject) {
|
||||||
JSONObject jsonObject = (JSONObject) o;
|
JSONObject jsonObject = (JSONObject) o;
|
||||||
Action action = Action.create(jsonObject.getString(TYPE),this);
|
Action action = Action.create(jsonObject.getString(TYPE),this);
|
||||||
if (action != null) add(action.load(jsonObject));
|
if (isSet(action)) add(action.load(jsonObject));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package de.srsoftware.web4rail.actions;
|
|
||||||
|
|
||||||
import de.srsoftware.web4rail.BaseClass;
|
|
||||||
|
|
||||||
public class BrakeStop extends Action {
|
|
||||||
|
|
||||||
public BrakeStop(BaseClass parent) {
|
|
||||||
super(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fire(Context context) {
|
|
||||||
if (isNull(context.route()) || isNull(context.route().train())) return false;
|
|
||||||
context.route().brakeStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,15 +15,18 @@ import de.srsoftware.web4rail.tags.Input;
|
|||||||
public class DelayedAction extends ActionList {
|
public class DelayedAction extends ActionList {
|
||||||
|
|
||||||
public static final String DELAY = "delay";
|
public static final String DELAY = "delay";
|
||||||
|
public static final String MIN_DELAY = "min_delay";
|
||||||
|
public static final String MAX_DELAY = "max_delay";
|
||||||
private static final int DEFAULT_DELAY = 1000;
|
private static final int DEFAULT_DELAY = 1000;
|
||||||
private int delay = DEFAULT_DELAY;
|
private int min_delay = DEFAULT_DELAY;
|
||||||
|
private int max_delay = DEFAULT_DELAY;
|
||||||
|
|
||||||
public DelayedAction(BaseClass parent) {
|
public DelayedAction(BaseClass parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(DelayedAction other) {
|
public boolean equals(DelayedAction other) {
|
||||||
return (delay+":"+actions).equals(other.delay+":"+other.actions);
|
return (min_delay+":"+max_delay+":"+actions).equals(other.min_delay+":"+other.max_delay+":"+other.actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,8 +34,8 @@ public class DelayedAction extends ActionList {
|
|||||||
Application.threadPool.execute(new Thread() {
|
Application.threadPool.execute(new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(delay);
|
Thread.sleep(min_delay + (min_delay < max_delay ? random.nextInt(max_delay - min_delay) : 0));
|
||||||
LOG.debug("{} ms passed by, firing actions:",delay);
|
LOG.debug("{} ms passed by, firing actions:",min_delay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LOG.warn("Interrupted Exception thrown while waiting:",e);
|
LOG.warn("Interrupted Exception thrown while waiting:",e);
|
||||||
}
|
}
|
||||||
@@ -44,38 +47,69 @@ public class DelayedAction extends ActionList {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject json() {
|
public JSONObject json() {
|
||||||
return super.json().put(DELAY, delay);
|
return super.json().put(MIN_DELAY, min_delay).put(MAX_DELAY, max_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelayedAction load(JSONObject json) {
|
public DelayedAction load(JSONObject json) {
|
||||||
super.load(json);
|
super.load(json);
|
||||||
delay = json.getInt(DELAY);
|
if (json.has(DELAY)) {
|
||||||
|
min_delay = json.getInt(DELAY);
|
||||||
|
max_delay = json.getInt(DELAY);
|
||||||
|
}
|
||||||
|
if (json.has(MIN_DELAY)) min_delay = json.getInt(MIN_DELAY);
|
||||||
|
if (json.has(MAX_DELAY)) max_delay = json.getInt(MAX_DELAY);
|
||||||
return this;
|
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) {
|
||||||
formInputs.add(t("Delay"),new Input(DELAY,delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
formInputs.add(t("Minimum delay"),new Input(MIN_DELAY,min_delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
||||||
|
formInputs.add(t("Maximum delay"),new Input(MAX_DELAY,max_delay).numeric().addTo(new Tag("span")).content(NBSP+"ms"));
|
||||||
return super.properties(preForm, formInputs, postForm);
|
return super.properties(preForm, formInputs, postForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DelayedAction setMaxDelay(int max_delay) {
|
||||||
|
this.max_delay = max_delay;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelayedAction setMinDelay(int min_delay) {
|
||||||
|
this.min_delay = min_delay;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return t("Wait {} ms, then:",delay);
|
return t("Wait {} ms, then:",min_delay < max_delay ? min_delay+"…"+max_delay : min_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object update(HashMap<String, String> params) {
|
protected Object update(HashMap<String, String> params) {
|
||||||
String d = params.get(DELAY);
|
String d = params.get(MIN_DELAY);
|
||||||
if (d != null) try {
|
if (isSet(d)) try {
|
||||||
int ms = Integer.parseInt(d);
|
int ms = Integer.parseInt(d);
|
||||||
if (ms < 0) throw new NumberFormatException(t("Delay must not be less than zero!"));
|
if (ms < 0) throw new NumberFormatException(t("Delay must not be less than zero!"));
|
||||||
delay = ms;
|
min_delay = ms;
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
Window props = properties();
|
Window props = properties();
|
||||||
props.children().insertElementAt(new Tag("div").content(nfe.getMessage()), 2);
|
props.children().insertElementAt(new Tag("div").content(nfe.getMessage()), 2);
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
d = params.get(MAX_DELAY);
|
||||||
|
if (isSet(d)) try {
|
||||||
|
int ms = Integer.parseInt(d);
|
||||||
|
if (ms < 0) throw new NumberFormatException(t("Delay must not be less than zero!"));
|
||||||
|
max_delay = ms;
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
Window props = properties();
|
||||||
|
props.children().insertElementAt(new Tag("div").content(nfe.getMessage()), 2);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
if (min_delay > max_delay) {
|
||||||
|
int dummy = min_delay;
|
||||||
|
min_delay = max_delay;
|
||||||
|
max_delay = dummy;
|
||||||
|
}
|
||||||
return super.update(params);
|
return super.update(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,9 @@ public class PreserveRoute extends Action {
|
|||||||
if (isNull(train)) return false;
|
if (isNull(train)) return false;
|
||||||
if (isNull(route)) return false;
|
if (isNull(route)) return false;
|
||||||
|
|
||||||
|
|
||||||
// These are NOT errors:
|
// These are NOT errors:
|
||||||
if (!train.usesAutopilot()) return true;
|
if (!train.usesAutopilot()) return true; // do not reserve routes, when not in auto-mode
|
||||||
if (train.destination() == route.endBlock()) return true;
|
if (train.destination() == route.endBlock()) return true; // do not reserve routes, when destination has been reached
|
||||||
|
|
||||||
Range waitTime = route.endBlock().getWaitTime(train,route.endDirection);
|
Range waitTime = route.endBlock().getWaitTime(train,route.endDirection);
|
||||||
if (waitTime.max > 0) {
|
if (waitTime.max > 0) {
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ public class SetSignal extends Action {
|
|||||||
private Signal signal = null;
|
private Signal signal = null;
|
||||||
private String state = Signal.RED;
|
private String state = Signal.RED;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean correspondsTo(Action other) {
|
||||||
|
if (other instanceof SetSignal) {
|
||||||
|
SetSignal otherSS = (SetSignal) other;
|
||||||
|
return otherSS.signal == this.signal;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fire(Context context) {
|
public boolean fire(Context context) {
|
||||||
if (isNull(signal)) return false;
|
if (isNull(signal)) return false;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class BlockFree extends Condition {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (block == null) return t("[Click here to select block!]");
|
if (block == null) return "["+t("Click here to select block!")+"]";
|
||||||
return t(inverted ? "Block {} is occupied":"Block {} is free",block);
|
return t(inverted ? "Block {} is occupied":"Block {} is free",block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class Table extends Tag{
|
|||||||
super("table");
|
super("table");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table addRow(Object...cols) {
|
public Tag addRow(Object...cols) {
|
||||||
Tag row = new Tag("tr");
|
Tag row = new Tag("tr");
|
||||||
for (Object column : cols) {
|
for (Object column : cols) {
|
||||||
Tag col = null;
|
Tag col = null;
|
||||||
@@ -22,12 +22,13 @@ public class Table extends Tag{
|
|||||||
col.addTo(row);
|
col.addTo(row);
|
||||||
}
|
}
|
||||||
row.addTo(this);
|
row.addTo(this);
|
||||||
return this;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table addHead(Object...cols) {
|
public Table addHead(Object...cols) {
|
||||||
Object[] tags = new Tag[cols.length];
|
Object[] tags = new Tag[cols.length];
|
||||||
for (int i=0; i<cols.length; i++) tags[i]= cols[i] instanceof Tag ? ((Tag)cols[i]).addTo(new Tag("th")) : new Tag("th").content(cols[i].toString());
|
for (int i=0; i<cols.length; i++) tags[i]= cols[i] instanceof Tag ? ((Tag)cols[i]).addTo(new Tag("th")) : new Tag("th").content(cols[i].toString());
|
||||||
return addRow(tags);
|
addRow(tags);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package de.srsoftware.web4rail.tiles;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -305,7 +306,9 @@ public abstract class Block extends StretchableTile{
|
|||||||
if (isNull(exclude)) exclude = new Vector<Block>();
|
if (isNull(exclude)) exclude = new Vector<Block>();
|
||||||
Select select = new Select(Block.class.getSimpleName());
|
Select select = new Select(Block.class.getSimpleName());
|
||||||
new Tag("option").attr("value","0").content(t("unset")).addTo(select);
|
new Tag("option").attr("value","0").content(t("unset")).addTo(select);
|
||||||
for (Block block : BaseClass.listElements(Block.class)) {
|
List<Block> blocks = BaseClass.listElements(Block.class);
|
||||||
|
Collections.sort(blocks, (b1,b2) -> b1.name.compareTo(b2.name));
|
||||||
|
for (Block block : blocks) {
|
||||||
if (exclude.contains(block)) continue;
|
if (exclude.contains(block)) continue;
|
||||||
Tag opt = select.addOption(block.id(), block);
|
Tag opt = select.addOption(block.id(), block);
|
||||||
if (block == preselected) opt.attr("selected", "selected");
|
if (block == preselected) opt.attr("selected", "selected");
|
||||||
|
|||||||
@@ -44,6 +44,14 @@ public abstract class Signal extends Tile {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashSet<Integer> addresses(){
|
||||||
|
HashSet<Integer> list = new HashSet<Integer>();
|
||||||
|
for (HashSet<int[]> commands : aspects.values()) {
|
||||||
|
for (int[] data : commands) list.add(data[0]);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector<String> classes() {
|
protected Vector<String> classes() {
|
||||||
Vector<String> classes = super.classes();
|
Vector<String> classes = super.classes();
|
||||||
|
|||||||
Reference in New Issue
Block a user