From 9e36d5c0c802d61f5b005b586ac63d31cc07c45f Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sun, 20 Sep 2020 14:43:33 +0200 Subject: [PATCH] working on train movements --- resources/css/style.css | 5 ++ resources/js/plan.js | 6 +- .../de/srsoftware/web4rail/Application.java | 2 +- .../java/de/srsoftware/web4rail/Plan.java | 9 ++- .../java/de/srsoftware/web4rail/Route.java | 78 ++++++++++++++++++- .../srsoftware/web4rail/actions/Action.java | 12 +++ .../web4rail/actions/ActivateRoute.java | 17 ++++ .../web4rail/actions/FinishRoute.java | 20 +++++ .../web4rail/actions/SetSignalsToStop.java | 21 +++++ .../web4rail/actions/SpeedReduction.java | 21 +++++ .../de/srsoftware/web4rail/moving/Train.java | 13 +++- .../de/srsoftware/web4rail/tiles/Block.java | 14 +++- .../de/srsoftware/web4rail/tiles/Contact.java | 5 ++ .../de/srsoftware/web4rail/tiles/Tile.java | 19 +++-- .../srsoftware/web4rail/tiles/TurnoutL.java | 4 +- .../srsoftware/web4rail/tiles/TurnoutR.java | 4 +- 16 files changed, 228 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/srsoftware/web4rail/actions/Action.java create mode 100644 src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java create mode 100644 src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java create mode 100644 src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java create mode 100644 src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java diff --git a/resources/css/style.css b/resources/css/style.css index 6395904..d453432 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -44,6 +44,11 @@ svg.locked rect:not(.sig_a):not(.sig_b){ fill:lime; } +svg.occupied polygon, +svg.occupied rect:not(.sig_a):not(.sig_b){ + fill:yellow; +} + svg text{ font-size: 50px; } diff --git a/resources/js/plan.js b/resources/js/plan.js index e440ae5..72aa1c4 100644 --- a/resources/js/plan.js +++ b/resources/js/plan.js @@ -15,7 +15,7 @@ function addClass(data){ } function addMessage(txt){ - $('#messages').html(txt).show().delay(1000).fadeOut(); + $('#messages').html(txt).show().delay(5000).fadeOut(5000); } function addTile(x,y){ @@ -61,8 +61,8 @@ function closeWindows(){ } function dropClass(data){ - parts = data.split(" "); - $('#'+parts[0]).removeClass(parts[1]); + var parts = data.split(" "); + for (var i=1; i inflate(String data) { - LOG.debug("inflate({})",data); + //LOG.debug("inflate({})",data); HashMap params = new HashMap(); if (data == null || data.trim().isEmpty()) return params; String[] parts = data.split("&"); diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index 0ba9a80..4487348 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -154,7 +154,10 @@ public class Plan { for (HashMap column: tiles.values()) { 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()); } @@ -583,4 +586,8 @@ public class Plan { Tile tile = get(x,y,true); if (tile != null) set(x,y,tile.update(params)); } + + public void warn(Contact contact) { + stream(t("Warning: {}",t("Ghost train @ {}",contact))); + } } diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index 475568b..afaacb9 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -15,6 +15,11 @@ import org.slf4j.LoggerFactory; import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; 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.tags.Form; import de.srsoftware.web4rail.tiles.Block; @@ -36,10 +41,22 @@ public class Route { private Vector signals; private Vector contacts; private HashMap turnouts; + private HashMap> triggers = new HashMap>(); 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) { - 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); if (tile instanceof Contact) contacts.add((Contact) tile); if (tile instanceof Signal) { @@ -60,6 +77,8 @@ public class Route { protected Route clone() { Route clone = new Route(); + clone.startBlock = startBlock; + clone.endBlock = endBlock; clone.contacts = new Vector(contacts); clone.signals = new Vector(signals); clone.turnouts = new HashMap<>(turnouts); @@ -67,6 +86,54 @@ public class Route { 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 actions = triggers.get(trigger); + if (actions == null) { + actions = new Vector(); + 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 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() { if (id == null) { StringBuilder sb = new StringBuilder(); @@ -113,10 +180,11 @@ public class Route { } public Route lock(Train train) throws IOException { + this.train = train; for (Entry entry : turnouts.entrySet()) { entry.getKey().state(entry.getValue()); } - for (Tile tile : path) tile.lock(train); + for (Tile tile : path) tile.lock(this); return this; } @@ -194,6 +262,7 @@ public class Route { signals = new Vector(); path = new Vector(); turnouts = new HashMap<>(); + startBlock = block; path.add(block); return this; } @@ -222,7 +291,8 @@ public class Route { return Translation.get(Application.class, txt, fills); } - public Route unlock() { + public Route unlock() throws IOException { + setSignals(Signal.STOP); for (Tile tile : path) tile.unlock(); return this; } diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java new file mode 100644 index 0000000..48b9db8 --- /dev/null +++ b/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(); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java new file mode 100644 index 0000000..998a09c --- /dev/null +++ b/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(); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java new file mode 100644 index 0000000..f49ea90 --- /dev/null +++ b/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(); + } + +} diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java new file mode 100644 index 0000000..07c0052 --- /dev/null +++ b/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); + } + +} diff --git a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java new file mode 100644 index 0000000..a834124 --- /dev/null +++ b/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); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index e244a76..84d63a9 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -5,6 +5,9 @@ import java.util.HashSet; import java.util.Random; import java.util.Vector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; @@ -15,11 +18,13 @@ import de.srsoftware.web4rail.tiles.Signal; import de.srsoftware.web4rail.tiles.Tile; public class Train { + private static final Logger LOG = LoggerFactory.getLogger(Train.class); private Vector locos = new Vector(); private Vector cars = new Vector(); private String name = null; private Block block = null; - private Route route; + private Route route; + public int speed = 0; public Train(Locomotive loco) { add(loco); @@ -53,6 +58,11 @@ public class Train { return window; } + public void setSpeed(int v) { + LOG.debug("Setting speed to {} kmh.",v); + this.speed = v; + } + public String start() throws IOException { if (block == null) return t("{] not in a block",this); HashSet routes = block.routes(); @@ -67,6 +77,7 @@ public class Train { if (route != null) route.unlock().setSignals(Signal.STOP); int sel = rand.nextInt(availableRoutes.size()); route = availableRoutes.get(sel).lock(this).setSignals(null); + setSpeed(100); return t("started {}",this); } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index 4e5da96..805a1b3 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -75,12 +75,22 @@ public abstract class Block extends StretchableTile{ return this; } - public void train(Train train) { + public void train(Train train) throws IOException { this.train = train; - train.block(this); + if (train != null) train.block(this); + plan.stream("place "+tag(null)); } public Train 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"); + } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java index 3c5d032..13e8c19 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Contact.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Contact.java @@ -21,6 +21,11 @@ public abstract class Contact extends Tile{ } catch (Exception e) {} } }.start(); + if (route == null) { + plan.warn(this); + } else { + route.contact(this); + } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 84c22aa..55543d3 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/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.Route; import de.srsoftware.web4rail.Window; -import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.tags.Form; public abstract class Tile { @@ -31,7 +30,7 @@ public abstract class Tile { protected HashSet shadows = new HashSet<>(); private HashSet routes = new HashSet<>(); protected Plan plan; - protected Train lockedBy; + protected Route route; protected static Logger LOG = LoggerFactory.getLogger(Tile.class); @@ -71,12 +70,19 @@ public abstract class Tile { return 1; } - public void lock(Train train) { - lockedBy = train; + public void lock(Route route) { + this.route = route; classes.add("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) { this.plan = plan; } @@ -194,9 +200,10 @@ public abstract class Tile { } public void unlock() { - lockedBy = null; + route = null; 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 params) { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java index 07f405b..c59d8c7 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java @@ -5,8 +5,8 @@ import java.io.IOException; public class TurnoutL extends Turnout { @Override public Object click() throws IOException { - if (lockedBy != null) { - plan.stream(t("{} is locked by {}!",this,lockedBy)); + if (route != null) { + plan.stream(t("{} is locked by {}!",this,route)); } else { state = (state == State.STRAIGHT) ? State.LEFT : State.STRAIGHT; plan.stream("place "+tag(null)); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java index 3fb8bcb..46b08dc 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java @@ -5,8 +5,8 @@ import java.io.IOException; public class TurnoutR extends Turnout { @Override public Object click() throws IOException { - if (lockedBy != null) { - plan.stream(t("{} is locked by {}!",this,lockedBy)); + if (route != null) { + plan.stream(t("{} is locked by {}!",this,route)); } else { state = (state == State.STRAIGHT) ? State.RIGHT : State.STRAIGHT; plan.stream("place "+tag(null));