Browse Source

working on train movements

lookup-tables
Stephan Richter 5 years ago
parent
commit
9e36d5c0c8
  1. 5
      resources/css/style.css
  2. 6
      resources/js/plan.js
  3. 2
      src/main/java/de/srsoftware/web4rail/Application.java
  4. 9
      src/main/java/de/srsoftware/web4rail/Plan.java
  5. 78
      src/main/java/de/srsoftware/web4rail/Route.java
  6. 12
      src/main/java/de/srsoftware/web4rail/actions/Action.java
  7. 17
      src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java
  8. 20
      src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
  9. 21
      src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
  10. 21
      src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java
  11. 13
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  12. 14
      src/main/java/de/srsoftware/web4rail/tiles/Block.java
  13. 5
      src/main/java/de/srsoftware/web4rail/tiles/Contact.java
  14. 19
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java
  15. 4
      src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java
  16. 4
      src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java

5
resources/css/style.css

@ -44,6 +44,11 @@ svg.locked rect:not(.sig_a):not(.sig_b){
fill:lime; fill:lime;
} }
svg.occupied polygon,
svg.occupied rect:not(.sig_a):not(.sig_b){
fill:yellow;
}
svg text{ svg text{
font-size: 50px; font-size: 50px;
} }

6
resources/js/plan.js

@ -15,7 +15,7 @@ function addClass(data){
} }
function addMessage(txt){ function addMessage(txt){
$('#messages').html(txt).show().delay(1000).fadeOut(); $('#messages').html(txt).show().delay(5000).fadeOut(5000);
} }
function addTile(x,y){ function addTile(x,y){
@ -61,8 +61,8 @@ function closeWindows(){
} }
function dropClass(data){ function dropClass(data){
parts = data.split(" "); var parts = data.split(" ");
$('#'+parts[0]).removeClass(parts[1]); for (var i=1; i<parts.length; i++) $('#'+parts[0]).removeClass(parts[i]);
} }
function enableAdding(ev){ function enableAdding(ev){

2
src/main/java/de/srsoftware/web4rail/Application.java

@ -61,7 +61,7 @@ public class Application {
} }
private static HashMap<String, String> inflate(String data) { private static HashMap<String, String> inflate(String data) {
LOG.debug("inflate({})",data); //LOG.debug("inflate({})",data);
HashMap<String, String> params = new HashMap<String, String>(); HashMap<String, String> params = new HashMap<String, String>();
if (data == null || data.trim().isEmpty()) return params; if (data == null || data.trim().isEmpty()) return params;
String[] parts = data.split("&"); String[] parts = data.split("&");

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

@ -154,7 +154,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) registerRoute(route); for (Route route : routes) {
route.complete();
registerRoute(route);
}
return t("Found {} routes.",routes.size()); return t("Found {} routes.",routes.size());
} }
@ -583,4 +586,8 @@ public class Plan {
Tile tile = get(x,y,true); Tile tile = get(x,y,true);
if (tile != null) set(x,y,tile.update(params)); if (tile != null) set(x,y,tile.update(params));
} }
public void warn(Contact contact) {
stream(t("Warning: {}",t("Ghost train @ {}",contact)));
}
} }

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

