Browse Source

refactored tiles data structure in plan

lookup-tables
Stephan Richter 5 years ago
parent
commit
67623f49bc
  1. 2
      pom.xml
  2. 11
      resources/js/plan.js
  3. 82
      src/main/java/de/srsoftware/web4rail/Plan.java
  4. 30
      src/main/java/de/srsoftware/web4rail/Route.java
  5. 15
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

2
pom.xml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId>
<version>0.3.5</version>
<version>0.3.6</version>
<name>Web4Rail</name>
<description>Java Model Railway Control</description>
<url>https://github.com/StephanRichter/Web4Rail</url>

11
resources/js/plan.js

@ -24,8 +24,9 @@ function addTile(x,y){ @@ -24,8 +24,9 @@ function addTile(x,y){
}
function clickTile(x,y){
console.log("clickTile:",x,y);
if ($('#tile-'+x+'-'+y).length > 0) request({action:'click',x:x,y:y});
var id = x+"-"+y;
console.log("clickTile:",id);
if ($('#'+id).length > 0) request({action:'click',id:id});
return false;
}
@ -84,8 +85,9 @@ function heartbeat(data){ @@ -84,8 +85,9 @@ function heartbeat(data){
}
function moveTile(x,y){
console.log("moveTile:",selected.id,x,y);
return request({action:mode,direction:selected.id,x:x,y:y});
var id = x+"-"+y;
console.log("moveTile:",selected.id,id);
return request({action:mode,direction:selected.id,id:id});
}
function openRoute(id){
@ -153,6 +155,7 @@ function train(id,mode){ @@ -153,6 +155,7 @@ function train(id,mode){
function stream(ev){
var data = ev.data;
console.log("received: ",data);
if (data.startsWith("heartbeat")) return heartbeat(data);
if (data.startsWith("place ")) return place(data.substring(6));
if (data.startsWith("remove")) return remove(data.substring(7));

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

@ -106,7 +106,7 @@ public class Plan { @@ -106,7 +106,7 @@ public class Plan {
private static final HashMap<OutputStreamWriter,Integer> clients = new HashMap<OutputStreamWriter, Integer>();
private static final String ACTION_TRAIN = "train";
public HashMap<Integer,HashMap<Integer,Tile>> tiles = new HashMap<Integer,HashMap<Integer,Tile>>();
public HashMap<String,Tile> tiles = new HashMap<String,Tile>();
private HashSet<Block> blocks = new HashSet<Block>();
private HashMap<String, Route> routes = new HashMap<String, Route>();
@ -139,7 +139,7 @@ public class Plan { @@ -139,7 +139,7 @@ public class Plan {
clazz = tc.getName().replace(".Tile", "."+clazz);
Tile tile = (Tile) tc.getClassLoader().loadClass(clazz).getDeclaredConstructor().newInstance();
if (tile instanceof Eraser) {
Tile erased = get(x,y,true);
Tile erased = get(Tile.id(x,y),true);
remove(erased);
return erased == null ? null : t("Removed {}.",erased);
}
@ -154,9 +154,7 @@ public class Plan { @@ -154,9 +154,7 @@ public class Plan {
for (Connector con : block.startPoints()) routes.addAll(follow(new Route().start(block,con.from.inverse()),con));
}
this.routes.clear();
for (HashMap<Integer, Tile> column: tiles.values()) {
for (Tile tile : column.values()) tile.routes().clear();
}
for (Tile tile : tiles.values()) tile.routes().clear();
for (Route route : routes) {
route.complete();
registerRoute(route);
@ -174,7 +172,7 @@ public class Plan { @@ -174,7 +172,7 @@ public class Plan {
}
private Collection<Route> follow(Route route, Connector connector) {
Tile tile = get(connector.x,connector.y,false);
Tile tile = get(Tile.id(connector.x,connector.y),false);
Vector<Route> results = new Vector<>();
if (tile == null) return results;
Tile addedTile = route.add(tile,connector.from);
@ -183,7 +181,7 @@ public class Plan { @@ -183,7 +181,7 @@ public class Plan {
LOG.debug("Found {}, coming from {}.",addedTile,connector.from);
for (Connector con : cons.keySet()) { // falls direkt nach dem Block noch ein Kontakt kommt: diesen mit zu Route hinzufügen
LOG.debug("This is connected to {}",con);
Tile nextTile = get(con.x,con.y,false);
Tile nextTile = get(Tile.id(con.x,con.y),false);
if (nextTile instanceof Contact) {
LOG.debug("{} is followed by {}",addedTile,nextTile);
route.add(nextTile, con.from);
@ -208,13 +206,8 @@ public class Plan { @@ -208,13 +206,8 @@ public class Plan {
return results;
}
private Tile get(String x, String y,boolean resolveShadows) {
return get(Integer.parseInt(x),Integer.parseInt(y),resolveShadows);
}
public Tile get(int x, int y,boolean resolveShadows) {
HashMap<Integer, Tile> column = tiles.get(x);
Tile tile = (column == null) ? null : column.get(y);
public Tile get(String tileId,boolean resolveShadows) {
Tile tile = tiles.get(tileId);
if (resolveShadows && tile instanceof Shadow) tile = ((Shadow)tile).overlay();
return tile;
}
@ -229,15 +222,10 @@ public class Plan { @@ -229,15 +222,10 @@ public class Plan {
public Page html() throws IOException {
Page page = new Page().append("<div id=\"plan\">");
for (Entry<Integer, HashMap<Integer, Tile>> column : tiles.entrySet()) {
int x = column.getKey();
for (Entry<Integer, Tile> row : column.getValue().entrySet()) {
int y = row.getKey();
Tile tile = row.getValue().position(x, y);
for (Tile tile: tiles.values()) {
if (tile == null) continue;
page.append("\t\t"+tile.tag(null)+"\n");
}
}
return page
.append(menu())
.append(messages())
@ -281,54 +269,54 @@ public class Plan { @@ -281,54 +269,54 @@ public class Plan {
return new Tag("div").clazz("list").content(tiles.toString()).addTo(tileMenu);
}
private String moveTile(String direction, String x, String y) throws NumberFormatException, IOException {
private String moveTile(String direction, String tileId) throws NumberFormatException, IOException {
switch (direction) {
case "south":
return moveTile(Direction.SOUTH,Integer.parseInt(x),Integer.parseInt(y));
return moveTile(get(tileId,false),Direction.SOUTH);
case "north":
return moveTile(Direction.NORTH,Integer.parseInt(x),Integer.parseInt(y));
return moveTile(get(tileId,false),Direction.NORTH);
case "east":
return moveTile(Direction.EAST,Integer.parseInt(x),Integer.parseInt(y));
return moveTile(get(tileId,false),Direction.EAST);
case "west":
return moveTile(Direction.WEST,Integer.parseInt(x),Integer.parseInt(y));
return moveTile(get(tileId,false),Direction.WEST);
}
throw new InvalidParameterException(t("\"{}\" is not a known direction!"));
}
private String moveTile(Direction direction, int x, int y) throws IOException {
//LOG.debug("moveTile({},{},{})",direction,x,y);
private String moveTile(Tile tile, Direction direction) throws IOException {
boolean moved = false;
if (tile != null) {
LOG.debug("moveTile({},{},{})",direction,tile.x,tile.y);
switch (direction) {
case EAST:
moved = moveTile(x,y,+1,0);
moved = moveTile(tile,+1,0);
break;
case WEST:
moved = moveTile(x,y,-1,0);
moved = moveTile(tile,-1,0);
break;
case NORTH:
moved = moveTile(x,y,0,-1);
moved = moveTile(tile,0,-1);
break;
case SOUTH:
moved = moveTile(x,y,0,+1);
moved = moveTile(tile,0,+1);
break;
}
}
return t(moved ? "Tile(s) moved.":"No tile(s) moved.");
}
private boolean moveTile(int x, int y,int xstep,int ystep) throws IOException {
LOG.error("moveTile({}+ {},{}+ {})",x,xstep,y,ystep);
private boolean moveTile(Tile tile,int xstep,int ystep) throws IOException {
LOG.error("moveTile({} +{}/+{})",tile,xstep,ystep);
Stack<Tile> stack = new Stack<Tile>();
Tile tile = get(x,y,false);
while (tile != null) {
LOG.debug("scheduling tile for movement: {} @ {},{}",tile,x,y);
LOG.debug("scheduling tile for movement: {}",tile);
stack.add(tile);
x+=xstep;
y+=ystep;
tile = get(x,y,false);
tile = get(Tile.id(tile.x+xstep, tile.y+ystep),false);
}
while (!stack.isEmpty()) {
tile = stack.pop();
if (!(tile instanceof Shadow)) {
LOG.debug("altering position of {}",tile);
remove(tile);
set(tile.x+xstep,tile.y+ystep,tile);
}
@ -349,11 +337,11 @@ public class Plan { @@ -349,11 +337,11 @@ public class Plan {
case ACTION_ADD:
return addTile(params.get(TILE),params.get(X),params.get(Y),null);
case ACTION_CLICK:
return click(get(params.get(X),params.get(Y),true));
return click(get(params.get(Tile.ID),true));
case ACTION_ANALYZE:
return analyze();
case ACTION_MOVE:
return moveTile(params.get(DIRECTION),params.get(X),params.get(Y));
return moveTile(params.get(DIRECTION),params.get(Tile.ID));
case ACTION_ROUTE:
return routeProperties(params.get(ID));
case ACTION_SAVE:
@ -395,12 +383,11 @@ public class Plan { @@ -395,12 +383,11 @@ public class Plan {
if (tile instanceof Block) blocks.remove(tile);
for (int i=1; i<tile.len(); i++) remove_intern(tile.x+i, tile.y); // remove shadow tiles
for (int i=1; i<tile.height(); i++) remove_intern(tile.x, tile.y+i); // remove shadow tiles
if (tile != null) stream("remove tile-"+tile.x+"-"+tile.y);
if (tile != null) stream("remove "+tile.id());
}
private void remove_intern(int x, int y) {
HashMap<Integer, Tile> column = tiles.get(x);
if (column != null) column.remove(y);
LOG.debug("removed {} from tile list",tiles.remove(Tile.id(x, y)));
}
private String saveTo(String name) throws IOException {
@ -422,13 +409,8 @@ public class Plan { @@ -422,13 +409,8 @@ public class Plan {
}
private void set_intern(int x, int y, Tile tile) {
HashMap<Integer, Tile> column = tiles.get(x);
if (column == null) {
column = new HashMap<Integer, Tile>();
tiles.put(x,column);
}
tile.position(x, y).plan(this);
column.put(y,tile);
tiles.put(tile.id(),tile);
}
public synchronized void stream(String data) {
@ -510,7 +492,7 @@ public class Plan { @@ -510,7 +492,7 @@ public class Plan {
}
private void update(int x,int y, HashMap<String, String> params) throws IOException {
Tile tile = get(x,y,true);
Tile tile = get(Tile.id(x, y),true);
if (tile != null) set(x,y,tile.update(params));
}

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

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
package de.srsoftware.web4rail;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
@ -35,7 +37,6 @@ import de.srsoftware.web4rail.tiles.Turnout.State; @@ -35,7 +37,6 @@ import de.srsoftware.web4rail.tiles.Turnout.State;
public class Route {
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
static final String NAME = "name";
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";
@ -45,6 +46,7 @@ public class Route { @@ -45,6 +46,7 @@ public class Route {
private HashMap<Turnout,Turnout.State> turnouts;
private HashMap<Object,Vector<Action>> triggers = new HashMap<Object, Vector<Action>>();
private String id;
private String name;
public Train train;
private Block startBlock = null,endBlock;
public Direction startDirection;
@ -190,14 +192,29 @@ public class Route { @@ -190,14 +192,29 @@ public class Route {
}
props.put(TURNOUTS, turnouts);
if (names.containsKey(id())) props.put(NAME, names.get(id));
if (name != null) props.put(NAME, name);
return props.toString();
}
public static void loadAll(String string, Plan plan) {
// TODO Auto-generated method stub
private Route load(JSONObject json,Plan plan) {
JSONArray pathIds = json.getJSONArray(PATH);
for (Object tileId : pathIds) {
plan.get((String) tileId,false);
}
return this;
}
public static void loadAll(String filename, Plan plan) throws IOException {
BufferedReader file = new BufferedReader(new FileReader(filename));
String line = file.readLine();
while (line != null) {
JSONObject json = new JSONObject(line);
new Route().load(json,plan);
line = file.readLine();
}
file.close();
}
public Route lock(Train train) throws IOException {
@ -216,14 +233,11 @@ public class Route { @@ -216,14 +233,11 @@ public class Route {
}
public String name() {
String name = names.get(id());
return name == null ? id() : name;
}
public void name(String name) {
if (name.isEmpty()) {
names.remove(id());
} else names.put(id(),name);
this.name = name;
}
public Vector<Tile> path() {

15
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -96,7 +96,11 @@ public abstract class Tile { @@ -96,7 +96,11 @@ public abstract class Tile {
}
public String id() {
return x+":"+y;
return Tile.id(x, y);
}
public static String id(int x, int y) {
return x+"-"+y;
}
private static void inflate(String clazz, JSONObject json, Plan plan) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException {
@ -237,15 +241,12 @@ public abstract class Tile { @@ -237,15 +241,12 @@ public abstract class Tile {
return routes;
}
public static void saveAll(HashMap<Integer, HashMap<Integer, Tile>> tiles ,String filename) throws IOException {
public static void saveAll(HashMap<String, Tile> tiles ,String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
for (Entry<Integer, HashMap<Integer, Tile>> column : tiles.entrySet()) {
for (Entry<Integer, Tile> row : column.getValue().entrySet()) {
Tile tile = row.getValue();
for (Tile tile : tiles.values()) {
if (tile == null || tile instanceof Shadow) continue;
file.append(tile.json()+"\n");
}
}
file.close();
}
@ -261,7 +262,7 @@ public abstract class Tile { @@ -261,7 +262,7 @@ public abstract class Tile {
replacements.put("%height%",height);
String style = "";
Tag svg = new Tag("svg")
.id((x!=-1 && y!=-1)?("tile-"+x+"-"+y):(getClass().getSimpleName()))
.id((x!=-1 && y!=-1)?(id()):(getClass().getSimpleName()))
.clazz(classes())
.size(100,100)
.attr("name", getClass().getSimpleName())

Loading…
Cancel
Save