From 28ade2f7fafdd4d56d89e9499af79ec4f21b349e Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 17 Sep 2020 01:08:23 +0200 Subject: [PATCH] implemented saving and loading of routes --- pom.xml | 2 +- .../de/srsoftware/web4rail/Application.java | 2 +- .../java/de/srsoftware/web4rail/Plan.java | 59 ++++++++++-- .../java/de/srsoftware/web4rail/Route.java | 95 ++++++++++++++----- .../de/srsoftware/web4rail/tiles/Turnout.java | 1 + 5 files changed, 126 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index b061892..93c3e9f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.1.0 + 0.2.0 Web4Rail Java Model Railway Control https://github.com/StephanRichter/Web4Rail diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java index e86d474..bff7dce 100644 --- a/src/main/java/de/srsoftware/web4rail/Application.java +++ b/src/main/java/de/srsoftware/web4rail/Application.java @@ -41,7 +41,7 @@ public class Application { server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool()); server.start(); try { - plan = Plan.load("default.plan"); + plan = Plan.load("default"); } catch (FileNotFoundException e) { plan = new Plan(); } diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index d97c4e3..b91fa85 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -39,6 +39,7 @@ import de.srsoftware.web4rail.tiles.EndS; import de.srsoftware.web4rail.tiles.EndW; import de.srsoftware.web4rail.tiles.Eraser; import de.srsoftware.web4rail.tiles.Shadow; +import de.srsoftware.web4rail.tiles.Signal; import de.srsoftware.web4rail.tiles.SignalE; import de.srsoftware.web4rail.tiles.SignalN; import de.srsoftware.web4rail.tiles.SignalS; @@ -46,6 +47,7 @@ import de.srsoftware.web4rail.tiles.SignalW; import de.srsoftware.web4rail.tiles.StraightH; import de.srsoftware.web4rail.tiles.StraightV; import de.srsoftware.web4rail.tiles.Tile; +import de.srsoftware.web4rail.tiles.Turnout; import de.srsoftware.web4rail.tiles.Turnout.State; import de.srsoftware.web4rail.tiles.TurnoutLE; import de.srsoftware.web4rail.tiles.TurnoutLN; @@ -114,13 +116,10 @@ public class Plan { for (HashMap column: tiles.values()) { for (Tile tile : column.values()) tile.routes().clear(); } - for (Route route : routes) { - for (Tile tile: route.path()) tile.add(route); - this.routes.put(route.id(), route); - } + for (Route route : routes) registerRoute(route); return t("Found {} routes.",routes.size()); } - + private Collection follow(Route route, Connector connector) { Tile tile = get(connector.x,connector.y); Vector results = new Vector<>(); @@ -166,7 +165,7 @@ public class Plan { public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Plan result = new Plan(); - File file = new File(filename); + File file = new File(filename+".plan"); BufferedReader br = new BufferedReader(new FileReader(file)); while (br.ready()) { String line = br.readLine().trim(); @@ -181,6 +180,43 @@ public class Plan { } } br.close(); + file = new File(filename+".routes"); + if (file.exists()) { + br = new BufferedReader(new FileReader(file)); + while (br.ready()) { + String line = br.readLine().trim(); + String[] parts = line.split("=",2); + try { + String id = parts[0]; + JSONObject json = new JSONObject(parts[1]); + Route route = new Route(); + json.getJSONArray(Route.PATH).forEach(entry -> { + JSONObject pos = (JSONObject) entry; + Tile tile = result.get(pos.getInt("x"),pos.getInt("y")); + if (route.path().isEmpty()) { + route.start((Block) tile); + } else { + route.add(tile, null); + } + }); + json.getJSONArray(Route.SIGNALS).forEach(entry -> { + JSONObject pos = (JSONObject) entry; + Tile tile = result.get(pos.getInt("x"),pos.getInt("y")); + route.addSignal((Signal) tile); + }); + json.getJSONArray(Route.TURNOUTS).forEach(entry -> { + JSONObject pos = (JSONObject) entry; + Tile tile = result.get(pos.getInt("x"),pos.getInt("y")); + route.addTurnout((Turnout) tile, Turnout.State.valueOf(pos.getString(Turnout.STATE))); + }); + if (json.has(Route.NAME)) route.name(json.getString(Route.NAME)); + result.registerRoute(route); + } catch (Exception e) { + LOG.warn("Was not able to load \"{}\":",line,e); + } + } + br.close(); + } else LOG.debug("{} not found.",file); return result; } @@ -321,6 +357,11 @@ public class Plan { if (tile instanceof Shadow) tile = ((Shadow)tile).overlay(); return tile.propMenu(); } + + private void registerRoute(Route route) { + for (Tile tile: route.path()) tile.add(route); + routes.put(route.id(), route); + } private String saveTo(String name) throws IOException { if (name == null || name.isEmpty()) throw new NullPointerException("Name must not be empty!"); @@ -340,6 +381,12 @@ public class Plan { } } br.close(); + file = new File(name+".routes"); + br = new BufferedWriter(new FileWriter(file)); + for (Route route: routes.values()) { + br.append(route.id()+"="+route.json()+"\n"); + } + br.close(); return t("Plan saved as \"{}\".",file); } diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index c6314e0..1d31dd4 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -2,9 +2,12 @@ package de.srsoftware.web4rail; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,8 +25,11 @@ import de.srsoftware.web4rail.tiles.Turnout.State; public class Route { private static final Logger LOG = LoggerFactory.getLogger(Route.class); - private static final String NAME = "name"; + static final String NAME = "name"; private static final HashMap names = new HashMap(); + static final String PATH = "path"; + static final String SIGNALS = "signals"; + static final String TURNOUTS = "turnouts"; private Vector path; private Vector signals; private Vector contacts; @@ -36,12 +42,20 @@ public class Route { if (tile instanceof Contact) contacts.add((Contact) tile); if (tile instanceof Signal) { Signal signal = (Signal) tile; - if (signal.isAffectedFrom(direrction)) signals.add(signal); + if (signal.isAffectedFrom(direrction)) addSignal(signal); } return tile; } + void addSignal(Signal signal) { + signals.add(signal); + } + + void addTurnout(Turnout t, State s) { + turnouts.put(t, s); + } + protected Route clone() { Route clone = new Route(); clone.contacts = new Vector(contacts); @@ -68,6 +82,29 @@ public class Route { } return id; } + + public String json() { + JSONObject props = new JSONObject(); + JSONArray path = new JSONArray(); + for (Tile t : this.path) path.put(new JSONObject(Map.of("x",t.x,"y",t.y))); + props.put(PATH, path); + + JSONArray signals = new JSONArray(); + for (Tile t : this.signals) signals.put(new JSONObject(Map.of("x",t.x,"y",t.y))); + props.put(SIGNALS, signals); + + JSONArray turnouts = new JSONArray(); + for (Entry entry : this.turnouts.entrySet()) { + Turnout t = entry.getKey(); + turnouts.put(new JSONObject(Map.of("x",t.x,"y",t.y,Turnout.STATE,entry.getValue()))); + } + props.put(TURNOUTS, turnouts); + + if (names.containsKey(id())) props.put(NAME, names.get(id)); + + return props.toString(); + } + public List multiply(int size) { Vector routes = new Vector(); @@ -80,30 +117,44 @@ public class Route { return name == null ? id() : name; } + public void name(String name) { + if (name.isEmpty()) { + names.remove(id()); + } else names.put(id(),name); + } + public Vector path() { - return new Vector(path); + Vector result = new Vector(); + if (path != null) result.addAll(path); + return result; } public Window properties() { Window win = new Window("route-properties",t("Properties of {}",this)); - new Tag("h4").content(t("Signals")).addTo(win); - Tag list = new Tag("ul"); - for (Signal s : signals) Plan.addLink(s,s.toString(),list); - list.addTo(win); + if (!signals.isEmpty()) { + new Tag("h4").content(t("Signals")).addTo(win); + Tag list = new Tag("ul"); + for (Signal s : signals) Plan.addLink(s,s.toString(),list); + list.addTo(win); + } - new Tag("h4").content(t("Contacts")).addTo(win); - list = new Tag("ul"); - for (Contact c : contacts) Plan.addLink(c,c.toString(),list); - list.addTo(win); + if (!contacts.isEmpty()) { + new Tag("h4").content(t("Contacts")).addTo(win); + Tag list = new Tag("ul"); + for (Contact c : contacts) Plan.addLink(c,c.toString(),list); + list.addTo(win); + } - new Tag("h4").content(t("Turnouts")).addTo(win); - list = new Tag("ul"); - for (Entry entry : turnouts.entrySet()) { - Turnout turnout = entry.getKey(); - Plan.addLink(turnout, turnout+": "+entry.getValue(), list); + if (!turnouts.isEmpty()) { + new Tag("h4").content(t("Turnouts")).addTo(win); + Tag list = new Tag("ul"); + for (Entry entry : turnouts.entrySet()) { + Turnout turnout = entry.getKey(); + Plan.addLink(turnout, turnout+": "+entry.getValue(), list); + } + list.addTo(win); } - list.addTo(win); Tag form = propForm(); new Tag("button").attr("type", "submit").content(t("save")).addTo(form); @@ -141,13 +192,7 @@ public class Route { public void setLast(State state) { if (state == null || state == State.UNDEF) return; Tile lastTile = path.lastElement(); - if (lastTile instanceof Turnout) turnouts.put((Turnout) lastTile,state); - } - - private void setName(String name) { - if (name.isEmpty()) { - names.remove(id()); - } else names.put(id(),name); + if (lastTile instanceof Turnout) addTurnout((Turnout) lastTile,state); } public Block startBlock() { @@ -160,6 +205,6 @@ public class Route { public void update(HashMap params) { LOG.debug("update({})",params); - if (params.containsKey(NAME)) setName(params.get(NAME)); + if (params.containsKey(NAME)) name(params.get(NAME)); } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java index 0bf6e12..8a886a0 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java @@ -1,6 +1,7 @@ package de.srsoftware.web4rail.tiles; public abstract class Turnout extends Tile { + public static final String STATE = "state"; public enum State{ LEFT,STRAIGHT,RIGHT,UNDEF; }