@ -15,6 +15,11 @@ import org.slf4j.LoggerFactory;
import de.keawe.tools.translations.Translation; import de.keawe.tools.translations.Translation;
import de.srsoftware.tools.Tag; import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.actions.ActivateRoute;
import de.srsoftware.web4rail.actions.FinishRoute;
import de.srsoftware.web4rail.actions.SetSignalsToStop;
import de.srsoftware.web4rail.actions.SpeedReduction;
import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tags.Form;
import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Block;
@ -36,10 +41,22 @@ 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 String id; private String id;
public Train train;
private Block startBlock = null,endBlock;
/**
* Route wurde von Zug betreten
*/
public void activate() {
LOG.debug("{} aktiviert.",this);
for (Tile tile : path) tile.occupy(this);
}
public Tile add(Tile tile, Direction direrction) { public Tile add(Tile tile, Direction direrction) {
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay(); if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
if (tile instanceof Block) endBlock = (Block) tile;
path.add(tile); path.add(tile);
if (tile instanceof Contact) contacts.add((Contact) tile); if (tile instanceof Contact) contacts.add((Contact) tile);
if (tile instanceof Signal) { if (tile instanceof Signal) {
@ -60,6 +77,8 @@ public class Route {
protected Route clone() { protected Route clone() {
Route clone = new Route(); Route clone = new Route();
clone.startBlock = startBlock;
clone.endBlock = endBlock;
clone.contacts = new Vector<Contact>(contacts); clone.contacts = new Vector<Contact>(contacts);
clone.signals = new Vector<Signal>(signals); clone.signals = new Vector<Signal>(signals);
clone.turnouts = new HashMap<>(turnouts); clone.turnouts = new HashMap<>(turnouts);
@ -67,6 +86,54 @@ public class Route {
return clone; return clone;
} }
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));
}
if (!contacts.isEmpty()) {
Contact lastContact = contacts.lastElement();
addAction(lastContact, new SpeedReduction(this, 0));
addAction(lastContact, new FinishRoute(this));
}
}
private void addAction(Object trigger, Action action) {
// TODO Auto-generated method stub
Vector<Action> actions = triggers.get(trigger);
if (actions == null) {
actions = new Vector<Action>();
triggers.put(trigger, actions);
}
actions.add(action);
}
public void finish() throws IOException {
startBlock.train(null);
endBlock.train(train);
unlock();
}
/**
* Kontakt der Route aktivieren
* @param contact
* @param train
*/
public void contact(Contact contact) {
LOG.debug("{} on {} activated {}.",train,this,contact);
Vector<Action> actions = triggers.get(contact);
for (Action action : actions) {
try {
action.fire();
} catch (IOException e) {
LOG.warn("Action did not fire properly: {}",action,e);
}
}
}
public String id() { public String id() {
if (id == null) { if (id == null) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -113,10 +180,11 @@ public class Route {
} }
public Route lock(Train train) throws IOException { public Route lock(Train train) throws IOException {
this.train = train;
for (Entry<Turnout, State> entry : turnouts.entrySet()) { for (Entry<Turnout, State> entry : turnouts.entrySet()) {
entry.getKey().state(entry.getValue()); entry.getKey().state(entry.getValue());
} }
for (Tile tile : path) tile.lock(train); for (Tile tile : path) tile.lock(this);
return this; return this;
} }
@ -194,6 +262,7 @@ public class Route {
signals = new Vector<Signal>(); signals = new Vector<Signal>();
path = new Vector<Tile>(); path = new Vector<Tile>();
turnouts = new HashMap<>(); turnouts = new HashMap<>();
startBlock = block;
path.add(block); path.add(block);
return this; return this;
} }
@ -222,7 +291,8 @@ public class Route {
return Translation.get(Application.class, txt, fills); return Translation.get(Application.class, txt, fills);
} }
public Route unlock() { public Route unlock() throws IOException {
setSignals(Signal.STOP);
for (Tile tile : path) tile.unlock(); for (Tile tile : path) tile.unlock();
return this; return this;
} }

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

@ -0,0 +1,12 @@
package de.srsoftware.web4rail.actions;
import java.io.IOException;
public abstract class Action {
public abstract void fire() throws IOException;
@Override
public String toString() {
return getClass().getSimpleName();
}
}

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

@ -0,0 +1,17 @@
package de.srsoftware.web4rail.actions;
import de.srsoftware.web4rail.Route;
public class ActivateRoute extends Action {
private Route route;
public ActivateRoute(Route route) {
this.route = route;
}
@Override
public void fire() {
route.activate();
}
}

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

@ -0,0 +1,20 @@
package de.srsoftware.web4rail.actions;
import java.io.IOException;
import de.srsoftware.web4rail.Route;
public class FinishRoute extends Action {
private Route route;
public FinishRoute(Route route) {
this.route = route;
}
@Override
public void fire() throws IOException {
route.finish();
}
}

21
src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java

@ -0,0 +1,21 @@
package de.srsoftware.web4rail.actions;
import java.io.IOException;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.tiles.Signal;
public class SetSignalsToStop extends Action {
private Route route;
public SetSignalsToStop(Route route) {
this.route = route;
}
@Override
public void fire() throws IOException {
route.setSignals(Signal.STOP);
}
}

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

@ -0,0 +1,21 @@
package de.srsoftware.web4rail.actions;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.moving.Train;
public class SpeedReduction extends Action {
private int maxSpeed;
private Route route;
public SpeedReduction(Route route, int kmh) {
this.route = route;
maxSpeed = kmh;
}
@Override
public void fire() {
Train train = route.train;
if (train != null && train.speed > maxSpeed) train.setSpeed(maxSpeed);
}
}

13
src/main/java/de/srsoftware/web4rail/moving/Train.java

@ -5,6 +5,9 @@ import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Vector; import java.util.Vector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.keawe.tools.translations.Translation; import de.keawe.tools.translations.Translation;
import de.srsoftware.tools.Tag; import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Application; import de.srsoftware.web4rail.Application;
@ -15,11 +18,13 @@ import de.srsoftware.web4rail.tiles.Signal;
import de.srsoftware.web4rail.tiles.Tile; import de.srsoftware.web4rail.tiles.Tile;
public class Train { public class Train {
private static final Logger LOG = LoggerFactory.getLogger(Train.class);
private Vector<Locomotive> locos = new Vector<Locomotive>(); private Vector<Locomotive> locos = new Vector<Locomotive>();
private Vector<Car> cars = new Vector<Car>(); private Vector<Car> cars = new Vector<Car>();
private String name = null; private String name = null;
private Block block = null; private Block block = null;
private Route route; private Route route;
public int speed = 0;
public Train(Locomotive loco) { public Train(Locomotive loco) {
add(loco); add(loco);
@ -53,6 +58,11 @@ public class Train {
return window; return window;
} }
public void setSpeed(int v) {
LOG.debug("Setting speed to {} kmh.",v);
this.speed = v;
}
public String start() throws IOException { public String start() throws IOException {
if (block == null) return t("{] not in a block",this); if (block == null) return t("{] not in a block",this);
HashSet<Route> routes = block.routes(); HashSet<Route> routes = block.routes();
@ -67,6 +77,7 @@ public class Train {
if (route != null) route.unlock().setSignals(Signal.STOP); if (route != null) route.unlock().setSignals(Signal.STOP);
int sel = rand.nextInt(availableRoutes.size()); int sel = rand.nextInt(availableRoutes.size());
route = availableRoutes.get(sel).lock(this).setSignals(null); route = availableRoutes.get(sel).lock(this).setSignals(null);
setSpeed(100);
return t("started {}",this); return t("started {}",this);
} }

14
src/main/java/de/srsoftware/web4rail/tiles/Block.java

@ -75,12 +75,22 @@ public abstract class Block extends StretchableTile{
return this; return this;
} }
public void train(Train train) { public void train(Train train) throws IOException {
this.train = train; this.train = train;
train.block(this); if (train != null) train.block(this);
plan.stream("place "+tag(null));
} }
public Train train() { public Train train() {
return train; return train;
} }
public void unlock() {
route = null;
classes.remove("locked");
if (train != null) {
classes.remove("occupied");
plan.stream("dropclass tile-"+x+"-"+y+" locked");
} else plan.stream("dropclass tile-"+x+"-"+y+" locked occupied");
}
} }

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

@ -21,6 +21,11 @@ public abstract class Contact extends Tile{
} catch (Exception e) {} } catch (Exception e) {}
} }
}.start(); }.start();
if (route == null) {
plan.warn(this);
} else {
route.contact(this);
}
} }

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

