Browse Source

re-implemented moving of tiles

lookup-tables
Stephan Richter 5 years ago
parent
commit
9bfe0d56dd
  1. 2
      pom.xml
  2. 4
      resources/css/style.css
  3. 4
      src/main/java/de/srsoftware/web4rail/BaseClass.java
  4. 95
      src/main/java/de/srsoftware/web4rail/Plan.java
  5. 2
      src/main/java/de/srsoftware/web4rail/tiles/BlockH.java
  6. 2
      src/main/java/de/srsoftware/web4rail/tiles/BlockV.java
  7. 4
      src/main/java/de/srsoftware/web4rail/tiles/Shadow.java
  8. 2
      src/main/java/de/srsoftware/web4rail/tiles/StraightH.java
  9. 2
      src/main/java/de/srsoftware/web4rail/tiles/StraightV.java
  10. 62
      src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java
  11. 2
      src/main/java/de/srsoftware/web4rail/tiles/TextDisplay.java
  12. 25
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

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>1.2.16</version> <version>1.2.17</version>
<name>Web4Rail</name> <name>Web4Rail</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>Java Model Railway Control</description> <description>Java Model Railway Control</description>

4
resources/css/style.css

@ -109,7 +109,9 @@ svg circle{
text-align: center; text-align: center;
} }
.Shadow, .Shadow{
z-index: 100;
}
.menu .list{ .menu .list{
display: none; display: none;
} }

4
src/main/java/de/srsoftware/web4rail/BaseClass.java

