implemented splitting of trains and parking in blocks
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.srsoftware</groupId>
|
||||
<artifactId>web4rail</artifactId>
|
||||
<version>1.3.20</version>
|
||||
<version>1.3.21</version>
|
||||
<name>Web4Rail</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Java Model Railway Control</description>
|
||||
|
||||
@@ -58,6 +58,7 @@ CarInTrain : Wagen im Zug
|
||||
Car manager : Waggon-Verwaltung
|
||||
CarOrientation : Wagen-Laufrichtung
|
||||
Cars : Waggons
|
||||
cars : Fahrzeugen teilen
|
||||
Click here to add conditions : Hier klicken, um Bedingungen hinzuzufügen
|
||||
Click here to select block! : Hier klicken, um Block auszuwählen!
|
||||
Click here to select car! : Hier klicken, um Fahrzeug auszuwählen!
|
||||
@@ -199,6 +200,7 @@ OrCondition : Oder-Bedingung
|
||||
other train properties : andere Zug-Eigenschaften
|
||||
Origin and destination : Start und Ziel
|
||||
Origin\: {} to {} : Start: {} nach {}
|
||||
parked trains : abgestellte Züge
|
||||
Plan saved as "{}". : Plan als „{}“ gespeichert.
|
||||
Port for state {} : Anschluss für Status {}
|
||||
PreserveRoute : Anschlußroute vorwählen
|
||||
@@ -214,6 +216,7 @@ Relay : Relais
|
||||
Relay/Signal/Turnout : Relais/Signal/Weiche
|
||||
Remove tag "{}" from train : Markierung "{}" von Zug entfernen
|
||||
Removed {} : {} gelöscht
|
||||
Removed train "{}" : Zug „{}“ gelöscht
|
||||
rename : umbenennen
|
||||
Rename plan : Plan umbenennen
|
||||
Report Issue : Problem melden
|
||||
@@ -269,6 +272,9 @@ Simulating movement of {}... : Simuliere Fahrt von {}...
|
||||
Slower (10 {}) : 10 {} langsamer
|
||||
SOUTH : Süden
|
||||
Speed unit : Geschwindigkeits-Einheit
|
||||
Split behind : Nach
|
||||
SplitTrain : Zug teilen
|
||||
Split train behind {} cars : Zug nach {} Fahrzeugen teilen
|
||||
SRCP : SRCP-Dienst
|
||||
SRCP daemon : SRCP-Dienst
|
||||
Start actions : Start-Aktionen
|
||||
|
||||
@@ -23,7 +23,6 @@ public class PathFinder extends BaseClass{
|
||||
LOG.debug(inset+"PathFinder.availableRoutes({})",context);
|
||||
TreeMap<Integer,List<Route>> availableRoutes = new TreeMap<Integer, List<Route>>();
|
||||
|
||||
|
||||
boolean error = false;
|
||||
Block block = context.block();
|
||||
if (isNull(block)) {
|
||||
|
||||
@@ -64,6 +64,7 @@ public abstract class Action extends BaseClass {
|
||||
SetSpeed.class,
|
||||
SetTurnout.class,
|
||||
ShowText.class,
|
||||
SplitTrain.class,
|
||||
StartStopAuto.class,
|
||||
StopTrain.class,
|
||||
SwitchFunction.class,
|
||||
|
||||
60
src/main/java/de/srsoftware/web4rail/actions/SplitTrain.java
Normal file
60
src/main/java/de/srsoftware/web4rail/actions/SplitTrain.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package de.srsoftware.web4rail.actions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import de.srsoftware.tools.Tag;
|
||||
import de.srsoftware.web4rail.BaseClass;
|
||||
import de.srsoftware.web4rail.Window;
|
||||
import de.srsoftware.web4rail.moving.Train;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
import de.srsoftware.web4rail.tags.Input;
|
||||
|
||||
public class SplitTrain extends Action {
|
||||
|
||||
private static final String POSITION = "position";
|
||||
private int position = 1;
|
||||
|
||||
public SplitTrain(BaseClass parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Context context) {
|
||||
Train train = context.train();
|
||||
if (isNull(train)) return false;
|
||||
return train.splitAfter(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
JSONObject json = super.json();
|
||||
json.put(POSITION, position);
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action load(JSONObject json) {
|
||||
if (json.has(POSITION)) position = json.getInt(POSITION);
|
||||
return super.load(json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return t("Split train behind {} cars",position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
|
||||
formInputs.add(t("Split behind"),new Input(POSITION, position).numeric().addTo(new Tag("span")).content(t(" cars")));
|
||||
return super.properties(preForm, formInputs, postForm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object update(HashMap<String, String> params) {
|
||||
if (params.containsKey(POSITION)) position = Integer.parseInt(params.get(POSITION));
|
||||
return super.update(params);
|
||||
}
|
||||
}
|
||||
@@ -830,6 +830,29 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
setSpeed(speed-steps);
|
||||
return properties();
|
||||
}
|
||||
|
||||
public boolean splitAfter(int position) {
|
||||
if (isNull(currentBlock)) return false; // can only split within blocks!
|
||||
Train remaining = new Train();
|
||||
int len = cars.size();
|
||||
for (int i=0; i<len; i++) {
|
||||
if (i>=position) {
|
||||
Car car = cars.remove(position);
|
||||
LOG.debug("Moving {} from {} to {}",car,this,remaining);
|
||||
remaining.add(car);
|
||||
} else {
|
||||
LOG.debug("Skipping {}",cars.get(i));
|
||||
}
|
||||
}
|
||||
if (remaining.cars.isEmpty()) return false;
|
||||
remaining.name = this.name;
|
||||
this.name = null;
|
||||
currentBlock.add(remaining);
|
||||
remaining.currentBlock = currentBlock;
|
||||
plan.place(currentBlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Object start() throws IOException {
|
||||
LOG.debug("{}.start()",this);
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -40,10 +41,12 @@ public abstract class Block extends StretchableTile{
|
||||
private static final String WAIT_TIMES = "wait_times";
|
||||
private static final String RAISE = "raise";
|
||||
public static final String ACTION_ADD_CONTACT = "add_contact";
|
||||
private static final String PARKED_TRAINS = "parked_trains";
|
||||
|
||||
public String name = "Block";
|
||||
public boolean turnAllowed = false;
|
||||
private Vector<BlockContact> internalContacts = new Vector<BlockContact>();
|
||||
private Vector<Train> parkedTrains = new Vector<Train>();
|
||||
|
||||
public Block() {
|
||||
super();
|
||||
@@ -128,6 +131,12 @@ public abstract class Block extends StretchableTile{
|
||||
|
||||
|
||||
private Vector<WaitTime> waitTimes = new Vector<WaitTime>();
|
||||
|
||||
public void add(Train parkedTrain) {
|
||||
parkedTrain.register();
|
||||
parkedTrains.add(parkedTrain);
|
||||
}
|
||||
|
||||
|
||||
public Object addContact() {
|
||||
BlockContact contact = new BlockContact(this);
|
||||
@@ -135,6 +144,13 @@ public abstract class Block extends StretchableTile{
|
||||
return t("Trigger contact to learn new contact");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HashSet<String> classes() {
|
||||
HashSet<String> classes = super.classes();
|
||||
if (!parkedTrains.isEmpty()) classes.add(OCCUPIED);
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object click() throws IOException {
|
||||
if (isSet(train) && train.currentBlock() == this) return train.properties();
|
||||
@@ -207,6 +223,14 @@ public abstract class Block extends StretchableTile{
|
||||
public int indexOf(BlockContact contact) {
|
||||
return 1+internalContacts.indexOf(contact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFreeFor(Context context) {
|
||||
if (!super.isFreeFor(context)) return false;
|
||||
if (parkedTrains.isEmpty()) return true;
|
||||
Train t = isSet(context) ? context.train() : null;
|
||||
return isSet(t) ? t.isShunting() : false; // block contains train(s), thus it is olny free for shunting train
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
@@ -224,6 +248,13 @@ public abstract class Block extends StretchableTile{
|
||||
}
|
||||
}
|
||||
if (isSet(jContacts)) json.put(CONTACT, jContacts);
|
||||
if (!parkedTrains.isEmpty()) {
|
||||
JSONArray ptids = new JSONArray();
|
||||
for (Train parked : parkedTrains) {
|
||||
if (isSet(parked)) ptids.put(parked.id().toString());
|
||||
}
|
||||
json.put(PARKED_TRAINS, ptids);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -257,19 +288,37 @@ public abstract class Block extends StretchableTile{
|
||||
new BlockContact(this).load(jContact.getJSONObject(key));
|
||||
}
|
||||
}
|
||||
if (json.has(PARKED_TRAINS)) {
|
||||
JSONArray ptids = json.getJSONArray(PARKED_TRAINS);
|
||||
for (Object id : ptids) {
|
||||
Id trainId = new Id(id.toString());
|
||||
parkedTrains.add(BaseClass.get(trainId));
|
||||
}
|
||||
}
|
||||
return super.load(json);
|
||||
}
|
||||
|
||||
private Fieldset parkedTrains() {
|
||||
Fieldset fieldset = new Fieldset(t("parked trains"));
|
||||
Tag list = new Tag("ul");
|
||||
for (Train t : parkedTrains) {
|
||||
t.link("li", t).addTo(list);
|
||||
}
|
||||
list.addTo(fieldset);
|
||||
return fieldset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
|
||||
formInputs.add(t("Name"),new Input(NAME, name));
|
||||
formInputs.add("",new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed));
|
||||
formInputs.add(t("Train"),Train.selector(train, null));
|
||||
postForm.add(contactForm());
|
||||
postForm.add(waitTimeForm());
|
||||
postForm.add(waitTimeForm());
|
||||
if (!parkedTrains.isEmpty()) postForm.add(parkedTrains());
|
||||
return super.properties(preForm, formInputs, postForm);
|
||||
}
|
||||
|
||||
|
||||
public Tile raise(String tag) {
|
||||
for (int i=1; i<waitTimes.size(); i++) {
|
||||
WaitTime wt = waitTimes.get(i);
|
||||
@@ -291,6 +340,7 @@ public abstract class Block extends StretchableTile{
|
||||
public void removeChild(BaseClass child) {
|
||||
super.removeChild(child);
|
||||
internalContacts.remove(child);
|
||||
parkedTrains.remove(child);
|
||||
}
|
||||
|
||||
public void removeContact(BlockContact blockContact) {
|
||||
@@ -319,7 +369,12 @@ public abstract class Block extends StretchableTile{
|
||||
public Tag tag(Map<String, Object> replacements) throws IOException {
|
||||
if (isNull(replacements)) replacements = new HashMap<String, Object>();
|
||||
replacements.put("%text%",name);
|
||||
if (isSet(train)) replacements.put("%text%",train.directedName());
|
||||
Vector<String> trainNames = new Vector<String>();
|
||||
if (isSet(train)) trainNames.add(train.directedName());
|
||||
for (Train t:parkedTrains) {
|
||||
if (isSet(t)) trainNames.add(t.name());
|
||||
}
|
||||
if (!trainNames.isEmpty())replacements.put("%text%",String.join(" | ", trainNames));
|
||||
Tag tag = super.tag(replacements);
|
||||
tag.clazz(tag.get("class")+" Block");
|
||||
return tag;
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.json.JSONArray;
|
||||
@@ -53,8 +52,8 @@ public abstract class Signal extends Tile {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vector<String> classes() {
|
||||
Vector<String> classes = super.classes();
|
||||
protected HashSet<String> classes() {
|
||||
HashSet<String> classes = super.classes();
|
||||
classes.add("signal");
|
||||
return classes;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -44,7 +45,7 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
|
||||
|
||||
private static final String LENGTH = "length";
|
||||
private static final String LOCKED = "locked";
|
||||
private static final String OCCUPIED = "occupied";
|
||||
protected static final String OCCUPIED = "occupied";
|
||||
private static final String ONEW_WAY = "one_way";
|
||||
private static final String POS = "pos";
|
||||
private static final String TYPE = "type";
|
||||
@@ -65,8 +66,8 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
|
||||
this.routes.add(route);
|
||||
}
|
||||
|
||||
protected Vector<String> classes(){
|
||||
Vector<String> classes = new Vector<String>();
|
||||
protected HashSet<String> classes(){
|
||||
HashSet<String> classes = new HashSet<String>();
|
||||
classes.add("tile");
|
||||
classes.add(getClass().getSimpleName());
|
||||
if (isSet(route)) classes.add(LOCKED);
|
||||
|
||||
Reference in New Issue
Block a user