diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index 2a0e0fc..c1d263a 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -108,7 +108,7 @@ public class Plan { public HashMap tiles = new HashMap(); private HashSet blocks = new HashSet(); - private HashMap routes = new HashMap(); + private HashMap routes = new HashMap(); public Plan() { new Heartbeat().start(); @@ -239,11 +239,21 @@ public class Plan { public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { try { Car.loadAll(filename+".cars"); + } catch (Exception e) { + LOG.debug("Was not able to load cars!",e); + } + try { Train.loadAll(filename+".trains"); - } catch (Exception e) {} + } catch (Exception e) { + LOG.debug("Was not able to load trains!",e); + } Plan plan = new Plan(); Tile.loadAll(filename+".plan",plan); - Route.loadAll(filename+".routes",plan); + try { + Route.loadAll(filename+".routes",plan); + } catch (Exception e) { + LOG.debug("Was not able to load routes!",e); + } return plan; } @@ -343,7 +353,7 @@ public class Plan { case ACTION_MOVE: return moveTile(params.get(DIRECTION),params.get(Tile.ID)); case ACTION_ROUTE: - return routeProperties(params.get(ID)); + return routeProperties(Integer.parseInt(params.get(ID))); case ACTION_SAVE: return saveTo(params.get(FILE)); case ACTION_TRAIN: @@ -367,15 +377,16 @@ public class Plan { return result instanceof Train ? html() : result; } - private Object routeProperties(String routeId) { - Route route = routes.get(routeId); - if (route == null) return t("Could not find route \"{}\"",routeId); + private Object routeProperties(int id) { + Route route = routes.get(id); + if (route == null) return t("Could not find route \"{}\"",id); return route.properties(); } - private void registerRoute(Route route) { + Route registerRoute(Route route) { for (Tile tile: route.path()) tile.add(route); routes.put(route.id(), route); + return route; } private void remove(Tile tile) { @@ -395,7 +406,7 @@ public class Plan { Car.saveAll(name+".cars"); Tile.saveAll(tiles,name+".plan"); Train.saveAll(name+".trains"); // refers to cars, blocks - Route.saveAll(routes,name+".routes"); // refers to tiles + Route.saveAll(routes.values(),name+".routes"); // refers to tiles return t("Plan saved as \"{}\".",name); } @@ -484,7 +495,7 @@ public class Plan { private Object update(HashMap params) throws IOException { if (params.containsKey(ROUTE)) { - Route route = routes.get(params.get(ROUTE)); + Route route = routes.get(Integer.parseInt(params.get(ROUTE))); if (route == null) return t("Unknown route: {}",params.get(ROUTE)); route.update(params); } else update(Integer.parseInt(params.get("x")),Integer.parseInt(params.get("y")),params); diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index be03118..8b9a0ce 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -5,6 +5,7 @@ import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,12 +45,17 @@ public class Route { private Vector signals; private Vector contacts; private HashMap turnouts; - private HashMap> triggers = new HashMap>(); - private String id; - private String name; + private HashMap> triggers = new HashMap>(); + private int id; + private static HashMap names = new HashMap(); // maps id to name. needed to keep names during plan.analyze() public Train train; private Block startBlock = null,endBlock; + private static final String START_DIRECTION = "direction_start"; public Direction startDirection; + private static final String END_DIRECTION = "direction_end"; + private static final String TRIGGER = "trigger"; + private static final String ACTIONS = "actions"; + private static final String ID = "id"; private Direction endDirection; /** @@ -77,7 +83,7 @@ public class Route { return tile; } - private void addAction(Object trigger, Action action) { + private void addAction(String trigger, Action action) { Vector actions = triggers.get(trigger); if (actions == null) { actions = new Vector(); @@ -109,15 +115,15 @@ public class Route { public void complete() { if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein - addAction(contacts.firstElement(),new ActivateRoute(this)); - Contact nextToLastContact = contacts.get(contacts.size()-2); - addAction(nextToLastContact,new SpeedReduction(this,30)); - addAction(nextToLastContact,new SetSignalsToStop(this)); + addAction(contacts.firstElement().trigger(),new ActivateRoute(this)); + Contact nextToLastContact = contacts.get(contacts.size()-2); + addAction(nextToLastContact.trigger(),new SpeedReduction(this,30)); + addAction(nextToLastContact.trigger(),new SetSignalsToStop(this)); } if (!contacts.isEmpty()) { Contact lastContact = contacts.lastElement(); - addAction(lastContact, new SpeedReduction(this, 0)); - addAction(lastContact, new FinishRoute(this)); + addAction(lastContact.trigger(), new SpeedReduction(this, 0)); + addAction(lastContact.trigger(), new FinishRoute(this)); } } @@ -128,7 +134,7 @@ public class Route { */ public void contact(Contact contact) { LOG.debug("{} on {} activated {}.",train,this,contact); - Vector actions = triggers.get(contact); + Vector actions = triggers.get(contact.trigger()); for (Action action : actions) { try { action.fire(); @@ -150,33 +156,37 @@ public class Route { endBlock.train(train.heading(endDirection.inverse())); } - public String id() { - if (id == null) { - StringBuilder sb = new StringBuilder(); - for (int i=0; i0) sb.append("-"); - if (tile instanceof Block) { - sb.append(((Block)tile).name); - if (i>0) break; // Kontakt nach dem Ziel-Block nicht mitnehmen - } else { - sb.append(tile.id()); - } - } - id = sb.toString(); - } - return id; - } - public boolean free() { for (int i=1; i0) sb.append("-"); + if (tile instanceof Block) { + sb.append(((Block)tile).name); + if (i>0) break; // Kontakt nach dem Ziel-Block nicht mitnehmen + } else { + sb.append(tile.id()); + } + } + return sb.toString(); + } + + public int id() { + if (id == 0) id = generateName().hashCode(); + return id; + } public String json() { JSONObject props = new JSONObject(); + + props.put(ID, id()); Vector tileIds = new Vector(); for (Tile t : this.path) tileIds.add(t.id()); props.put(PATH, tileIds); @@ -191,18 +201,44 @@ public class Route { turnouts.put(new JSONObject(Map.of(Turnout.ID,t.id(),Turnout.STATE,entry.getValue()))); } props.put(TURNOUTS, turnouts); + props.put(START_DIRECTION, startDirection); + props.put(END_DIRECTION, startDirection); + + JSONArray jTriggers = new JSONArray(); + for (Entry> entry : triggers.entrySet()) { + JSONObject trigger = new JSONObject(); + trigger.put(TRIGGER, entry.getKey()); + + JSONArray jActions = new JSONArray(); + for (Action action : entry.getValue()) { + jActions.put(action.json()); + } + trigger.put(ACTIONS, jActions); + + jTriggers.put(trigger); + + } + if (!jTriggers.isEmpty()) props.put(ACTIONS, jTriggers); + String name = name(); if (name != null) props.put(NAME, name); return props.toString(); } private Route load(JSONObject json,Plan plan) { + if (json.has(ID)) id = json.getInt(ID); JSONArray pathIds = json.getJSONArray(PATH); + startDirection = Direction.valueOf(json.getString(START_DIRECTION)); + endDirection = Direction.valueOf(json.getString(END_DIRECTION)); for (Object tileId : pathIds) { - plan.get((String) tileId,false); + Tile tile = plan.get((String) tileId,false); + if (startBlock == null) { + start((Block) tile, startDirection); + } else add(tile, endDirection); } - return this; + if (json.has(NAME)) name(json.getString(NAME)); + return plan.registerRoute(this); } public static void loadAll(String filename, Plan plan) throws IOException { @@ -233,11 +269,16 @@ public class Route { } public String name() { - return name == null ? id() : name; + String name = names.get(id()); + if (name == null) { + name = generateName(); + name(name); + } + return name; } - + public void name(String name) { - this.name = name; + names.put(id(),name); } public Vector path() { @@ -290,7 +331,7 @@ public class Route { public Tag propForm() { Form form = new Form(); new Tag("input").attr("type", "hidden").attr("name","action").attr("value", "update").addTo(form); - new Tag("input").attr("type", "hidden").attr("name","route").attr("value", id()).addTo(form); + new Tag("input").attr("type", "hidden").attr("name","route").attr("value", ""+id()).addTo(form); Tag label = new Tag("label").content(t("name:")); new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).addTo(label); @@ -299,12 +340,9 @@ public class Route { return form; } - public static void saveAll(HashMap routes, String filename) throws IOException { + public static void saveAll(Collection routes, String filename) throws IOException { BufferedWriter file = new BufferedWriter(new FileWriter(filename)); - for (Entry entry : routes.entrySet()) { - Route route = entry.getValue(); - file.write(route.json()+"\n"); - } + for (Route route : routes) file.write(route.json()+"\n"); file.close(); } diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java index 48b9db8..9bf47db 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/Action.java +++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java @@ -2,9 +2,19 @@ package de.srsoftware.web4rail.actions; import java.io.IOException; +import org.json.JSONObject; + public abstract class Action { + private static final String TYPE = "type"; + public abstract void fire() throws IOException; + public JSONObject json() { + JSONObject json = new JSONObject(); + json.put(TYPE, getClass().getSimpleName()); + return json; + } + @Override public String toString() { return getClass().getSimpleName(); diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java index 4e724fd..1e504a9 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java +++ b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java @@ -4,12 +4,11 @@ import java.io.IOException; import de.srsoftware.web4rail.Route; -public class ActivateRoute extends Action { +public class ActivateRoute extends RouteAction { - private Route route; public ActivateRoute(Route route) { - this.route = route; + super(route); } @Override diff --git a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java index f49ea90..403a1a6 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java +++ b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java @@ -4,17 +4,14 @@ import java.io.IOException; import de.srsoftware.web4rail.Route; -public class FinishRoute extends Action { - - private Route route; +public class FinishRoute extends RouteAction { public FinishRoute(Route route) { - this.route = route; + super(route); } @Override public void fire() throws IOException { route.finish(); } - } diff --git a/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java b/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java new file mode 100644 index 0000000..665f076 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java @@ -0,0 +1,22 @@ +package de.srsoftware.web4rail.actions; + +import org.json.JSONObject; + +import de.srsoftware.web4rail.Route; + +public abstract class RouteAction extends Action { + + private static final String ROUTE = "route"; + protected Route route; + + public RouteAction(Route route) { + this.route = route; + } + + @Override + public JSONObject json() { + JSONObject json = super.json(); + json.put(ROUTE, route.id()); + return json; + } +} diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java index 07c0052..a1e9ba6 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java @@ -5,17 +5,15 @@ import java.io.IOException; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.tiles.Signal; -public class SetSignalsToStop extends Action { +public class SetSignalsToStop extends RouteAction { - private Route route; public SetSignalsToStop(Route route) { - this.route = route; + super(route); } @Override public void fire() throws IOException { route.setSignals(Signal.STOP); } - } diff --git a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java index a834124..89c7e3b 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java @@ -1,15 +1,17 @@ package de.srsoftware.web4rail.actions; +import org.json.JSONObject; + import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.moving.Train; -public class SpeedReduction extends Action { +public class SpeedReduction extends RouteAction { + private static final String MAX_SPEED = "max_speed"; private int maxSpeed; - private Route route; public SpeedReduction(Route route, int kmh) { - this.route = route; + super(route); maxSpeed = kmh; } @@ -18,4 +20,11 @@ public class SpeedReduction extends Action { Train train = route.train; if (train != null && train.speed > maxSpeed) train.setSpeed(maxSpeed); } + + @Override + public JSONObject json() { + JSONObject json = super.json(); + json.put(MAX_SPEED, maxSpeed); + return json; + } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java index dfe7ddb..4997408 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java @@ -7,7 +7,7 @@ import de.srsoftware.tools.Tag; public abstract class Contact extends Tile{ private boolean active = false; - + private String trigger = null; public void activate() throws IOException { active = true; @@ -41,4 +41,10 @@ public abstract class Contact extends Tile{ plan.stream("place "+tag); } + + public String trigger() { + if (trigger == null) trigger = getClass().getSimpleName()+"-"+id(); + return trigger; + } + }