Browse Source

implemented storing of routes

lookup-tables
Stephan Richter 5 years ago
parent
commit
5c67e6089d
  1. 31
      src/main/java/de/srsoftware/web4rail/Plan.java
  2. 118
      src/main/java/de/srsoftware/web4rail/Route.java
  3. 10
      src/main/java/de/srsoftware/web4rail/actions/Action.java
  4. 5
      src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java
  5. 7
      src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
  6. 22
      src/main/java/de/srsoftware/web4rail/actions/RouteAction.java
  7. 6
      src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
  8. 15
      src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java
  9. 8
      src/main/java/de/srsoftware/web4rail/tiles/Contact.java

31
src/main/java/de/srsoftware/web4rail/Plan.java

@ -108,7 +108,7 @@ public class Plan {
public HashMap<String,Tile> tiles = new HashMap<String,Tile>(); public HashMap<String,Tile> tiles = new HashMap<String,Tile>();
private HashSet<Block> blocks = new HashSet<Block>(); private HashSet<Block> blocks = new HashSet<Block>();
private HashMap<String, Route> routes = new HashMap<String, Route>(); private HashMap<Integer, Route> routes = new HashMap<Integer, Route>();
public Plan() { public Plan() {
new Heartbeat().start(); 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 { public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
try { try {
Car.loadAll(filename+".cars"); Car.loadAll(filename+".cars");
} catch (Exception e) {
LOG.debug("Was not able to load cars!",e);
}
try {
Train.loadAll(filename+".trains"); Train.loadAll(filename+".trains");
} catch (Exception e) {} } catch (Exception e) {
LOG.debug("Was not able to load trains!",e);
}
Plan plan = new Plan(); Plan plan = new Plan();
Tile.loadAll(filename+".plan",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; return plan;
} }
@ -343,7 +353,7 @@ public class Plan {
case ACTION_MOVE: case ACTION_MOVE:
return moveTile(params.get(DIRECTION),params.get(Tile.ID)); return moveTile(params.get(DIRECTION),params.get(Tile.ID));
case ACTION_ROUTE: case ACTION_ROUTE:
return routeProperties(params.get(ID)); return routeProperties(Integer.parseInt(params.get(ID)));
case ACTION_SAVE: case ACTION_SAVE:
return saveTo(params.get(FILE)); return saveTo(params.get(FILE));
case ACTION_TRAIN: case ACTION_TRAIN:
@ -367,15 +377,16 @@ public class Plan {
return result instanceof Train ? html() : result; return result instanceof Train ? html() : result;
} }
private Object routeProperties(String routeId) { private Object routeProperties(int id) {
Route route = routes.get(routeId); Route route = routes.get(id);
if (route == null) return t("Could not find route \"{}\"",routeId); if (route == null) return t("Could not find route \"{}\"",id);
return route.properties(); return route.properties();
} }
private void registerRoute(Route route) { Route registerRoute(Route route) {
for (Tile tile: route.path()) tile.add(route); for (Tile tile: route.path()) tile.add(route);
routes.put(route.id(), route); routes.put(route.id(), route);
return route;
} }
private void remove(Tile tile) { private void remove(Tile tile) {
@ -395,7 +406,7 @@ public class Plan {
Car.saveAll(name+".cars"); Car.saveAll(name+".cars");
Tile.saveAll(tiles,name+".plan"); Tile.saveAll(tiles,name+".plan");
Train.saveAll(name+".trains"); // refers to cars, blocks 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); return t("Plan saved as \"{}\".",name);
} }
@ -484,7 +495,7 @@ public class Plan {
private Object update(HashMap<String, String> params) throws IOException { private Object update(HashMap<String, String> params) throws IOException {
if (params.containsKey(ROUTE)) { 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)); if (route == null) return t("Unknown route: {}",params.get(ROUTE));
route.update(params); route.update(params);
} else update(Integer.parseInt(params.get("x")),Integer.parseInt(params.get("y")),params); } else update(Integer.parseInt(params.get("x")),Integer.parseInt(params.get("y")),params);

118
src/main/java/de/srsoftware/web4rail/Route.java

@ -5,6 +5,7 @@ import java.io.BufferedWriter;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -44,12 +45,17 @@ public class Route {
private Vector<Signal> signals; private Vector<Signal> signals;
private Vector<Contact> contacts; private Vector<Contact> contacts;
private HashMap<Turnout,Turnout.State> turnouts; private HashMap<Turnout,Turnout.State> turnouts;
private HashMap<Object,Vector<Action>> triggers = new HashMap<Object, Vector<Action>>(); private HashMap<String,Vector<Action>> triggers = new HashMap<String, Vector<Action>>();
private String id; private int id;
private String name; private static HashMap<Integer, String> names = new HashMap<Integer, String>(); // maps id to name. needed to keep names during plan.analyze()
public Train train; public Train train;
private Block startBlock = null,endBlock; private Block startBlock = null,endBlock;
private static final String START_DIRECTION = "direction_start";
public Direction startDirection; 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; private Direction endDirection;
/** /**
@ -77,7 +83,7 @@ public class Route {
return tile; return tile;
} }
private void addAction(Object trigger, Action action) { private void addAction(String trigger, Action action) {
Vector<Action> actions = triggers.get(trigger); Vector<Action> actions = triggers.get(trigger);
if (actions == null) { if (actions == null) {
actions = new Vector<Action>(); actions = new Vector<Action>();
@ -109,15 +115,15 @@ public class Route {
public void complete() { public void complete() {
if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein
addAction(contacts.firstElement(),new ActivateRoute(this)); addAction(contacts.firstElement().trigger(),new ActivateRoute(this));
Contact nextToLastContact = contacts.get(contacts.size()-2); Contact nextToLastContact = contacts.get(contacts.size()-2);
addAction(nextToLastContact,new SpeedReduction(this,30)); addAction(nextToLastContact.trigger(),new SpeedReduction(this,30));
addAction(nextToLastContact,new SetSignalsToStop(this)); addAction(nextToLastContact.trigger(),new SetSignalsToStop(this));
} }
if (!contacts.isEmpty()) { if (!contacts.isEmpty()) {
Contact lastContact = contacts.lastElement(); Contact lastContact = contacts.lastElement();
addAction(lastContact, new SpeedReduction(this, 0)); addAction(lastContact.trigger(), new SpeedReduction(this, 0));
addAction(lastContact, new FinishRoute(this)); addAction(lastContact.trigger(), new FinishRoute(this));
} }
} }
@ -128,7 +134,7 @@ public class Route {
*/ */
public void contact(Contact contact) { public void contact(Contact contact) {
LOG.debug("{} on {} activated {}.",train,this,contact); LOG.debug("{} on {} activated {}.",train,this,contact);
Vector<Action> actions = triggers.get(contact); Vector<Action> actions = triggers.get(contact.trigger());
for (Action action : actions) { for (Action action : actions) {
try { try {
action.fire(); action.fire();
@ -150,33 +156,37 @@ public class Route {
endBlock.train(train.heading(endDirection.inverse())); endBlock.train(train.heading(endDirection.inverse()));
} }
public String id() {
if (id == null) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<path.size();i++) {
Tile tile = path.get(i);
if (i>0) 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() { public boolean free() {
for (int i=1; i<path.size(); i++) { for (int i=1; i<path.size(); i++) {
if (!path.get(i).free()) return false; if (!path.get(i).free()) return false;
} }
return true; return true;
} }
private String generateName() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<path.size();i++) {
Tile tile = path.get(i);
if (i>0) 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() { public String json() {
JSONObject props = new JSONObject(); JSONObject props = new JSONObject();
props.put(ID, id());
Vector<String> tileIds = new Vector<String>(); Vector<String> tileIds = new Vector<String>();
for (Tile t : this.path) tileIds.add(t.id()); for (Tile t : this.path) tileIds.add(t.id());
props.put(PATH, tileIds); 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()))); turnouts.put(new JSONObject(Map.of(Turnout.ID,t.id(),Turnout.STATE,entry.getValue())));
} }
props.put(TURNOUTS, turnouts); props.put(TURNOUTS, turnouts);
props.put(START_DIRECTION, startDirection);
props.put(END_DIRECTION, startDirection);
JSONArray jTriggers = new JSONArray();
for (Entry<String, Vector<Action>> 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); if (name != null) props.put(NAME, name);
return props.toString(); return props.toString();
} }
private Route load(JSONObject json,Plan plan) { private Route load(JSONObject json,Plan plan) {
if (json.has(ID)) id = json.getInt(ID);
JSONArray pathIds = json.getJSONArray(PATH); JSONArray pathIds = json.getJSONArray(PATH);
startDirection = Direction.valueOf(json.getString(START_DIRECTION));
endDirection = Direction.valueOf(json.getString(END_DIRECTION));
for (Object tileId : pathIds) { 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 { public static void loadAll(String filename, Plan plan) throws IOException {
@ -233,11 +269,16 @@ public class Route {
} }
public String name() { 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) { public void name(String name) {
this.name = name; names.put(id(),name);
} }
public Vector<Tile> path() { public Vector<Tile> path() {
@ -290,7 +331,7 @@ public class Route {
public Tag propForm() { public Tag propForm() {
Form form = new Form(); 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","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:")); Tag label = new Tag("label").content(t("name:"));
new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).addTo(label); new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).addTo(label);
@ -299,12 +340,9 @@ public class Route {
return form; return form;
} }
public static void saveAll(HashMap<String, Route> routes, String filename) throws IOException { public static void saveAll(Collection<Route> routes, String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename)); BufferedWriter file = new BufferedWriter(new FileWriter(filename));
for (Entry<String, Route> entry : routes.entrySet()) { for (Route route : routes) file.write(route.json()+"\n");
Route route = entry.getValue();
file.write(route.json()+"\n");
}
file.close(); file.close();
} }

10
src/main/java/de/srsoftware/web4rail/actions/Action.java

@ -2,9 +2,19 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException; import java.io.IOException;
import org.json.JSONObject;
public abstract class Action { public abstract class Action {
private static final String TYPE = "type";
public abstract void fire() throws IOException; public abstract void fire() throws IOException;
public JSONObject json() {
JSONObject json = new JSONObject();
json.put(TYPE, getClass().getSimpleName());
return json;
}
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName(); return getClass().getSimpleName();

5
src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java

@ -4,12 +4,11 @@ import java.io.IOException;
import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Route;
public class ActivateRoute extends Action { public class ActivateRoute extends RouteAction {
private Route route;
public ActivateRoute(Route route) { public ActivateRoute(Route route) {
this.route = route; super(route);
} }
@Override @Override

7
src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java

@ -4,17 +4,14 @@ import java.io.IOException;
import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Route;
public class FinishRoute extends Action { public class FinishRoute extends RouteAction {
private Route route;
public FinishRoute(Route route) { public FinishRoute(Route route) {
this.route = route; super(route);
} }
@Override @Override
public void fire() throws IOException { public void fire() throws IOException {
route.finish(); route.finish();
} }
} }

22
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;
}
}

6
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.Route;
import de.srsoftware.web4rail.tiles.Signal; import de.srsoftware.web4rail.tiles.Signal;
public class SetSignalsToStop extends Action { public class SetSignalsToStop extends RouteAction {
private Route route;
public SetSignalsToStop(Route route) { public SetSignalsToStop(Route route) {
this.route = route; super(route);
} }
@Override @Override
public void fire() throws IOException { public void fire() throws IOException {
route.setSignals(Signal.STOP); route.setSignals(Signal.STOP);
} }
} }

15
src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java

@ -1,15 +1,17 @@
package de.srsoftware.web4rail.actions; package de.srsoftware.web4rail.actions;
import org.json.JSONObject;
import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.moving.Train; 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 int maxSpeed;
private Route route;
public SpeedReduction(Route route, int kmh) { public SpeedReduction(Route route, int kmh) {
this.route = route; super(route);
maxSpeed = kmh; maxSpeed = kmh;
} }
@ -18,4 +20,11 @@ public class SpeedReduction extends Action {
Train train = route.train; Train train = route.train;
if (train != null && train.speed > maxSpeed) train.setSpeed(maxSpeed); if (train != null && train.speed > maxSpeed) train.setSpeed(maxSpeed);
} }
@Override
public JSONObject json() {
JSONObject json = super.json();
json.put(MAX_SPEED, maxSpeed);
return json;
}
} }

8
src/main/java/de/srsoftware/web4rail/tiles/Contact.java

@ -7,7 +7,7 @@ import de.srsoftware.tools.Tag;
public abstract class Contact extends Tile{ public abstract class Contact extends Tile{
private boolean active = false; private boolean active = false;
private String trigger = null;
public void activate() throws IOException { public void activate() throws IOException {
active = true; active = true;
@ -41,4 +41,10 @@ public abstract class Contact extends Tile{
plan.stream("place "+tag); plan.stream("place "+tag);
} }
public String trigger() {
if (trigger == null) trigger = getClass().getSimpleName()+"-"+id();
return trigger;
}
} }

Loading…
Cancel
Save