@ -398,6 +398,10 @@ public abstract class BaseClass implements Constants{
return Translation.get(Application.class, txt, fills); return Translation.get(Application.class, txt, fills);
} }
public BaseClass unregister() {
return registry.remove(this.id());
}
protected Object update(HashMap<String, String> params) { protected Object update(HashMap<String, String> params) {
LOG.debug("update: {}",params); LOG.debug("update: {}",params);
if (params.containsKey(NOTES)) notes = params.get(NOTES).trim(); if (params.containsKey(NOTES)) notes = params.get(NOTES).trim();

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

@ -15,7 +15,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Stack;
import java.util.Vector; import java.util.Vector;
import org.json.JSONArray; import org.json.JSONArray;
@ -63,6 +62,7 @@ import de.srsoftware.web4rail.tiles.SignalS;
import de.srsoftware.web4rail.tiles.SignalW; 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.StretchableTile;
import de.srsoftware.web4rail.tiles.TextDisplay; import de.srsoftware.web4rail.tiles.TextDisplay;
import de.srsoftware.web4rail.tiles.Tile; import de.srsoftware.web4rail.tiles.Tile;
import de.srsoftware.web4rail.tiles.Turnout.State; import de.srsoftware.web4rail.tiles.Turnout.State;
@ -238,9 +238,8 @@ public class Plan extends BaseClass{
} }
return null; return null;
} }
//if (configJson != null) tile.configure(new JSONObject(configJson)); if (tile instanceof StretchableTile) ((StretchableTile)tile).placeShadows();
set(x, y, tile); place(tile.position(x, y));
tile.parent(this);
return t("Added {}",tile.getClass().getSimpleName()); return t("Added {}",tile.getClass().getSimpleName());
} }
@ -503,13 +502,13 @@ public class Plan extends BaseClass{
private String moveTile(String direction, Id tileId) throws NumberFormatException, IOException { private String moveTile(String direction, Id tileId) throws NumberFormatException, IOException {
switch (direction) { switch (direction) {
case "south": case "south":
return moveTile(get(tileId,false),Direction.SOUTH); return moveTile(get(tileId,true),Direction.SOUTH);
case "north": case "north":
return moveTile(get(tileId,false),Direction.NORTH); return moveTile(get(tileId,true),Direction.NORTH);
case "east": case "east":
return moveTile(get(tileId,false),Direction.EAST); return moveTile(get(tileId,true),Direction.EAST);
case "west": case "west":
return moveTile(get(tileId,false),Direction.WEST); return moveTile(get(tileId,true),Direction.WEST);
} }
throw new InvalidParameterException(t("\"{}\" is not a known direction!")); throw new InvalidParameterException(t("\"{}\" is not a known direction!"));
} }
@ -527,47 +526,25 @@ public class Plan extends BaseClass{
LOG.debug("moveTile({},{},{})",direction,tile.x,tile.y); LOG.debug("moveTile({},{},{})",direction,tile.x,tile.y);
switch (direction) { switch (direction) {
case EAST: case EAST:
moved = moveTile(tile,+1,0); moved = tile.move(+1,0);
break; break;
case WEST: case WEST:
moved = moveTile(tile,-1,0); moved = tile.move(-1,0);
break; break;
case NORTH: case NORTH:
moved = moveTile(tile,0,-1); moved = tile.move(0,-1);
break; break;
case SOUTH: case SOUTH:
moved = moveTile(tile,0,+1); moved = tile.move(0,+1);
break; break;
} }
} }
return t(moved ? "Tile(s) moved.":"No tile(s) moved."); return t(moved ? "Tile(s) moved.":"No tile(s) moved.");
} }
/** public void drop(Tile tile) {
* processes move-tile instructions sent from the client (subroutine) tile.unregister();
* @param tile stream("remove "+tile.id());
* @param xstep
* @param ystep
* @return
* @throws IOException
*/
private boolean moveTile(Tile tile,int xstep,int ystep) throws IOException {
LOG.error("moveTile({} +{}/+{})",tile,xstep,ystep);
Stack<Tile> stack = new Stack<Tile>();
while (tile != null) {
LOG.debug("scheduling tile for movement: {}",tile);
stack.add(tile);
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);
tile.remove();
set(tile.x+xstep,tile.y+ystep,tile);
}
}
return false;
} }
/** /**
@ -578,6 +555,8 @@ public class Plan extends BaseClass{
*/ */
public Tile place(Tile tile) { public Tile place(Tile tile) {
try { try {
tile.parent(this);
tile.register();
stream("place "+tile.tag(null)); stream("place "+tile.tag(null));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -659,22 +638,7 @@ public class Plan extends BaseClass{
@Override @Override
protected void removeChild(BaseClass child) { protected void removeChild(BaseClass child) {
if (child instanceof Tile) { if (child instanceof Tile) drop((Tile) child);
Tile tile = (Tile) child;
stream("remove "+tile.id());
for (int i=1; i<tile.width(); i++) removeTile(tile.x+i, tile.y); // remove shadow tiles
for (int i=1; i<tile.height(); i++) removeTile(tile.x, tile.y+i); // remove shadow tiles
}
}
/**
* removes a tile from the track layout (subroutine)
* @param x
* @param y
*/
private void removeTile(int x, int y) {
Tile tile = BaseClass.get(Tile.id(x, y));
if (isSet(tile)) tile.remove();
} }
/** /**
@ -713,31 +677,6 @@ public class Plan extends BaseClass{
.put(LENGTH_UNIT, lengthUnit); .put(LENGTH_UNIT, lengthUnit);
} }
/**
* adds a tile to the plan at a specific position
* @param x
* @param y
* @param tile
* @throws IOException
*/
public void set(int x,int y,Tile tile) throws IOException {
if (isNull(tile)) return;
setIntern(x,y,tile);
for (int i=1; i<tile.width(); i++) set(x+i,y,new Shadow(tile,x+i,y));
for (int i=1; i<tile.height(); i++) set(x,y+i,new Shadow(tile,x,y+1));
place(tile);
}
/**
* adds a tile to the plan at a specific position (subroutine)
* @param x
* @param y
* @param tile
*/
private void setIntern(int x, int y, Tile tile) {
tile.position(x, y).register();
}
public void sensor(int addr, boolean active) { public void sensor(int addr, boolean active) {
Contact contact = Contact.get(addr); Contact contact = Contact.get(addr);
if (active && learningContact != null) { if (active && learningContact != null) {

2
src/main/java/de/srsoftware/web4rail/tiles/BlockH.java

@ -36,7 +36,7 @@ public class BlockH extends Block{
@Override @Override
public int width() { public int width() {
return stretch; return stretch();
} }
@Override @Override

2
src/main/java/de/srsoftware/web4rail/tiles/BlockV.java

@ -36,7 +36,7 @@ public class BlockV extends Block{
@Override @Override
public int height() { public int height() {
return stretch; return stretch();
} }
@Override @Override

4
src/main/java/de/srsoftware/web4rail/tiles/Shadow.java

@ -20,11 +20,11 @@ public class Shadow extends Tile{
return super.connections(from); return super.connections(from);
} }
public Shadow(Tile overlay, int x, int y) { public Shadow(StretchableTile overlay, int x, int y) {
this.overlay = overlay; this.overlay = overlay;
this.x = x; this.x = x;
this.y = y; this.y = y;
overlay.addShadow(this); overlay.add(this);
} }
public Tile overlay() { public Tile overlay() {

2
src/main/java/de/srsoftware/web4rail/tiles/StraightH.java

@ -35,6 +35,6 @@ public class StraightH extends StretchableTile{
@Override @Override
public int width() { public int width() {
return stretch; return stretch();
} }
} }

2
src/main/java/de/srsoftware/web4rail/tiles/StraightV.java

@ -25,7 +25,7 @@ public class StraightV extends StretchableTile{
@Override @Override
public int height() { public int height() {
return stretch; return stretch();
} }
@Override @Override

62
src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java

@ -3,17 +3,24 @@ package de.srsoftware.web4rail.tiles;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Vector;
import org.json.JSONObject; import org.json.JSONObject;
import de.srsoftware.tools.Tag; import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Window; import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.tags.Fieldset; import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Input; import de.srsoftware.web4rail.tags.Input;
public abstract class StretchableTile extends Tile { public abstract class StretchableTile extends Tile {
private static final String STRETCH_LENGTH = "stretch"; private static final String STRETCH_LENGTH = "stretch";
public int stretch = 1; private int stretch = 1;
private Vector<Id> shadows = new Vector<Id>();
public void add(Shadow shadow) {
shadows.add(shadow.id());
}
@Override @Override
public JSONObject config() { public JSONObject config() {
@ -35,12 +42,57 @@ public abstract class StretchableTile extends Tile {
return super.load(json); return super.load(json);
} }
@Override
public boolean move(int dx, int dy) {
for (int destX=1; destX<width(); destX++) {
int destY = dy > 0 ? height() : dy;
Tile tileAtDest = plan.get(Tile.id(x+destX, y+destY), true);
if (isNull(tileAtDest) || tileAtDest == this) continue;
if (!tileAtDest.move(dx, dy)) return false;
}
for (int destY=1; destY<height(); destY++) {
int destX = dx > 0 ? width() : dx;
Tile tileAtDest = plan.get(Tile.id(x+destX, y+destY), true);
if (isNull(tileAtDest) || tileAtDest == this) continue;
if (!tileAtDest.move(dx, dy)) return false;
}
boolean moved = super.move(dx, dy);
if (moved) placeShadows();
return moved;
}
public void placeShadows() {
removeShadows();
for (int dx=1; dx<width(); dx++) plan.place(new Shadow(this, x+dx, y));
for (int dy=1; dy<height(); dy++) plan.place(new Shadow(this, x, y+dy));
}
@Override @Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) { protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
formInputs.add(stretchType(),new Input(STRETCH_LENGTH, stretch).numeric().addTo(new Tag("span")).content(NBSP+t("Tile(s)"))); formInputs.add(stretchType(),new Input(STRETCH_LENGTH, stretch).numeric().addTo(new Tag("span")).content(NBSP+t("Tile(s)")));
return super.properties(preForm, formInputs, postForm); return super.properties(preForm, formInputs, postForm);
} }
@Override
public BaseClass remove() {
super.remove();
removeShadows();
return this;
}
private void removeShadows() {
while (!shadows.isEmpty()) {
Tile tile = BaseClass.get(shadows.remove(0));
if (tile instanceof Shadow) tile.remove();
}
}
public int stretch() {
return stretch;
}
private void stretch(String value) { private void stretch(String value) {
try { try {
stretch(Integer.parseInt(value)); stretch(Integer.parseInt(value));
@ -49,8 +101,12 @@ public abstract class StretchableTile extends Tile {
} }
} }
public void stretch(int len) { public void stretch(int newStretch) {
this.stretch = Math.max(1, len); newStretch = Math.max(1, newStretch);
if (newStretch != stretch) {
stretch = newStretch;
placeShadows();
}
} }
protected abstract String stretchType(); protected abstract String stretchType();

2
src/main/java/de/srsoftware/web4rail/tiles/TextDisplay.java

@ -81,6 +81,6 @@ public class TextDisplay extends StretchableTile {
@Override @Override
public int width() { public int width() {
return stretch; return stretch();
} }
} }

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

@ -56,7 +56,6 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
protected Direction oneWay = null; protected Direction oneWay = null;
protected Route route = null; protected Route route = null;
private TreeSet<Route> routes = new TreeSet<>(); private TreeSet<Route> routes = new TreeSet<>();
protected TreeSet<Shadow> shadows = new TreeSet<>();
protected Train train = null; protected Train train = null;
public Integer x = null; public Integer x = null;
public Integer y = null; public Integer y = null;
@ -65,10 +64,6 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
this.routes.add(route); this.routes.add(route);
} }
public void addShadow(Shadow shadow) {
shadows.add(shadow);
}
protected Vector<String> classes(){ protected Vector<String> classes(){
Vector<String> classes = new Vector<String>(); Vector<String> classes = new Vector<String>();
classes.add("tile"); classes.add("tile");
@ -113,8 +108,9 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
private static void inflate(String clazz, JSONObject json, Plan plan) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException { private static void inflate(String clazz, JSONObject json, Plan plan) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException {
clazz = Tile.class.getName().replace(".Tile", "."+clazz); clazz = Tile.class.getName().replace(".Tile", "."+clazz);
Tile tile = (Tile) Tile.class.getClassLoader().loadClass(clazz).getDeclaredConstructor().newInstance(); Tile tile = (Tile) Tile.class.getClassLoader().loadClass(clazz).getDeclaredConstructor().newInstance();
tile.load(json).parent(plan); tile.load(json).register();
plan.set(tile.x, tile.y, tile); if (tile instanceof StretchableTile) ((StretchableTile)tile).placeShadows();
plan.place(tile);
} }
public boolean isFreeFor(Train newTrain) { public boolean isFreeFor(Train newTrain) {
@ -382,14 +378,12 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
public BaseClass remove() { public BaseClass remove() {
super.remove(); super.remove();
while (!routes.isEmpty()) routes.first().remove(); while (!routes.isEmpty()) routes.first().remove();
while (!shadows.isEmpty()) shadows.first().remove();
return this; return this;
} }
@Override @Override
public void removeChild(BaseClass child) { public void removeChild(BaseClass child) {
routes.remove(child); routes.remove(child);
if (child instanceof Shadow) shadows.remove(child);
if (child == train) train = null; if (child == train) train = null;
if (child == route) route = null; if (child == route) route = null;
plan.place(this); plan.place(this);
@ -421,4 +415,17 @@ public abstract class Tile extends BaseClass implements Comparable<Tile>{
public int width() { public int width() {
return 1; return 1;
} }
public boolean move(int dx, int dy) {
int destX = x+(dx > 0 ? width() : dx);
int destY = y+(dy > 0 ? height() : dy);
if (destX < 0 || destY < 0) return false;
Tile tileAtDestination = plan.get(id(destX, destY),true);
if (isSet(tileAtDestination) && !tileAtDestination.move(dx, dy)) return false;
plan.drop(this);
position(x+dx, y+dy);
plan.place(this);
return true;
}
} }

Loading…
Cancel
Save