@ -21,7 +21,6 @@ import de.srsoftware.web4rail.Plan;
import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.Window; import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tags.Form;
public abstract class Tile { public abstract class Tile {
@ -31,7 +30,7 @@ public abstract class Tile {
protected HashSet<Shadow> shadows = new HashSet<>(); protected HashSet<Shadow> shadows = new HashSet<>();
private HashSet<Route> routes = new HashSet<>(); private HashSet<Route> routes = new HashSet<>();
protected Plan plan; protected Plan plan;
protected Train lockedBy; protected Route route;
protected static Logger LOG = LoggerFactory.getLogger(Tile.class); protected static Logger LOG = LoggerFactory.getLogger(Tile.class);
@ -71,12 +70,19 @@ public abstract class Tile {
return 1; return 1;
} }
public void lock(Train train) { public void lock(Route route) {
lockedBy = train; this.route = route;
classes.add("locked"); classes.add("locked");
plan.stream("addclass tile-"+x+"-"+y+" locked"); plan.stream("addclass tile-"+x+"-"+y+" locked");
}
public void occupy(Route route) {
this.route = route;
classes.add("occupied");
plan.stream("addclass tile-"+x+"-"+y+" occupied");
} }
public void plan(Plan plan) { public void plan(Plan plan) {
this.plan = plan; this.plan = plan;
} }
@ -194,9 +200,10 @@ public abstract class Tile {
} }
public void unlock() { public void unlock() {
lockedBy = null; route = null;
classes.remove("locked"); classes.remove("locked");
plan.stream("dropclass tile-"+x+"-"+y+" locked"); classes.remove("occupied");
plan.stream("dropclass tile-"+x+"-"+y+" locked occupied");
} }
public Tile update(HashMap<String, String> params) { public Tile update(HashMap<String, String> params) {

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

@ -5,8 +5,8 @@ import java.io.IOException;
public class TurnoutL extends Turnout { public class TurnoutL extends Turnout {
@Override @Override
public Object click() throws IOException { public Object click() throws IOException {
if (lockedBy != null) { if (route != null) {
plan.stream(t("{} is locked by {}!",this,lockedBy)); plan.stream(t("{} is locked by {}!",this,route));
} else { } else {
state = (state == State.STRAIGHT) ? State.LEFT : State.STRAIGHT; state = (state == State.STRAIGHT) ? State.LEFT : State.STRAIGHT;
plan.stream("place "+tag(null)); plan.stream("place "+tag(null));

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

@ -5,8 +5,8 @@ import java.io.IOException;
public class TurnoutR extends Turnout { public class TurnoutR extends Turnout {
@Override @Override
public Object click() throws IOException { public Object click() throws IOException {
if (lockedBy != null) { if (route != null) {
plan.stream(t("{} is locked by {}!",this,lockedBy)); plan.stream(t("{} is locked by {}!",this,route));
} else { } else {
state = (state == State.STRAIGHT) ? State.RIGHT : State.STRAIGHT; state = (state == State.STRAIGHT) ? State.RIGHT : State.STRAIGHT;
plan.stream("place "+tag(null)); plan.stream("place "+tag(null));

Loading…
Cancel
Save