diff --git a/resources/css/style.css b/resources/css/style.css index fe2425a..90f6972 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -39,6 +39,11 @@ svg rect{ stroke:rgb(0,0,0); } +svg.locked polygon, +svg.locked rect{ + fill:lime; +} + svg text{ font-size: 50px; } diff --git a/resources/js/plan.js b/resources/js/plan.js index bb60d3b..4a0254d 100644 --- a/resources/js/plan.js +++ b/resources/js/plan.js @@ -9,6 +9,11 @@ const POST = 'POST'; var selected = null; var mode = null; +function addClass(data){ + parts = data.split(" "); + $('#'+parts[0]).addClass(parts[1]); +} + function addMessage(txt){ $('#messages').html(txt).show().delay(1000).fadeOut(); } @@ -55,6 +60,11 @@ function closeWindows(){ $('.window').remove(); } +function dropClass(data){ + parts = data.split(" "); + $('#'+parts[0]).removeClass(parts[1]); +} + function enableAdding(ev){ // console.log('enableAdding:',ev); if (selected != null) $(selected).css('border',''); @@ -143,7 +153,9 @@ function stream(ev){ 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)); - console.log(data); + if (data.startsWith("addclass")) return addClass(data.substring(9)); + if (data.startsWith("dropclass")) return dropClass(data.substring(10)); + console.log("received: ",data); } diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java index acf68aa..ab687a7 100644 --- a/src/main/java/de/srsoftware/web4rail/Application.java +++ b/src/main/java/de/srsoftware/web4rail/Application.java @@ -52,8 +52,8 @@ public class Application { plan = new Plan(); } Locomotive BR110 = new Locomotive("BR110"); - Block block = new Vector<>(plan.blocks()).firstElement(); - if (block != null) block.setTrain(new Train(BR110)); + Block block = new Vector<>(plan.blocks()).lastElement(); + if (block != null) block.train(new Train(BR110)); Desktop.getDesktop().browse(URI.create("http://localhost:"+config.getInt(PORT)+"/plan")); } diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index 2389476..4d72814 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -100,6 +100,7 @@ public class Plan { private static final String ROUTE = "route"; private static final HashMap clients = new HashMap(); private static final String ACTION_SHOW_TRAIN = "showTrain"; + private static final String ACTION_START_TRAIN = "startTrain"; private HashMap> tiles = new HashMap>(); private HashSet blocks = new HashSet(); @@ -378,7 +379,9 @@ public class Plan { case ACTION_SAVE: return saveTo(params.get(FILE)); case ACTION_SHOW_TRAIN: - return showTrain(get(params.get(X),params.get(Y),true)); + return show(train(get(params.get(X),params.get(Y),true))); + case ACTION_START_TRAIN: + return start(train(get(params.get(X),params.get(Y),true))); case ACTION_UPDATE: return update(params); default: @@ -392,6 +395,14 @@ public class Plan { } } + private Train train(Tile tile) { + if (tile instanceof Block) { + Block block = (Block) tile; + return block.train(); + } + return null; + } + private Object routeProperties(String routeId) { Route route = routes.get(routeId); if (route == null) return t("Could not find route \"{}\"",routeId); @@ -463,19 +474,20 @@ public class Plan { column = new HashMap(); tiles.put(x,column); } - column.put(y,tile.position(x, y)); + tile.position(x, y).plan(this); + column.put(y,tile); } - private Object showTrain(Tile tile) { - if (tile instanceof Block) { - Block block = (Block) tile; - Train train = block.train(); - if (train != null) return train.props(); - } - return null; + private Tag show(Train train) { + return (train == null) ? null : train.props(); + } + + private String start(Train train) { + if (train == null) return null; + return train.start(); } - private synchronized void stream(String data) { + public synchronized void stream(String data) { data = data.replaceAll("\n", "").replaceAll("\r", ""); LOG.debug("streaming: {}",data); Vector badClients = null; diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index 1d31dd4..58bad48 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -14,6 +14,7 @@ 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.moving.Train; import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Contact; @@ -82,6 +83,11 @@ public class Route { } return id; } + + public boolean inUse() { + return false; + } + public String json() { JSONObject props = new JSONObject(); @@ -105,6 +111,10 @@ public class Route { return props.toString(); } + public Route lock(Train train) { + for (Tile tile : path) tile.lock(train); + return this; + } public List multiply(int size) { Vector routes = new Vector(); @@ -203,6 +213,10 @@ public class Route { return Translation.get(Application.class, txt, fills); } + public void unlock() { + for (Tile tile : path) tile.unlock(); + } + public void update(HashMap params) { LOG.debug("update({})",params); if (params.containsKey(NAME)) name(params.get(NAME)); diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index 892ca2f..6922b61 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -1,16 +1,23 @@ package de.srsoftware.web4rail.moving; +import java.util.HashSet; +import java.util.Random; import java.util.Vector; import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; +import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.tiles.Block; +import de.srsoftware.web4rail.tiles.Tile; public class Train { private Vector locos = new Vector(); private Vector cars = new Vector(); private String name = null; + private Block block = null; + private Route route; public Train(Locomotive loco) { add(loco); @@ -43,4 +50,25 @@ public class Train { private String t(String message, Object...fills) { return Translation.get(Application.class, message, fills); } + + public void block(Block block) { + this.block = block; + } + + public String start() { + if (block == null) return t("{] not in a block",this); + HashSet routes = block.routes(); + Vector availableRoutes = new Vector(); + for (Route route : routes) { + Vector path = route.path(); + if (path.firstElement() != block) continue; + if (route.inUse()) continue; + availableRoutes.add(route); + } + Random rand = new Random(); + if (route != null) route.unlock(); + int sel = rand.nextInt(availableRoutes.size()); + route = availableRoutes.get(sel).lock(this); + 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 e93fbd4..0be4913 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -73,8 +73,9 @@ public abstract class Block extends StretchableTile{ return this; } - public void setTrain(Train train) { + public void train(Train train) { this.train = train; + train.block(this); } public Train train() { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 73c24f9..aba676f 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -17,10 +17,12 @@ import de.keawe.tools.translations.Translation; import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Application; import de.srsoftware.web4rail.Connector; +import de.srsoftware.web4rail.Plan; import de.srsoftware.web4rail.Plan.Direction; import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.moving.Train; public abstract class Tile { @@ -28,6 +30,8 @@ public abstract class Tile { protected HashSet classes = new HashSet<>(); protected HashSet shadows = new HashSet<>(); private HashSet routes = new HashSet<>(); + private Plan plan; + private Train lockedBy; protected static Logger LOG = LoggerFactory.getLogger(Tile.class); @@ -36,6 +40,10 @@ public abstract class Tile { classes.add(getClass().getSimpleName()); } + public void add(Route route) { + this.routes.add(route); + } + public void addShadow(Shadow shadow) { shadows.add(shadow); } @@ -59,6 +67,15 @@ public abstract class Tile { return 1; } + public void lock(Train train) { + lockedBy = train; + plan.stream("addclass tile-"+x+"-"+y+" locked"); + } + + public void plan(Plan plan) { + this.plan = plan; + } + public Tile position(int x, int y) { this.x = x; this.y = y; @@ -95,6 +112,29 @@ public abstract class Tile { return window; } + private static String replace(String line, Entry replacement) { + String key = replacement.getKey(); + Object val = replacement.getValue(); + int start = line.indexOf(key); + int len = key.length(); + while (start>0) { + int end = line.indexOf("\"",start); + int end2 = line.indexOf("<",start); + if (end2>0 && (end<0 || end2len) { + val = Integer.parseInt(tag.substring(len)) + (int) val; + } + line = line.replace(tag, ""+val); + start = line.indexOf(key); + } + return line; + } + + public HashSet routes() { + return routes; + } + public Tag tag(Map replacements) throws IOException { int width = 100*len(); int height = 100*height(); @@ -138,24 +178,6 @@ public abstract class Tile { return svg; } - private static String replace(String line, Entry replacement) { - String key = replacement.getKey(); - Object val = replacement.getValue(); - int start = line.indexOf(key); - int len = key.length(); - while (start>0) { - int end = line.indexOf("\"",start); - int end2 = line.indexOf("<",start); - if (end2>0 && (end<0 || end2len) { - val = Integer.parseInt(tag.substring(len)) + (int) val; - } - line = line.replace(tag, ""+val); - start = line.indexOf(key); - } - return line; - } protected static String t(String txt, Object...fills) { return Translation.get(Application.class, txt, fills); @@ -166,16 +188,13 @@ public abstract class Tile { return t("{}({},{})",getClass().getSimpleName(),x,y) ; } + public void unlock() { + lockedBy = null; + plan.stream("dropclass tile-"+x+"-"+y+" locked"); + } + public Tile update(HashMap params) { LOG.debug("{}.update({})",getClass().getSimpleName(),params); return this; } - - public HashSet routes() { - return routes; - } - - public void add(Route route) { - this.routes.add(route); - } }