From 104da20eecd611cc3589bbd12527dfc41545b574 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Wed, 11 Nov 2020 00:07:10 +0100 Subject: [PATCH] re-implemented waiting times: those are now block-assigned and relate to tags rather than trains TODO: * implement re-ordering of tags for block * implement autopilot such that it obeys the wait times --- pom.xml | 2 +- .../de/srsoftware/web4rail/moving/Train.java | 60 +----- .../de/srsoftware/web4rail/tiles/Block.java | 204 ++++++++++++++---- 3 files changed, 170 insertions(+), 96 deletions(-) diff --git a/pom.xml b/pom.xml index f733371..a967a7b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.10.15 + 0.10.16 Web4Rail jar Java Model Railway Control diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index c5c7e52..35aa342 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -71,25 +71,12 @@ public class Train extends BaseClass implements Comparable { private Vector locos = new Vector(); private static final String TAGS = "tags"; - private static final String WAIT_TIMES = "wait_times"; - private static final String MAX = "max"; - private static final String MIN = "min"; private HashSet tags = new HashSet(); - private HashMap waitTimes = new HashMap(); - private Block block = null; LinkedList trace = new LinkedList(); - - public class WaitTime{ - public int min =0,max=10000; - @Override - public String toString() { - return min+"..."+max+" s"; - } - } - + private class Autopilot extends Thread{ boolean stop = false; @@ -340,11 +327,6 @@ public class Train extends BaseClass implements Comparable { json.put(TRACE, tileIds); if (!tags.isEmpty()) json.put(TAGS, tags); - JSONObject jWaitTimes = new JSONObject(); - for (Entry entry: waitTimes.entrySet()) { - jWaitTimes.put(entry.getKey(), Map.of(MIN,entry.getValue().min,MAX,entry.getValue().max)); - } - json.put(WAIT_TIMES, jWaitTimes); return json; } @@ -388,14 +370,6 @@ public class Train extends BaseClass implements Comparable { 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! for (Object id : json.getJSONArray(CARS)) add(Car.get(id)); for (Object id : json.getJSONArray(LOCOS)) add((Locomotive) Car.get(id)); - if (json.has(WAIT_TIMES)) { - JSONObject jWaitTimes = json.getJSONObject(WAIT_TIMES); - for (String key : jWaitTimes.keySet()) { - JSONObject wt = jWaitTimes.getJSONObject(key); - setWaitTime(key, wt.getInt(MIN), true); - setWaitTime(key, wt.getInt(MAX), false); - } - } return this; } @@ -576,22 +550,6 @@ public class Train extends BaseClass implements Comparable { this.speed = v; } - public void setWaitTime(String key,int time, boolean min) { - WaitTime wt = waitTime(key); - if (time < 0) time = 0; - if (min) { - wt.min = time; - if (wt.max < time) wt.max = time; - } else { - wt.max = time; - if (wt.min > time) wt.min = time; - } - } - - public void setWaitTime(Block block, Direction dir, int time, boolean min) { - setWaitTime(block.id()+":"+dir, time, min); - } - public void showTrace() { int remainingLength = length(); if (remainingLength<1) remainingLength=1; @@ -685,20 +643,6 @@ public class Train extends BaseClass implements Comparable { } public void removeFromTrace(Tile tile) { - trace.remove(tile); - - } - - public WaitTime waitTime(String key) { - WaitTime wt = waitTimes.get(key); - if (wt == null) { - wt = new WaitTime(); - waitTimes.put(key, wt); - } - return wt; - } - - public WaitTime waitTime(Block block, Direction dir) { - return waitTime(block.id()+":"+dir); + trace.remove(tile); } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index 00a3b61..bc4568c 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -5,7 +5,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Vector; +import org.json.JSONArray; import org.json.JSONObject; import de.srsoftware.tools.Tag; @@ -13,7 +15,6 @@ import de.srsoftware.web4rail.Connector; import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Window; import de.srsoftware.web4rail.moving.Train; -import de.srsoftware.web4rail.moving.Train.WaitTime; import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Checkbox; import de.srsoftware.web4rail.tags.Form; @@ -29,8 +30,111 @@ import de.srsoftware.web4rail.tags.Select; public abstract class Block extends StretchableTile{ private static final String ALLOW_TURN = "allowTurn"; private static final String NAME = "name"; + private static final String NO_TAG = "[default]"; + private static final String NEW_TAG = "new_tag"; + private static final String TAG = "tag"; + private static final String MAX = "max"; + private static final String MIN = "min"; + private static final String WAIT_TIMES = "wait_times"; + public String name = "Block"; public boolean turnAllowed = false; + + public Block() { + super(); + WaitTime defaultWT = new WaitTime(NO_TAG); + defaultWT.setMin(directionA(), 0); + defaultWT.setMax(directionA(), 10000); + defaultWT.setMin(directionB(), 0); + defaultWT.setMax(directionB(), 10000); + waitTimes.add(defaultWT); + } + + /** + * class for min-max range + */ + public class Range{ + public int min=0,max=10000; + + public JSONObject json() { + return new JSONObject(Map.of(MIN,min,MAX,max)); + } + + public Range load(JSONObject json) { + min = json.getInt(MIN); + max = json.getInt(MAX); + return this; + } + + @Override + public String toString() { + return min+"…"+max; + } + } + + /** + * aggregates all (directional) wait times for one tag + */ + public class WaitTime{ + public String tag = ""; + private HashMap dirs = new HashMap(); + + public WaitTime(String tag) { + this.tag = tag; + } + + public Range get(Direction dir) { + Range range = dirs.get(dir); + if (range == null) { + range = new Range(); + dirs.put(dir, range); + } + return range; + } + + public JSONObject json() { + JSONObject json = new JSONObject(); + json.put(TAG, tag); + for (Entry entry : dirs.entrySet()) json.put(entry.getKey().toString(), entry.getValue().json()); + return json; + } + + public WaitTime load(JSONObject json) { + for (String key : json.keySet()) { + if (key.equals(TAG)) { + tag = json.getString(key); + } else { + Direction dir = Direction.valueOf(key); + Range range = new Range().load(json.getJSONObject(key)); + dirs.put(dir, range); + } + } + return this; + } + + public WaitTime setMax(Direction dir,int max) { + get(dir).max = max; + return this; + } + + public WaitTime setMin(Direction dir,int min) { + get(dir).min = min; + return this; + } + + public WaitTime setTag(String newTag){ + tag = newTag; + return this; + } + + @Override + public String toString() { + return "WaitTime("+tag+", "+dirs+")"; + } + } + + + private Vector waitTimes = new Vector(); @Override public JSONObject config() { @@ -47,6 +151,9 @@ public abstract class Block extends StretchableTile{ JSONObject json = super.json(); json.put(NAME, name); json.put(ALLOW_TURN, turnAllowed); + JSONArray jWaitTimes = new JSONArray(); + for (WaitTime wt : waitTimes) jWaitTimes.put(wt.json()); + json.put(WAIT_TIMES, jWaitTimes); return json; } @@ -55,6 +162,13 @@ public abstract class Block extends StretchableTile{ super.load(json); name = json.has(NAME) ? json.getString(NAME) : "Block"; turnAllowed = json.has(ALLOW_TURN) && json.getBoolean(ALLOW_TURN); + if (json.has(WAIT_TIMES)) { + waitTimes.clear(); + JSONArray wtArr = json.getJSONArray(WAIT_TIMES); + wtArr.forEach(object -> { + if (object instanceof JSONObject) waitTimes.add(new WaitTime(null).load((JSONObject) object)); + }); + } return this; } @@ -82,39 +196,44 @@ public abstract class Block extends StretchableTile{ new Input(ID,id()).hideIn(form); new Input(ACTION,ACTION_UPDATE).hideIn(form); + Direction dA = directionA(); + Direction dB = directionB(); + Tag table = new Tag("table"); - Tag row = new Tag("tr"); + Tag row = new Tag("tr"); new Tag("td").content(t("Direction")).addTo(row); - new Tag("th").attr("colspan", 2).content(directionA().toString()).addTo(row); - new Tag("th").attr("colspan", 2).content(directionB().toString()).addTo(row); + new Tag("th").content(t("{}",dA)).attr("colspan", 2).addTo(row); + new Tag("th").content(t("{}",dB)).attr("colspan", 2).addTo(row).addTo(table); - row.addTo(table); - - row = new Tag("tr"); - new Tag("th").content(t("Train")).addTo(row); + row = new Tag("tr"); + new Tag("th").content(t("Tag")).addTo(row); new Tag("th").content(t("min")).addTo(row); new Tag("th").content(t("max")).addTo(row); new Tag("th").content(t("min")).addTo(row); - new Tag("th").content(t("max")).addTo(row); - row.addTo(table); - - for (Train train : Train.list()) { + new Tag("th").content(t("max")).addTo(row).addTo(table); + + for (WaitTime wt : waitTimes) { row = new Tag("tr"); - new Tag("td").content(train.name()).addTo(row); - Direction a = directionA(); - WaitTime wtA = train.waitTime(this, a); - Direction b = directionB(); - WaitTime wtB = train.waitTime(this, b); - new Input("train."+train.id+"."+directionA()+".min",wtA.min).numeric().addTo(new Tag("td")).addTo(row); - new Input("train."+train.id+"."+directionA()+".max",wtA.max).numeric().addTo(new Tag("td")).addTo(row); - new Input("train."+train.id+"."+directionB()+".min",wtB.min).numeric().addTo(new Tag("td")).addTo(row); - new Input("train."+train.id+"."+directionB()+".max",wtB.max).numeric().addTo(new Tag("td")).addTo(row); - row.addTo(table); + new Tag("td").content(wt.tag).addTo(row); + new Input("min."+wt.tag+"."+dA,wt.get(dA).min).numeric().addTo(new Tag("td")).addTo(row); + new Input("max."+wt.tag+"."+dA,wt.get(dA).max).numeric().addTo(new Tag("td")).addTo(row); + new Input("min."+wt.tag+"."+dB,wt.get(dB).min).numeric().addTo(new Tag("td")).addTo(row); + new Input("max."+wt.tag+"."+dB,wt.get(dB).max).numeric().addTo(new Tag("td")).addTo(row).addTo(table); + } + + WaitTime defaultWT = getWaitTime(NO_TAG); + + row = new Tag("tr"); + new Input(NEW_TAG,"").attr("placeholder", t("new tag")).addTo(new Tag("td")).addTo(row); + new Input("min."+NEW_TAG+"."+dA,defaultWT.get(dA).min).numeric().addTo(new Tag("td")).addTo(row); + new Input("max."+NEW_TAG+"."+dA,defaultWT.get(dA).max).numeric().addTo(new Tag("td")).addTo(row); + new Input("min."+NEW_TAG+"."+dB,defaultWT.get(dB).min).numeric().addTo(new Tag("td")).addTo(row); + new Input("max."+NEW_TAG+"."+dB,defaultWT.get(dB).max).numeric().addTo(new Tag("td")).addTo(row).addTo(table); table.addTo(form); - new Button(t("Apply")).addTo(form).addTo(win); + new Button(t("Apply"),form).addTo(form).addTo(win); return win; } @@ -162,25 +281,36 @@ public abstract class Block extends StretchableTile{ } turnAllowed = params.containsKey(ALLOW_TURN) && params.get(ALLOW_TURN).equals("on"); - for (Entry entry : params.entrySet()) { + String newTag = params.get(NEW_TAG); + for (Entry entry:params.entrySet()) { String key = entry.getKey(); - if (key.startsWith("train.")) { + String val = entry.getValue(); + + if (key.startsWith("max.") || key.startsWith("min.")) { String[] parts = key.split("\\."); - int trainId = Integer.parseInt(parts[1]); - Train t = Train.get(trainId); - if (t == null) continue; - + boolean isMin = parts[0].equals("min"); + String tag = parts[1].equals("new_tag") ? newTag : parts[1]; Direction dir = Direction.valueOf(parts[2]); - boolean min = parts[3].equals("min"); - int time = Integer.parseInt(entry.getValue()); - t.setWaitTime(this,dir,time,min); - - LOG.debug("{} / {} : {}",t,dir,t.waitTime(this, dir)); - - } + WaitTime wt = getWaitTime(tag); + if (wt == null) { + wt = new WaitTime(tag); + waitTimes.add(wt); + } + if (isMin) { + wt.setMin(dir, Integer.parseInt(val)); + } else wt.setMax(dir, Integer.parseInt(val)); + } } - + return super.update(params); } + + private WaitTime getWaitTime(String tag) { + if (tag == null) return null; + for (WaitTime wt : waitTimes) { + if (wt.tag.equals(tag)) return wt; + } + return null; + } }