implemented saving and loading of routes
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>de.srsoftware</groupId>
|
<groupId>de.srsoftware</groupId>
|
||||||
<artifactId>web4rail</artifactId>
|
<artifactId>web4rail</artifactId>
|
||||||
<version>0.1.0</version>
|
<version>0.2.0</version>
|
||||||
<name>Web4Rail</name>
|
<name>Web4Rail</name>
|
||||||
<description>Java Model Railway Control</description>
|
<description>Java Model Railway Control</description>
|
||||||
<url>https://github.com/StephanRichter/Web4Rail</url>
|
<url>https://github.com/StephanRichter/Web4Rail</url>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class Application {
|
|||||||
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
|
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
|
||||||
server.start();
|
server.start();
|
||||||
try {
|
try {
|
||||||
plan = Plan.load("default.plan");
|
plan = Plan.load("default");
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
plan = new Plan();
|
plan = new Plan();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import de.srsoftware.web4rail.tiles.EndS;
|
|||||||
import de.srsoftware.web4rail.tiles.EndW;
|
import de.srsoftware.web4rail.tiles.EndW;
|
||||||
import de.srsoftware.web4rail.tiles.Eraser;
|
import de.srsoftware.web4rail.tiles.Eraser;
|
||||||
import de.srsoftware.web4rail.tiles.Shadow;
|
import de.srsoftware.web4rail.tiles.Shadow;
|
||||||
|
import de.srsoftware.web4rail.tiles.Signal;
|
||||||
import de.srsoftware.web4rail.tiles.SignalE;
|
import de.srsoftware.web4rail.tiles.SignalE;
|
||||||
import de.srsoftware.web4rail.tiles.SignalN;
|
import de.srsoftware.web4rail.tiles.SignalN;
|
||||||
import de.srsoftware.web4rail.tiles.SignalS;
|
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.StraightH;
|
||||||
import de.srsoftware.web4rail.tiles.StraightV;
|
import de.srsoftware.web4rail.tiles.StraightV;
|
||||||
import de.srsoftware.web4rail.tiles.Tile;
|
import de.srsoftware.web4rail.tiles.Tile;
|
||||||
|
import de.srsoftware.web4rail.tiles.Turnout;
|
||||||
import de.srsoftware.web4rail.tiles.Turnout.State;
|
import de.srsoftware.web4rail.tiles.Turnout.State;
|
||||||
import de.srsoftware.web4rail.tiles.TurnoutLE;
|
import de.srsoftware.web4rail.tiles.TurnoutLE;
|
||||||
import de.srsoftware.web4rail.tiles.TurnoutLN;
|
import de.srsoftware.web4rail.tiles.TurnoutLN;
|
||||||
@@ -114,13 +116,10 @@ public class Plan {
|
|||||||
for (HashMap<Integer, Tile> column: tiles.values()) {
|
for (HashMap<Integer, Tile> column: tiles.values()) {
|
||||||
for (Tile tile : column.values()) tile.routes().clear();
|
for (Tile tile : column.values()) tile.routes().clear();
|
||||||
}
|
}
|
||||||
for (Route route : routes) {
|
for (Route route : routes) registerRoute(route);
|
||||||
for (Tile tile: route.path()) tile.add(route);
|
|
||||||
this.routes.put(route.id(), route);
|
|
||||||
}
|
|
||||||
return t("Found {} routes.",routes.size());
|
return t("Found {} routes.",routes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<Route> follow(Route route, Connector connector) {
|
private Collection<Route> follow(Route route, Connector connector) {
|
||||||
Tile tile = get(connector.x,connector.y);
|
Tile tile = get(connector.x,connector.y);
|
||||||
Vector<Route> results = new Vector<>();
|
Vector<Route> 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 {
|
public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||||
Plan result = new Plan();
|
Plan result = new Plan();
|
||||||
File file = new File(filename);
|
File file = new File(filename+".plan");
|
||||||
BufferedReader br = new BufferedReader(new FileReader(file));
|
BufferedReader br = new BufferedReader(new FileReader(file));
|
||||||
while (br.ready()) {
|
while (br.ready()) {
|
||||||
String line = br.readLine().trim();
|
String line = br.readLine().trim();
|
||||||
@@ -181,6 +180,43 @@ public class Plan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
br.close();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +357,11 @@ public class Plan {
|
|||||||
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
|
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
|
||||||
return tile.propMenu();
|
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 {
|
private String saveTo(String name) throws IOException {
|
||||||
if (name == null || name.isEmpty()) throw new NullPointerException("Name must not be empty!");
|
if (name == null || name.isEmpty()) throw new NullPointerException("Name must not be empty!");
|
||||||
@@ -340,6 +381,12 @@ public class Plan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
br.close();
|
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);
|
return t("Plan saved as \"{}\".",file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ package de.srsoftware.web4rail;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -22,8 +25,11 @@ import de.srsoftware.web4rail.tiles.Turnout.State;
|
|||||||
|
|
||||||
public class Route {
|
public class Route {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
|
||||||
private static final String NAME = "name";
|
static final String NAME = "name";
|
||||||
private static final HashMap<String,String> names = new HashMap<String, String>();
|
private static final HashMap<String,String> names = new HashMap<String, String>();
|
||||||
|
static final String PATH = "path";
|
||||||
|
static final String SIGNALS = "signals";
|
||||||
|
static final String TURNOUTS = "turnouts";
|
||||||
private Vector<Tile> path;
|
private Vector<Tile> path;
|
||||||
private Vector<Signal> signals;
|
private Vector<Signal> signals;
|
||||||
private Vector<Contact> contacts;
|
private Vector<Contact> contacts;
|
||||||
@@ -36,12 +42,20 @@ public class Route {
|
|||||||
if (tile instanceof Contact) contacts.add((Contact) tile);
|
if (tile instanceof Contact) contacts.add((Contact) tile);
|
||||||
if (tile instanceof Signal) {
|
if (tile instanceof Signal) {
|
||||||
Signal signal = (Signal) tile;
|
Signal signal = (Signal) tile;
|
||||||
if (signal.isAffectedFrom(direrction)) signals.add(signal);
|
if (signal.isAffectedFrom(direrction)) addSignal(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addSignal(Signal signal) {
|
||||||
|
signals.add(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTurnout(Turnout t, State s) {
|
||||||
|
turnouts.put(t, s);
|
||||||
|
}
|
||||||
|
|
||||||
protected Route clone() {
|
protected Route clone() {
|
||||||
Route clone = new Route();
|
Route clone = new Route();
|
||||||
clone.contacts = new Vector<Contact>(contacts);
|
clone.contacts = new Vector<Contact>(contacts);
|
||||||
@@ -68,6 +82,29 @@ public class Route {
|
|||||||
}
|
}
|
||||||
return id;
|
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<Turnout, State> 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<Route> multiply(int size) {
|
public List<Route> multiply(int size) {
|
||||||
Vector<Route> routes = new Vector<Route>();
|
Vector<Route> routes = new Vector<Route>();
|
||||||
@@ -80,30 +117,44 @@ public class Route {
|
|||||||
return name == null ? id() : name;
|
return name == null ? id() : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void name(String name) {
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
names.remove(id());
|
||||||
|
} else names.put(id(),name);
|
||||||
|
}
|
||||||
|
|
||||||
public Vector<Tile> path() {
|
public Vector<Tile> path() {
|
||||||
return new Vector<Tile>(path);
|
Vector<Tile> result = new Vector<Tile>();
|
||||||
|
if (path != null) result.addAll(path);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Window properties() {
|
public Window properties() {
|
||||||
Window win = new Window("route-properties",t("Properties of {}",this));
|
Window win = new Window("route-properties",t("Properties of {}",this));
|
||||||
|
|
||||||
new Tag("h4").content(t("Signals")).addTo(win);
|
if (!signals.isEmpty()) {
|
||||||
Tag list = new Tag("ul");
|
new Tag("h4").content(t("Signals")).addTo(win);
|
||||||
for (Signal s : signals) Plan.addLink(s,s.toString(),list);
|
Tag list = new Tag("ul");
|
||||||
list.addTo(win);
|
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);
|
if (!contacts.isEmpty()) {
|
||||||
list.addTo(win);
|
new Tag("h4").content(t("Contacts")).addTo(win);
|
||||||
|
Tag list = new Tag("ul");
|
||||||
new Tag("h4").content(t("Turnouts")).addTo(win);
|
for (Contact c : contacts) Plan.addLink(c,c.toString(),list);
|
||||||
list = new Tag("ul");
|
list.addTo(win);
|
||||||
for (Entry<Turnout, State> 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<Turnout, State> entry : turnouts.entrySet()) {
|
||||||
|
Turnout turnout = entry.getKey();
|
||||||
|
Plan.addLink(turnout, turnout+": "+entry.getValue(), list);
|
||||||
|
}
|
||||||
|
list.addTo(win);
|
||||||
}
|
}
|
||||||
list.addTo(win);
|
|
||||||
|
|
||||||
Tag form = propForm();
|
Tag form = propForm();
|
||||||
new Tag("button").attr("type", "submit").content(t("save")).addTo(form);
|
new Tag("button").attr("type", "submit").content(t("save")).addTo(form);
|
||||||
@@ -141,13 +192,7 @@ public class Route {
|
|||||||
public void setLast(State state) {
|
public void setLast(State state) {
|
||||||
if (state == null || state == State.UNDEF) return;
|
if (state == null || state == State.UNDEF) return;
|
||||||
Tile lastTile = path.lastElement();
|
Tile lastTile = path.lastElement();
|
||||||
if (lastTile instanceof Turnout) turnouts.put((Turnout) lastTile,state);
|
if (lastTile instanceof Turnout) addTurnout((Turnout) lastTile,state);
|
||||||
}
|
|
||||||
|
|
||||||
private void setName(String name) {
|
|
||||||
if (name.isEmpty()) {
|
|
||||||
names.remove(id());
|
|
||||||
} else names.put(id(),name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block startBlock() {
|
public Block startBlock() {
|
||||||
@@ -160,6 +205,6 @@ public class Route {
|
|||||||
|
|
||||||
public void update(HashMap<String, String> params) {
|
public void update(HashMap<String, String> params) {
|
||||||
LOG.debug("update({})",params);
|
LOG.debug("update({})",params);
|
||||||
if (params.containsKey(NAME)) setName(params.get(NAME));
|
if (params.containsKey(NAME)) name(params.get(NAME));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.srsoftware.web4rail.tiles;
|
package de.srsoftware.web4rail.tiles;
|
||||||
|
|
||||||
public abstract class Turnout extends Tile {
|
public abstract class Turnout extends Tile {
|
||||||
|
public static final String STATE = "state";
|
||||||
public enum State{
|
public enum State{
|
||||||
LEFT,STRAIGHT,RIGHT,UNDEF;
|
LEFT,STRAIGHT,RIGHT,UNDEF;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user