diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index 416c133..d6b3046 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -91,6 +91,7 @@ export : exportieren Faster (10 {}) : 10 {} schneller Firing {} : starte {} FinishRoute : Route abschließen +forward : vorwärts Found {} routes. : {} Routen gefunden. FreeStartBlock : Start-Block freigeben Fullscreen : Vollbild @@ -156,6 +157,8 @@ quit autopilot : Autopilot beenden {} reached it`s destination! : {} ist am Ziel angekommen! Relay/Turnout : Relais/Weiche Report Issue : Problem melden +reverse : rückwärts +Reversed {}. : {} umgedreht. RIGHT : rechts Right port\: : Port für rechts Routes using this tile : Fahrstraßen, die diesen Abschnitt verwenden @@ -210,7 +213,6 @@ STRAIGHT : gerade Switch power off : Strom ausschalten Switch power on : Strom anschalten SYSTEM : Betriebssystem -Tag : Markierung Tags : Markierungen Text to display on clients\: : Text, welcher auf den Clients angezeigt werden soll: Text to show on display\: : Text, welcher in der Anzeige dargestellt werden soll: diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java index ae1defd..e4f1733 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Car.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java @@ -9,8 +9,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.TreeSet; +import java.util.stream.Collectors; import org.json.JSONObject; import org.slf4j.Logger; @@ -31,20 +31,24 @@ import de.srsoftware.web4rail.tags.Table; public class Car extends BaseClass implements Comparable{ protected static final Logger LOG = LoggerFactory.getLogger(Car.class); - static HashMap cars = new HashMap(); public static final String NAME = "name"; + public static boolean FORWARD = true; + public static boolean REVERSE = false; private static final String LENGTH = "length"; private static final String STOCK_ID = "stock-id"; private static final String TAGS = "tags"; private static final String MAX_SPEED = "max_speed"; + private static final String MAX_SPEED_REVERSE = "max_speed_reverse"; protected HashSet tags = new HashSet(); private String name; public int length; protected String stockId = ""; private Train train; - protected int maxSpeed = 0; + protected int maxSpeedForward = 0; + protected int maxSpeedReverse = 0; + protected boolean orientation = FORWARD; public Car(String name) { this(name,null); @@ -52,14 +56,13 @@ public class Car extends BaseClass implements Comparable{ public Car(String name, Id id) { this.name = name; - if (isNull(id)) id = new Id(); this.id = id; - cars.put(id, this); + register(); } public static Object action(HashMap params,Plan plan) throws IOException { String id = params.get(ID); - Car car = id == null ? null : Car.get(id); + Car car = id == null ? null : Car.get(new Id(id)); switch (params.get(ACTION)) { case ACTION_ADD: @@ -67,8 +70,12 @@ public class Car extends BaseClass implements Comparable{ car.clone(); } else new Car(params.get(Car.NAME)).parent(plan); return Car.manager(); + case ACTION_MOVE: + return car.moveUp(); case ACTION_PROPS: return car == null ? Car.manager() : car.properties(); + case ACTION_TURN: + return car.turn(); case ACTION_UPDATE: return car.update(params); } @@ -78,7 +85,7 @@ public class Car extends BaseClass implements Comparable{ public Car clone() { Car clone = new Car(name); - clone.maxSpeed = maxSpeed; + clone.maxSpeedForward = maxSpeedForward; clone.length = length; clone.tags = new HashSet(tags); clone.notes = notes; @@ -90,16 +97,18 @@ public class Car extends BaseClass implements Comparable{ private Button cloneButton() { return new Button(t("copy"),Map.of(REALM,REALM_CAR,ID,id(),ACTION,ACTION_ADD)); } - - public static Car get(Object id) { - return isNull(id) ? null : cars.get(new Id(""+id)); // try to get by id - } + @Override + public int compareTo(Car o) { + return (stockId+":"+name).compareTo(o.stockId+":"+o.name); + } + public JSONObject json() { JSONObject json = super.json(); json.put(NAME, name); json.put(LENGTH, length); - if (maxSpeed != 0) json.put(MAX_SPEED, maxSpeed); + if (maxSpeedForward != 0) json.put(MAX_SPEED, maxSpeedForward); + if (maxSpeedReverse != 0) json.put(MAX_SPEED_REVERSE, maxSpeedReverse); json.put(STOCK_ID, stockId); if (!tags.isEmpty()) json.put(TAGS, tags); return json; @@ -119,7 +128,6 @@ public class Car extends BaseClass implements Comparable{ } public static void loadAll(String filename, Plan plan) throws IOException { - cars.clear(); BufferedReader file = new BufferedReader(new FileReader(filename, UTF8)); String line = file.readLine(); while (line != null) { @@ -137,7 +145,11 @@ public class Car extends BaseClass implements Comparable{ public Car load(JSONObject json) { super.load(json); if (json.has(LENGTH)) length = json.getInt(LENGTH); - if (json.has(MAX_SPEED)) maxSpeed = json.getInt(MAX_SPEED); + if (json.has(MAX_SPEED)) { + maxSpeedForward = json.getInt(MAX_SPEED); + maxSpeedReverse = maxSpeedForward; + } + if (json.has(MAX_SPEED_REVERSE)) maxSpeedReverse = json.getInt(MAX_SPEED_REVERSE); if (json.has(STOCK_ID)) stockId = json.getString(STOCK_ID); if (json.has(TAGS)) json.getJSONArray(TAGS).forEach(elem -> { tags.add(elem.toString()); }); return this; @@ -149,26 +161,30 @@ public class Car extends BaseClass implements Comparable{ new Tag("p").content(t("Click on a name to edit the entry.")).addTo(win); Table table = new Table().addHead(t("Stock ID"),t("Name"),t("Max. Speed",speedUnit),t("Length"),t("Train"),t("Tags"),t("Actions")); - cars.values() - .stream() - .filter(car -> !(car instanceof Locomotive)) - .sorted((c1,c2)->{ - try { - return Integer.parseInt(c1.stockId)-Integer.parseInt(c2.stockId); - } catch (NumberFormatException nfe) { - return c1.stockId.compareTo(c2.stockId); - } - - }) - .forEach(car -> table.addRow( + List cars = BaseClass.listElements(Car.class) + .stream() + .filter(car -> !(car instanceof Locomotive)) + .sorted((c1,c2)->{ + try { + return Integer.parseInt(c1.stockId)-Integer.parseInt(c2.stockId); + } catch (NumberFormatException nfe) { + return c1.stockId.compareTo(c2.stockId); + } + + }).collect(Collectors.toList()); + for (Car car : cars) { + String maxSpeed = (car.maxSpeedForward == 0 ? "–":""+car.maxSpeedForward)+NBSP; + if (car.maxSpeedReverse != car.maxSpeedForward) maxSpeed += "("+car.maxSpeedReverse+")"+NBSP; + + table.addRow( car.stockId, car.link(), - car.maxSpeed == 0 ? "–":(car.maxSpeed+NBSP+speedUnit), + maxSpeed+speedUnit, car.length+NBSP+lengthUnit, isSet(car.train) ? car.train.link("span", car.train) : "", String.join(", ", car.tags()), - car.cloneButton() - )); + car.cloneButton()); + } table.addTo(win); Form form = new Form("add-car-form"); @@ -182,7 +198,12 @@ public class Car extends BaseClass implements Comparable{ } public int maxSpeed() { - return maxSpeed; + return orientation == FORWARD ? maxSpeedForward : maxSpeedReverse; + } + + protected Window moveUp() { + if (!isSet(train())) return properties(); + return train().moveUp(this); } String name(){ @@ -194,8 +215,11 @@ public class Car extends BaseClass implements Comparable{ formInputs.add(t("Name"),new Input(NAME,name)); formInputs.add(t("Stock ID"),new Input(STOCK_ID,stockId)); formInputs.add(t("Length"),new Input(LENGTH,length).attr("type", "number").addTo(new Tag("span")).content(NBSP+lengthUnit)); - formInputs.add(t("Tag"), new Input(TAGS,String.join(", ", tags))); - formInputs.add(t("Maximum Speed"),new Input(MAX_SPEED, maxSpeed).numeric().addTo(new Tag("span")).content(NBSP+speedUnit)); + formInputs.add(t("Tags"), new Input(TAGS,String.join(", ", tags))); + Tag div = new Tag("div"); + new Input(MAX_SPEED, maxSpeedForward).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("forward")).addTo(div); + new Input(MAX_SPEED_REVERSE, maxSpeedReverse).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("reverse")).addTo(div); + formInputs.add(t("Maximum Speed"),div); Fieldset fieldset = new Fieldset(t("Train")); if (train != null) train.link().addTo(fieldset); @@ -214,7 +238,7 @@ public class Car extends BaseClass implements Comparable{ public static void saveAll(String filename) throws IOException { BufferedWriter file = new BufferedWriter(new FileWriter(filename)); - for (Entry entry: cars.entrySet()) file.write(entry.getValue().json()+"\n"); + for (Car car : BaseClass.listElements(Car.class)) file.write(car.json()+"\n"); file.close(); } @@ -243,7 +267,8 @@ public class Car extends BaseClass implements Comparable{ super.update(params); if (params.containsKey(NAME)) name = params.get(NAME).trim(); if (params.containsKey(LENGTH)) length = Integer.parseInt(params.get(LENGTH)); - if (params.containsKey(MAX_SPEED)) maxSpeed = Integer.parseInt(params.get(MAX_SPEED)); + if (params.containsKey(MAX_SPEED)) maxSpeedForward = Integer.parseInt(params.get(MAX_SPEED)); + if (params.containsKey(MAX_SPEED_REVERSE)) maxSpeedReverse = Integer.parseInt(params.get(MAX_SPEED_REVERSE)); if (params.containsKey(STOCK_ID)) stockId = params.get(STOCK_ID); if (params.containsKey(TAGS)) { String[] parts = params.get(TAGS).replace(",", " ").split(" "); @@ -256,8 +281,8 @@ public class Car extends BaseClass implements Comparable{ return properties(); } - @Override - public int compareTo(Car o) { - return (stockId+":"+name).compareTo(o.stockId+":"+o.name); + public String turn() { + orientation = !orientation; + return t("Reversed {}.",this); } } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java index 200a743..bb199dc 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Locomotive.java @@ -9,6 +9,7 @@ import java.util.Map; import org.json.JSONObject; import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.BaseClass; import de.srsoftware.web4rail.Command; import de.srsoftware.web4rail.Constants; import de.srsoftware.web4rail.Device; @@ -28,7 +29,6 @@ public class Locomotive extends Car implements Constants,Device{ private static final String REVERSE = "reverse"; public static final String LOCOMOTIVE = "locomotive"; - boolean reverse = false; private Protocol proto = Protocol.DCC128; private int address = 3; private int speed = 0; @@ -45,13 +45,15 @@ public class Locomotive extends Car implements Constants,Device{ public static Object action(HashMap params, Plan plan) throws IOException { String id = params.get(ID); - Locomotive loco = id == null ? null : Locomotive.get(id); + Locomotive loco = id == null ? null : BaseClass.get(new Id(id)); switch (params.get(ACTION)) { case ACTION_ADD: new Locomotive(params.get(Locomotive.NAME)).parent(plan).register(); return Locomotive.manager(); case ACTION_FASTER10: return loco.faster(10); + case ACTION_MOVE: + return loco.moveUp(); case ACTION_PROPS: return loco == null ? Locomotive.manager() : loco.properties(); case ACTION_SLOWER10: @@ -75,7 +77,7 @@ public class Locomotive extends Car implements Constants,Device{ return t("Unknown action: {}",params.get(ACTION)); } - + @Override public int address() { return address; @@ -161,12 +163,6 @@ public class Locomotive extends Car implements Constants,Device{ return properties(); } - public static Locomotive get(Object id) { - Car car = Car.get(id); - if (car instanceof Locomotive) return (Locomotive) car; - return null; - } - private void init() { if (init) return; String proto = null; @@ -205,7 +201,7 @@ public class Locomotive extends Car implements Constants,Device{ public JSONObject json() { JSONObject json = super.json(); JSONObject loco = new JSONObject(); - loco.put(REVERSE, reverse); + loco.put(REVERSE, orientation); loco.put(PROTOCOL, proto); loco.put(ADDRESS, address); json.put(LOCOMOTIVE, loco); @@ -217,7 +213,7 @@ public class Locomotive extends Car implements Constants,Device{ super.load(json); if (json.has(LOCOMOTIVE)) { JSONObject loco = json.getJSONObject(LOCOMOTIVE); - if (loco.has(REVERSE)) reverse = loco.getBoolean(REVERSE); + if (loco.has(REVERSE)) orientation = loco.getBoolean(REVERSE); if (loco.has(PROTOCOL)) proto = Protocol.valueOf(loco.getString(PROTOCOL)); if (loco.has(ADDRESS)) address = loco.getInt(ADDRESS); } @@ -231,13 +227,14 @@ public class Locomotive extends Car implements Constants,Device{ new Tag("p").content(t("Click on a name to edit the entry.")).addTo(win); Table table = new Table().addHead(t("Stock ID"),t("Name"),t("Max. Speed",speedUnit),t("Protocol"),t("Address"),t("Length"),t("Tags")); - cars.values() - .stream() - .filter(car -> car instanceof Locomotive) - .map(car -> (Locomotive)car) - .sorted(Comparator.comparing(loco -> loco.address)) - .sorted(Comparator.comparing(loco -> loco.stockId)) - .forEach(loco -> table.addRow(loco.stockId,loco.link(),loco.maxSpeed == 0 ? "–":loco.maxSpeed+NBSP+speedUnit,loco.proto,loco.address,loco.length+NBSP+lengthUnit,String.join(", ", loco.tags()))); + List locos = BaseClass.listElements(Locomotive.class); + locos.sort(Comparator.comparing(loco -> loco.address)); + locos.sort(Comparator.comparing(loco -> loco.stockId)); + for (Locomotive loco : locos) { + String maxSpeed = (loco.maxSpeedForward == 0 ? "–":""+loco.maxSpeedForward)+NBSP; + if (loco.maxSpeedReverse != loco.maxSpeedForward) maxSpeed += "("+loco.maxSpeedReverse+")"+NBSP; + table.addRow(loco.stockId,loco.link(),maxSpeed+speedUnit,loco.proto,loco.address,loco.length+NBSP+lengthUnit,String.join(", ", loco.tags())); + } table.addTo(win); @@ -264,8 +261,8 @@ public class Locomotive extends Car implements Constants,Device{ } private void queue() { - int step = proto.steps * speed / (maxSpeed == 0 ? 100 : maxSpeed); - plan.queue(new Command("SET {} GL "+address+" "+(reverse?1:0)+" "+step+" "+proto.steps+" "+(f1?1:0)+" "+(f2?1:0)+" "+(f3?1:0)+" "+(f4?1:0)) { + int step = proto.steps * speed / (maxSpeedForward == 0 ? 100 : maxSpeedForward); + plan.queue(new Command("SET {} GL "+address+" "+(orientation == FORWARD ? 0 : 1)+" "+step+" "+proto.steps+" "+(f1?1:0)+" "+(f2?1:0)+" "+(f3?1:0)+" "+(f4?1:0)) { @Override public void onFailure(Reply reply) { @@ -284,7 +281,7 @@ public class Locomotive extends Car implements Constants,Device{ LOG.debug(this.detail()+".setSpeed({})",newSpeed); init(); speed = newSpeed; - if (speed > maxSpeed && maxSpeed > 0) speed = maxSpeed(); + if (speed > maxSpeedForward && maxSpeedForward > 0) speed = maxSpeed(); if (speed < 0) speed = 0; queue(); @@ -322,9 +319,9 @@ public class Locomotive extends Car implements Constants,Device{ return t("{} F{}",t(active?"Activated":"Deavtivated"),f); } - public Object turn() { - reverse = !reverse; + public String turn() { stop(); + super.turn(); return t("Stopped and reversed {}.",this); } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index bc2b0bb..cd697c1 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -7,6 +7,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -65,10 +66,8 @@ public class Train extends BaseClass implements Comparable { public boolean pushPull = false; private static final String CARS = "cars"; + private static final String LOCOS = "locomotives"; private Vector cars = new Vector(); - - private static final String LOCOS = "locomotives"; - private Vector locos = new Vector(); private static final String TAGS = "tags"; @@ -179,8 +178,9 @@ public class Train extends BaseClass implements Comparable { private Object addCar(HashMap params) { LOG.debug("addCar({})",params); - if (!params.containsKey(CAR_ID)) return t("No car id passed to Train.addCar!"); - Car car = Car.get(params.get(CAR_ID)); + String carId = params.get(CAR_ID); + if (isNull(carId)) return t("No car id passed to Train.addCar!"); + Car car = BaseClass.get(new Id(carId)); if (isNull(car)) return t("No car with id \"{}\" known!",params.get(CAR_ID)); add(car); return properties(); @@ -188,9 +188,7 @@ public class Train extends BaseClass implements Comparable { public void add(Car car) { if (isNull(car)) return; - if (car instanceof Locomotive) { - locos.add((Locomotive) car); - } else cars.add(car); + cars.add(car); car.train(this); } @@ -209,41 +207,54 @@ public class Train extends BaseClass implements Comparable { public String brakeId(boolean reversed) { TreeSet carIds = new TreeSet(); - locos.stream().map(loco -> loco.id()+":"+(reversed != loco.reverse?"r":"f")).forEach(carIds::add); - cars.stream().map(car -> ""+car.id()).forEach(carIds::add); + cars.stream().map(car -> car.id()+":"+(car.orientation == reversed ? "r":"f")).forEach(carIds::add); String brakeId = md5sum(carIds); LOG.debug("generated new brake id for {}: {}",this,brakeId); return brakeId; } private Tag carList() { - Tag locoProp = new Tag("li").content(t("Cars:")); - Tag locoList = new Tag("ul").clazz("carlist").content(""); + Tag locoProp = new Tag("li").content(t("Locomotives and cars:")); + Tag carList = new Tag("ul").clazz("carlist"); for (Car car : this.cars) { Tag li = new Tag("li"); - car.link(car.name()+(car.stockId.isEmpty() ? "" : " ("+car.stockId+")")).addTo(li).content(NBSP); - button(t("delete"),Map.of(ACTION,ACTION_DROP,CAR_ID,car.id().toString())).addTo(li); - li.addTo(locoList); - } - - Form addCarForm = new Form("append-car-form"); - addCarForm.content(t("add car:")+" "); - new Input(REALM, REALM_TRAIN).hideIn(addCarForm); - new Input(ACTION, ACTION_ADD).hideIn(addCarForm); - new Input(ID,id).hideIn(addCarForm); - Select select = new Select(CAR_ID); - for (Car car : BaseClass.listElements(Car.class)) { - if (car instanceof Locomotive) continue; - if (isSet(car.train())) continue; - select.addOption(car.id(), car+(car.stockId.isEmpty()?"":" ("+car.stockId+")")); - } - if (!select.children().isEmpty()) { - select.addTo(addCarForm); - new Button(t("add"),addCarForm).addTo(addCarForm); - addCarForm.addTo(new Tag("li")).addTo(locoList); + car.link(car.name()+(car.stockId.isEmpty() ? "" : " ("+car.stockId+")")).addTo(li).content(NBSP); + car.button(t("turn within train"),Map.of(ACTION,ACTION_TURN)).addTo(li); + car.button("↑",Map.of(ACTION,ACTION_MOVE)).addTo(li); + button(t("delete"),Map.of(ACTION,ACTION_DROP,LOCO_ID,car.id().toString())).addTo(li); + li.addTo(carList); + } + + List locos = BaseClass.listElements(Locomotive.class).stream().filter(loco -> isNull(loco.train())).collect(Collectors.toList()); + if (!locos.isEmpty()) { + Form addLocoForm = new Form("append-loco-form"); + addLocoForm.content(t("add locomotive:")+" "); + new Input(REALM, REALM_TRAIN).hideIn(addLocoForm); + new Input(ACTION, ACTION_ADD).hideIn(addLocoForm); + new Input(ID,id).hideIn(addLocoForm); + Select select = new Select(CAR_ID); + for (Car loco : locos) select.addOption(loco.id(), loco); + select.addTo(addLocoForm); + new Button(t("add"),addLocoForm).addTo(addLocoForm); + addLocoForm.addTo(new Tag("li")).addTo(carList); } - return locoList.addTo(locoProp); + + List cars = BaseClass.listElements(Car.class).stream().filter(car -> !(car instanceof Locomotive)).filter(loco -> isNull(loco.train())).collect(Collectors.toList()); + if (!cars.isEmpty()) { + Form addCarForm = new Form("append-car-form"); + addCarForm.content(t("add car:")+" "); + new Input(REALM, REALM_TRAIN).hideIn(addCarForm); + new Input(ACTION, ACTION_ADD).hideIn(addCarForm); + new Input(ID,id).hideIn(addCarForm); + Select select = new Select(CAR_ID); + for (Car car : cars) select.addOption(car.id(), car+(car.stockId.isEmpty()?"":" ("+car.stockId+")")); + select.addTo(addCarForm); + new Button(t("add"),addCarForm).addTo(addCarForm); + addCarForm.addTo(new Tag("li")).addTo(carList); + } + return carList.addTo(locoProp); + } public List cars(){ @@ -256,7 +267,9 @@ public class Train extends BaseClass implements Comparable { } private static Object create(HashMap params, Plan plan) { - Locomotive loco = (Locomotive) Locomotive.get(params.get(Train.LOCO_ID)); + String locoId = params.get(Train.LOCO_ID); + if (isNull(locoId)) return t("Need loco id to create new train!"); + Locomotive loco = BaseClass.get(new Id(locoId)); if (isNull(loco)) return t("unknown locomotive: {}",params.get(ID)); Train train = new Train(loco); train.parent(plan); @@ -297,16 +310,13 @@ public class Train extends BaseClass implements Comparable { } private Object dropCar(HashMap params) { - Car car = Car.get(params.get(CAR_ID)); + String carId = params.get(CAR_ID); + if (isNull(carId)) return t("Cannot drop car without car id!"); + Car car = BaseClass.get(new Id(carId)); if (isSet(car)) { cars.remove(car); car.train(null); } - Locomotive loco = Locomotive.get(params.get(LOCO_ID)); - if (isSet(loco)) { - locos.remove(loco); - loco.train(null); - } return properties(); } @@ -342,7 +352,6 @@ public class Train extends BaseClass implements Comparable { if (isSet(route)) json.put(ROUTE, route.id()); if (isSet(direction)) json.put(DIRECTION, direction); - json.put(LOCOS, locos.stream().map(l -> l.id().toString()).collect(Collectors.toList())); json.put(CARS,cars.stream().map(c -> c.id().toString()).collect(Collectors.toList())); json.put(TRACE, trace.stream().map(t -> t.id().toString()).collect(Collectors.toList())); @@ -352,7 +361,6 @@ public class Train extends BaseClass implements Comparable { public int length() { int result = 0; - for (Locomotive loco : locos) result += loco.length; for (Car car : cars) result += car.length; return result; } @@ -397,46 +405,14 @@ public class Train extends BaseClass implements Comparable { 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(new Id(elem.toString()), false).set(this)); }); if (json.has(BLOCK)) currentBlock = (Block) plan.get(new Id(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)); + if (json.has(LOCOS)) { // for downward compatibility + for (Object id : json.getJSONArray(LOCOS)) add(BaseClass.get(new Id(""+id))); + } + for (Object id : json.getJSONArray(CARS)) add(BaseClass.get(new Id(""+id))); super.load(json); return this; } - private Tag locoList() { - Tag locoProp = new Tag("li").content(t("Locomotives:")); - Tag locoList = new Tag("ul").clazz("locolist"); - - for (Locomotive loco : this.locos) { - Tag li = new Tag("li"); - loco.link(loco.name()+(loco.stockId.isEmpty() ? "" : " ("+loco.stockId+")")).addTo(li); - loco.button(t("turn within train"),Map.of(ACTION,ACTION_TURN)).addTo(li); - button(t("delete"),Map.of(ACTION,ACTION_DROP,LOCO_ID,loco.id().toString())).addTo(li); - li.addTo(locoList); - } - - Form addLocoForm = new Form("append-loco-form"); - addLocoForm.content(t("add locomotive:")+" "); - new Input(REALM, REALM_TRAIN).hideIn(addLocoForm); - new Input(ACTION, ACTION_ADD).hideIn(addLocoForm); - new Input(ID,id).hideIn(addLocoForm); - Select select = new Select(CAR_ID); - for (Car loco : BaseClass.listElements(Locomotive.class)) { - if (isNull(loco.train())) select.addOption(loco.id(), loco); - } - if (!select.children().isEmpty()) { - select.addTo(addLocoForm); - new Button(t("add"),addLocoForm).addTo(addLocoForm); - addLocoForm.addTo(new Tag("li")).addTo(locoList); - } - return locoList.addTo(locoProp); - } - - public List locos(){ - return new Vector(locos); - } - - public static Object manager() { Window win = new Window("train-manager", t("Train manager")); new Tag("h4").content(t("known trains")).addTo(win); @@ -481,11 +457,6 @@ public class Train extends BaseClass implements Comparable { private int maxSpeed() { int maxSpeed = Integer.MAX_VALUE; - for (Locomotive loco : locos) { - int max = loco.maxSpeed(); - if (max == 0) continue; - maxSpeed = Math.min(max, maxSpeed); - } for (Car car : cars) { int max = car.maxSpeed(); if (max == 0) continue; @@ -493,9 +464,21 @@ public class Train extends BaseClass implements Comparable { } return maxSpeed; } + + public Window moveUp(Car car) { + for (int i = 1; i isSet(car.name())).findFirst().get().name()); } private Train name(String newName) { @@ -513,7 +496,6 @@ public class Train extends BaseClass implements Comparable { Tag propList = new Tag("ul").clazz("proplist"); - locoList().addTo(propList); carList().addTo(propList); if (isSet(currentBlock)) currentBlock.button(currentBlock.toString()).addTo(new Tag("li").content(t("Current location:")+NBSP)).addTo(propList); @@ -579,7 +561,6 @@ public class Train extends BaseClass implements Comparable { if (child == currentBlock) currentBlock = null; if (child == destination) destination = null; cars.remove(child); - locos.remove(child); trace.remove(child); super.removeChild(child); } @@ -657,7 +638,7 @@ public class Train extends BaseClass implements Comparable { public void setSpeed(int newSpeed) { speed = Math.min(newSpeed,maxSpeed()); if (speed < 0) speed = 0; - for (Locomotive loco : locos) loco.setSpeed(speed); + cars.stream().filter(c -> c instanceof Locomotive).forEach(car -> ((Locomotive)car).setSpeed(speed)); plan.stream(t("Set {} to {} {}",this,speed,speedUnit)); } @@ -781,19 +762,21 @@ public class Train extends BaseClass implements Comparable { public SortedSet tags() { TreeSet list = new TreeSet(tags); - for (Locomotive loco : locos) list.addAll(loco.tags()); + //for (Locomotive loco : locos) list.addAll(loco.tags()); for (Car car:cars) list.addAll(car.tags()); return list; } @Override public String toString() { - return isSet(name) ? name : locos.firstElement().name(); + return name(); } public Tag turn() { LOG.debug("train.turn()"); - for (Locomotive loco : locos) loco.turn(); + + for (Car car : cars) car.turn(); + Collections.reverse(cars); if (isSet(direction)) { direction = direction.inverse(); reverseTrace();