working on train movements
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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("&");
|
||||||
|
|||||||
@@ -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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
Normal file
12
src/main/java/de/srsoftware/web4rail/actions/Action.java
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user