From daae49296ffb6a117b8ba71c8379a9f543953a86 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 29 Oct 2020 11:41:10 +0100 Subject: [PATCH] bugfixes, improved action framework, added actions --- pom.xml | 2 +- .../java/de/srsoftware/web4rail/Plan.java | 9 ++- .../java/de/srsoftware/web4rail/Route.java | 22 +++--- .../srsoftware/web4rail/actions/Action.java | 23 ++++++- .../web4rail/actions/ActivateRoute.java | 7 +- .../web4rail/actions/FinishRoute.java | 6 +- .../web4rail/actions/RouteAction.java | 12 ---- .../web4rail/actions/SetSignalsToStop.java | 6 +- .../web4rail/actions/SpeedReduction.java | 6 +- .../web4rail/actions/TurnTrain.java | 7 +- .../de/srsoftware/web4rail/moving/Train.java | 69 ++++++++++--------- .../de/srsoftware/web4rail/tags/Button.java | 6 +- .../de/srsoftware/web4rail/tags/Form.java | 5 +- .../de/srsoftware/web4rail/tiles/Block.java | 11 ++- .../web4rail/tiles/StretchableTile.java | 4 +- .../de/srsoftware/web4rail/tiles/Tile.java | 9 +-- .../de/srsoftware/web4rail/tiles/Turnout.java | 4 +- .../srsoftware/web4rail/tiles/TurnoutL.java | 4 +- .../srsoftware/web4rail/tiles/TurnoutR.java | 4 +- 19 files changed, 115 insertions(+), 101 deletions(-) diff --git a/pom.xml b/pom.xml index 5b26fc7..a8c0be6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.7.5 + 0.7.6 Web4Rail jar Java Model Railway Control diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java index 9e46b43..2000f6d 100644 --- a/src/main/java/de/srsoftware/web4rail/Plan.java +++ b/src/main/java/de/srsoftware/web4rail/Plan.java @@ -118,8 +118,7 @@ public class Plan implements Constants{ case ACTION_SAVE: return saveTo("default"); case ACTION_UPDATE: - update(get(params.get(Tile.ID),true),params); - return html(); + return update(get(params.get(Tile.ID),true),params); } return t("Unknown action: {}",params.get(ACTION)); } @@ -170,7 +169,7 @@ public class Plan implements Constants{ this.routes.clear(); for (Tile tile : tiles.values()) tile.routes().clear(); for (Route route : routes) { - route.complete(); + route.complete(this); registerRoute(route); } return t("Found {} routes.",routes.size()); @@ -524,8 +523,8 @@ public class Plan implements Constants{ return tiles.addTo(tileMenu); } - private void update(Tile tile, HashMap params) throws IOException { - if (tile != null) place(tile.update(params)); + private Tile update(Tile tile, HashMap params) throws IOException { + return tile == null ? null : tile.update(params); } public void warn(Contact contact) { diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index 27ba98a..5ff3cca 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -24,6 +24,7 @@ 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.Action.Context; import de.srsoftware.web4rail.actions.ActivateRoute; import de.srsoftware.web4rail.actions.FinishRoute; import de.srsoftware.web4rail.actions.SetSignalsToStop; @@ -172,26 +173,26 @@ public class Route implements Constants{ Tag list = new Tag("ul"); for (Contact c : contacts) { Tag link = Plan.addLink(c,c.toString(),list); - JSONObject json = new JSONObject(Map.of( + Map props = new HashMap(Map.of( REALM,REALM_ROUTE, ID,id, ACTION,ACTION_ADD_ACTION, CONTACT,c.id())); - new Button(t("add action"),json).addTo(link); + new Button(t("add action"),props).addTo(link); Vector actions = triggers.get(c.trigger()); if (actions != null && !actions.isEmpty()) { Tag ul = new Tag("ul"); boolean first = true; for (Action action : actions) { - json.put(ACTION_ID, action.toString()); + props.put(ACTION_ID, action.toString()); Tag act = new Tag("li").content(action.toString()); if (!first) { - json.put(ACTION, ACTION_MOVE); - new Button("↑",json).addTo(act); + props.put(ACTION, ACTION_MOVE); + new Button("↑",props).addTo(act); } - json.put(ACTION, ACTION_DROP); - new Button("-",json).addTo(act); + props.put(ACTION, ACTION_DROP); + new Button("-",props).addTo(act); act.addTo(ul); first = false; } @@ -249,7 +250,8 @@ public class Route implements Constants{ return clone; } - public void complete() { + public void complete(Plan plan) { + this.plan = plan; if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein addAction(contacts.firstElement().trigger(),new ActivateRoute(id())); Contact nextToLastContact = contacts.get(contacts.size()-2); @@ -272,9 +274,11 @@ public class Route implements Constants{ LOG.debug("{} on {} activated {}.",train,this,contact); Vector actions = triggers.get(contact.trigger()); if (actions == null) return; + LOG.debug("Triggering {}",actions); + Context context = new Context(contact); for (Action action : actions) { try { - action.fire(contact.plan()); + action.fire(context); } catch (IOException e) { LOG.warn("Action did not fire properly: {}",action,e); } diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java index 913be8c..bb80697 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/Action.java +++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java @@ -5,17 +5,38 @@ import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import de.keawe.tools.translations.Translation; import de.srsoftware.web4rail.Application; import de.srsoftware.web4rail.Plan; +import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.moving.Train; +import de.srsoftware.web4rail.tiles.Contact; public abstract class Action { + public static final Logger LOG = LoggerFactory.getLogger(Action.class); private static final String TYPE = "type"; - public abstract void fire(Plan plan) throws IOException; + public static class Context { + public Plan plan = null; + public Contact contact = null; + public Route route = null; + public Train train = null; + + public Context(Contact c) { + contact = c; + route = contact.route(); + if (route == null) return; + train = route.train; + } + } + + public abstract void fire(Context context) throws IOException; + public JSONObject json() { JSONObject json = new JSONObject(); json.put(TYPE, getClass().getSimpleName()); diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java index b3095ef..05332dd 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java +++ b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java @@ -2,17 +2,14 @@ package de.srsoftware.web4rail.actions; import java.io.IOException; -import de.srsoftware.web4rail.Route; - public class ActivateRoute extends RouteAction { - public ActivateRoute(int routeId) { super(routeId); } @Override - public void fire(Route route) throws IOException { - route.activate(); + public void fire(Context context) throws IOException { + context.route.activate(); } } diff --git a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java index 01d4a67..1967ce5 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java +++ b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java @@ -2,8 +2,6 @@ package de.srsoftware.web4rail.actions; import java.io.IOException; -import de.srsoftware.web4rail.Route; - public class FinishRoute extends RouteAction { public FinishRoute(int routeId) { @@ -11,7 +9,7 @@ public class FinishRoute extends RouteAction { } @Override - public void fire(Route route) throws IOException { - route.finish(); + public void fire(Context context) throws IOException { + context.route.finish(); } } diff --git a/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java b/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java index 7e79a8d..758d973 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java +++ b/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java @@ -1,12 +1,7 @@ package de.srsoftware.web4rail.actions; -import java.io.IOException; - import org.json.JSONObject; -import de.srsoftware.web4rail.Plan; -import de.srsoftware.web4rail.Route; - public abstract class RouteAction extends Action { static final String ROUTE = "route"; @@ -22,11 +17,4 @@ public abstract class RouteAction extends Action { json.put(ROUTE, routeId); return json; } - - @Override - public void fire(Plan plan) throws IOException { - fire(plan.route(routeId)); - } - - protected abstract void fire(Route route) throws IOException; } diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java index 648099b..bc6cacd 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java @@ -2,18 +2,16 @@ package de.srsoftware.web4rail.actions; import java.io.IOException; -import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.tiles.Signal; public class SetSignalsToStop extends RouteAction { - public SetSignalsToStop(int routeId) { super(routeId); } @Override - public void fire(Route route) throws IOException { - route.setSignals(Signal.STOP); + public void fire(Context context) throws IOException { + context.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 index e3f5c3c..559fce2 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java @@ -8,7 +8,6 @@ import de.srsoftware.tools.Tag; import de.srsoftware.web4rail.Constants; import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Window; -import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tags.Input; @@ -26,9 +25,8 @@ public class SpeedReduction extends RouteAction implements Constants{ } @Override - public void fire(Route route) { - Train train = route.train; - if (train != null && train.speed > maxSpeed) train.setSpeed(maxSpeed); + public void fire(Context context) { + if (context.train != null && context.train.speed > maxSpeed) context.train.setSpeed(maxSpeed); } @Override diff --git a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java index a637f01..241fc1f 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java +++ b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java @@ -1,8 +1,6 @@ package de.srsoftware.web4rail.actions; import de.srsoftware.web4rail.Constants; -import de.srsoftware.web4rail.Route; -import de.srsoftware.web4rail.moving.Train; public class TurnTrain extends RouteAction implements Constants{ @@ -11,8 +9,7 @@ public class TurnTrain extends RouteAction implements Constants{ } @Override - public void fire(Route route) { - Train train = route.train; - if (train != null) train.turn(); + public void fire(Context context) { + if (context.train != null) context.train.turn(); } } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index a435baa..f0666a5 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Vector; @@ -33,9 +34,7 @@ import de.srsoftware.web4rail.tags.Input; import de.srsoftware.web4rail.tags.Label; import de.srsoftware.web4rail.tags.Select; import de.srsoftware.web4rail.tiles.Block; -import de.srsoftware.web4rail.tiles.Contact; import de.srsoftware.web4rail.tiles.Signal; -import de.srsoftware.web4rail.tiles.Tile; public class Train implements Constants { private static final Logger LOG = LoggerFactory.getLogger(Train.class); @@ -73,18 +72,11 @@ public class Train implements Constants { public void run() { try { stop = false; - Vector path = new Vector(); while (true) { if (route == null) { Thread.sleep(2000); if (stop) return; Train.this.start(); - path = route == null ? new Vector() : route.path(); - } else { - if (!path.isEmpty()) { - Tile t = path.remove(0); - if (t instanceof Contact) ((Contact)t).activate(); - } } Thread.sleep(250); } @@ -189,6 +181,10 @@ public class Train implements Constants { return t("{} now in auto-mode",this); } + public Block block() { + return block; + } + public void block(Block block) throws IOException { this.block = block; } @@ -259,6 +255,32 @@ public class Train implements Constants { return this; } + private Tag locoList() { + Tag locoProp = new Tag("li").content(t("Locomotives:")); + Tag locoList = new Tag("ul").clazz("locolist"); + + for (Locomotive loco : this.locos) { + Tag li = loco.link("li"); + Map props = Map.of(REALM,REALM_LOCO,ID,loco.id(),ACTION,ACTION_TURN); + new Button(t("turn within train"),props).addTo(li).addTo(locoList); + } + + Tag addLocoForm = new Form().content(t("add locomotive:")+" "); + new Input(REALM, REALM_TRAIN).hideIn(addLocoForm); + new Input(ACTION, ACTION_ADD).hideIn(addLocoForm); + new Input(ID,id).hideIn(addLocoForm); + Select select = new Select(CAR_ID); + for (Locomotive loco : Locomotive.list()) { + if (!this.locos.contains(loco)) select.addOption(loco.id(), loco); + } + if (!select.children().isEmpty()) { + select.addTo(addLocoForm); + new Button(t("add")).addTo(addLocoForm); + addLocoForm.addTo(new Tag("li")).addTo(locoList); + } + return locoList.addTo(locoProp); + } + public static Object manager() { Window win = new Window("train-manager", t("Train manager")); new Tag("h4").content(t("known trains")).addTo(win); @@ -307,7 +329,7 @@ public class Train implements Constants { public Tag props() { Window window = new Window("train-properties",t("Properties of {}",this)); - Fieldset fieldset = new Fieldset(t("Train properties")); + Fieldset fieldset = new Fieldset(t("editable train properties")); Form form = new Form(); new Input(ACTION,ACTION_UPDATE).hideIn(form); new Input(REALM,REALM_TRAIN).hideIn(form); @@ -318,27 +340,11 @@ public class Train implements Constants { new Button(t("Turn"), "train("+id+",'"+ACTION_TURN+"')").addTo(fieldset).addTo(window); + fieldset = new Fieldset(t("other train properties")); + Tag propList = new Tag("ul").clazz("proplist"); - Tag locoProp = new Tag("li").content(t("Locomotives:")); - Tag locoList = new Tag("ul").clazz("locolist"); - - for (Locomotive loco : this.locos) loco.link("li").addTo(locoList); - - Tag addLocoForm = new Form().content(t("add locomotive:")+" "); - new Input(REALM, REALM_TRAIN).hideIn(addLocoForm); - new Input(ACTION, ACTION_ADD).hideIn(addLocoForm); - new Input(ID,id).hideIn(addLocoForm); - Select select = new Select(CAR_ID); - for (Locomotive loco : Locomotive.list()) { - if (!this.locos.contains(loco)) select.addOption(loco.id(), loco); - } - if (!select.children().isEmpty()) { - select.addTo(addLocoForm); - new Button(t("add")).addTo(addLocoForm); - addLocoForm.addTo(new Tag("li")).addTo(locoList); - } - locoList.addTo(locoProp).addTo(propList); + locoList().addTo(propList); if (block != null) { new Tag("li").content(t("Current location: {}",block)).addTo(propList); @@ -358,10 +364,10 @@ public class Train implements Constants { if (direction != null) new Tag("li").content(t("Direction: heading {}",direction)).addTo(propList); - propList.addTo(window); + propList.addTo(fieldset).addTo(window); return window; } - + private Object quitAutopilot() { if (autopilot != null) { autopilot.stop = true; @@ -424,6 +430,7 @@ public class Train implements Constants { } private Object stopNow() { + quitAutopilot(); setSpeed(0); if (route != null) try { route.unlock(); diff --git a/src/main/java/de/srsoftware/web4rail/tags/Button.java b/src/main/java/de/srsoftware/web4rail/tags/Button.java index 4a76200..f513ee1 100644 --- a/src/main/java/de/srsoftware/web4rail/tags/Button.java +++ b/src/main/java/de/srsoftware/web4rail/tags/Button.java @@ -1,5 +1,7 @@ package de.srsoftware.web4rail.tags; +import java.util.Map; + import org.json.JSONObject; import de.srsoftware.tools.Tag; @@ -20,8 +22,8 @@ public class Button extends Tag { attr("onclick",action).content(text); } - public Button(String text,JSONObject json) { + public Button(String text, Map props) { super("button"); - attr("onclick","request("+(json.toString().replace("\"", "'"))+")").content(text); + attr("onclick","request("+(new JSONObject(props).toString().replace("\"", "'"))+")").content(text); } } diff --git a/src/main/java/de/srsoftware/web4rail/tags/Form.java b/src/main/java/de/srsoftware/web4rail/tags/Form.java index cd768bb..50d1941 100644 --- a/src/main/java/de/srsoftware/web4rail/tags/Form.java +++ b/src/main/java/de/srsoftware/web4rail/tags/Form.java @@ -8,13 +8,12 @@ public class Form extends Tag { public Form() { - super("form"); - attr("method","POST"); + this(null); } public Form(String id) { super("form"); attr("method","POST"); - id(id); + if (id!=null) id(id); } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index bc9a2f3..fca4d5c 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -58,8 +58,8 @@ public abstract class Block extends StretchableTile{ } @Override - public Tag propForm() { - Tag form = super.propForm(); + public Tag propForm(String id) { + Tag form = super.propForm(id); new Input(NAME, name).addTo(new Label(t("name:")+" ")).addTo(new Tag("p")).addTo(form); @@ -119,7 +119,12 @@ public abstract class Block extends StretchableTile{ if (params.containsKey(NAME)) name=params.get(NAME); if (params.containsKey(TRAIN)) { long trainId = Long.parseLong(params.get(TRAIN)); - train(trainId == 0 ? null : Train.get(trainId)); + Train t = Train.get(trainId); + if (t != null) { + Block oldBlock = t.block(); + if (oldBlock != null) oldBlock.train(null); + train(t); + } } turnAllowed = params.containsKey(ALLOW_TURN) && params.get(ALLOW_TURN).equals("on"); return this; diff --git a/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java b/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java index aecbe77..68574b5 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/StretchableTile.java @@ -34,8 +34,8 @@ public abstract class StretchableTile extends Tile { } @Override - public Tag propForm() { - Tag form = super.propForm(); + public Tag propForm(String id) { + Tag form = super.propForm(id); Tag label = new Tag("label").content(t("length:")); new Tag("input").attr("type", "number").attr("name","length").attr("value", length).addTo(label); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 97d0425..e06a4d1 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -180,8 +180,8 @@ public abstract class Tile implements Constants{ return new Vector(); } - public Tag propForm() { - Form form = new Form(); + public Tag propForm(String id) { + Form form = new Form(id); new Input(ACTION, ACTION_UPDATE).hideIn(form); new Input(REALM, REALM_PLAN).hideIn(form); new Input(ID,id()).hideIn(form); @@ -199,9 +199,10 @@ public abstract class Tile implements Constants{ public Tag propMenu() { Window window = new Window("tile-properties",t("Properties of {} @ ({},{})",getClass().getSimpleName(),x,y)); - Tag form = propForm(); + String formId = "tile-properties-"+id(); + Tag form = propForm(formId); if (form!=null && form.children().size()>3) { - new Button(t("save")).addTo(form); + new Button(t("save"),"submitForm('"+formId+"')").addTo(form); form.addTo(window); } else { window.content(t("This tile ({}) has no editable properties",getClass().getSimpleName())); diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java index edb9c28..d42213c 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java @@ -101,8 +101,8 @@ public abstract class Turnout extends Tile implements Device{ } @Override - public Tag propForm() { - Tag form = super.propForm(); + public Tag propForm(String id) { + Tag form = super.propForm(id); Fieldset fieldset = new Fieldset(t("Decoder settings")); Label protocol = new Label(t("Protocol:")); for (Protocol proto : Protocol.values()) { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java index 34b0e07..2a630f7 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutL.java @@ -34,8 +34,8 @@ public class TurnoutL extends Turnout { } @Override - public Tag propForm() { - Tag form = super.propForm(); + public Tag propForm(String id) { + Tag form = super.propForm(id); Tag fieldset = null; for (Tag child : form.children()) { if (child.is(Fieldset.TYPE)) { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java index 21489ff..6c46e90 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/TurnoutR.java @@ -35,8 +35,8 @@ public class TurnoutR extends Turnout { } @Override - public Tag propForm() { - Tag form = super.propForm(); + public Tag propForm(String id) { + Tag form = super.propForm(id); Tag fieldset = null; for (Tag child : form.children()) { if (child.is(Fieldset.TYPE)) {