From ce00d2118414a52ea879edd5fe7ea5a35121a5b3 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Fri, 30 Oct 2020 12:35:04 +0100 Subject: [PATCH] implemented conditions on routes --- pom.xml | 2 +- resources/css/style.css | 2 +- .../translations/Application.de.translation | 1 + .../java/de/srsoftware/web4rail/Route.java | 81 +++++++++++++++++-- .../srsoftware/web4rail/actions/Action.java | 4 + .../web4rail/actions/ActionList.java | 5 +- .../web4rail/actions/ConditionalAction.java | 6 +- .../srsoftware/web4rail/actions/SetSpeed.java | 5 +- .../web4rail/conditions/Condition.java | 11 ++- .../de/srsoftware/web4rail/moving/Train.java | 3 + .../de/srsoftware/web4rail/tags/Button.java | 4 + 11 files changed, 102 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index ebf15e0..1ce2b5a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.8.2 + 0.8.3 Web4Rail jar Java Model Railway Control diff --git a/resources/css/style.css b/resources/css/style.css index e8bb375..bc0ad7f 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -222,4 +222,4 @@ ul{ .menu div.emergency{ background: #ffb561; -} \ No newline at end of file +} diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index 9f53c17..4512068 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -3,6 +3,7 @@ Added {} : {} hinzugefügt Add tile : Kachel hinzufügen Analyze plan : Plan analysieren Apply : Übernehmen +Conditions : Bedingungen Contacts and actions : Kontakte und Aktionen Destination\: {} from {} : Ziel: {} von {} length\: : Länge: diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index bf07d6f..cdfee0a 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -28,9 +28,13 @@ import de.srsoftware.web4rail.actions.ActivateRoute; import de.srsoftware.web4rail.actions.FinishRoute; import de.srsoftware.web4rail.actions.SetSignalsToStop; import de.srsoftware.web4rail.actions.SetSpeed; +import de.srsoftware.web4rail.conditions.Condition; +import de.srsoftware.web4rail.conditions.TrainSelect; import de.srsoftware.web4rail.moving.Train; +import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Select; import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Contact; import de.srsoftware.web4rail.tiles.Shadow; @@ -62,6 +66,7 @@ public class Route implements Constants{ private Block startBlock = null,endBlock; private static final String START_DIRECTION = "direction_start"; private static final String END_DIRECTION = "direction_end"; + private Vector conditions = new Vector(); public Direction startDirection; private Direction endDirection; @@ -70,6 +75,7 @@ public class Route implements Constants{ private static final String ACTIONS = "actions"; private static final String ACTION_LISTS = "action_lists"; private static final String ROUTES = "routes"; + private static final String CONDITIONS = "conditions"; /** * process commands from the client @@ -81,11 +87,10 @@ public class Route implements Constants{ Route route = plan.route(Integer.parseInt(params.get(ID))); if (route == null) return t("Unknown route: {}",params.get(ID)); switch (params.get(ACTION)) { + case ACTION_UPDATE: + return route.update(params); case ACTION_PROPS: return route.properties(); - case ACTION_UPDATE: - route.update(params); - return plan.html(); } return t("Unknown action: {}",params.get(ACTION)); } @@ -150,6 +155,33 @@ public class Route implements Constants{ } } + private void addCondition(String type) { + switch (type) { + case "TrainSelect": + conditions.add(new TrainSelect()); + } + } + + private void addConditionsTo(Window win) { + new Tag("h4").content(t("Conditions")).addTo(win); + if (!conditions.isEmpty()) { + Tag list = new Tag("ul"); + for (Condition condition : conditions) condition.link("li",REALM_ROUTE+":"+id).addTo(list); + list.addTo(win); + } + + Form form = new Form("action-prop-form-"+id); + new Input(REALM,REALM_ROUTE).hideIn(form); + new Input(ID,id()).hideIn(form); + new Input(ACTION,ACTION_UPDATE).hideIn(form); + + Select select = new Select(REALM_CONDITION); + List> classes = List.of(TrainSelect.class); + for (Class clazz : classes) select.addOption(clazz.getSimpleName()); + select.addTo(form); + new Button(t("Add condition"),form).addTo(form).addTo(win); + } + private void addContactsTo(Window win) { if (!contacts.isEmpty()) { new Tag("h4").content(t("Contacts and actions")).addTo(win); @@ -168,7 +200,7 @@ public class Route implements Constants{ } private void addFormTo(Window win) { - Form form = new Form(); + Form form = new Form("route-"+id+"-props"); new Input(ACTION, ACTION_UPDATE).hideIn(form); new Input(REALM,REALM_ROUTE).hideIn(form); new Input(ID,id()).hideIn(form); @@ -177,8 +209,7 @@ public class Route implements Constants{ new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).style("width: 80%").addTo(label); label.addTo(form); - new Tag("button").attr("type", "submit").content(t("Apply")).addTo(form); - form.addTo(win); + new Button(t("Apply"),form).addTo(form).addTo(win); } void addSignal(Signal signal) { @@ -201,6 +232,18 @@ public class Route implements Constants{ } } + /** + * checks, whether the route may be used in a given context + * @param context + * @return false, if any of the associated conditions is not fulfilled + */ + public boolean allowed(Context context) { + for (Condition condition : conditions) { + if (!condition.fulfilledBy(context)) return false; + } + return true; + } + protected Route clone() { Route clone = new Route(); clone.startBlock = startBlock; @@ -309,6 +352,10 @@ public class Route implements Constants{ json.put(START_DIRECTION, startDirection); json.put(END_DIRECTION, endDirection); + JSONArray jConditions = new JSONArray(); + for (Condition condition : conditions) jConditions.put(condition.json()); + if (!jConditions.isEmpty()) json.put(CONDITIONS, jConditions); + JSONArray jTriggers = new JSONArray(); for (Entry entry : triggers.entrySet()) { JSONObject trigger = new JSONObject(); @@ -355,6 +402,7 @@ public class Route implements Constants{ for (Object signalId : json.getJSONArray(SIGNALS)) addSignal((Signal) plan.get((String) signalId, false)); } if (json.has(ACTION_LISTS)) loadActions(json.getJSONArray(ACTION_LISTS)); + if (json.has(CONDITIONS)) loadConditions(json.getJSONArray(CONDITIONS)); return plan.registerRoute(this); } @@ -379,6 +427,14 @@ public class Route implements Constants{ LOG.debug("json: {}",json.getClass()); } + private void loadConditions(JSONArray arr) { + for (int i=0; i lockedTiles = new ArrayList(); try { @@ -424,6 +480,7 @@ public class Route implements Constants{ addFormTo(win); addBasicPropertiesTo(win); addTurnoutsTo(win); + addConditionsTo(win); addContactsTo(win); return win; @@ -508,8 +565,16 @@ public class Route implements Constants{ return this; } - public void update(HashMap params) { + public Object update(HashMap params) { LOG.debug("update({})",params); - if (params.containsKey(NAME)) name(params.get(NAME)); + String name = params.get(NAME); + if (name != null) name(name); + + String condition = params.get(REALM_CONDITION); + if (condition != null) { + addCondition(condition); + return properties(); + } + return t("{} updated.",this); } } diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java index b3ded0d..4edfad8 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/Action.java +++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java @@ -34,6 +34,10 @@ public abstract class Action implements Constants { if (route == null) return; train = route.train; } + + public Context(Train train) { + this.train = train; + } } public Action() { diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java index 7436e8e..5d2921a 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java +++ b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java @@ -50,8 +50,7 @@ public class ActionList extends Vector implements Constants{ } private Object actionTypeForm(Window win, String context) { - String formId ="add-action-to-"+id; - Tag typeForm = new Form(formId); + Form typeForm = new Form("add-action-to-"+id); new Input(REALM, REALM_ACTIONS).hideIn(typeForm); new Input(ID,id).hideIn(typeForm); new Input(ACTION,ACTION_ADD).hideIn(typeForm); @@ -68,7 +67,7 @@ public class ActionList extends Vector implements Constants{ ); for (Class clazz : classes) select.addOption(clazz.getSimpleName()); select.addTo(new Label("Action type:")).addTo(typeForm); - return new Button(t("Create action"),"return submitForm('"+formId+"');").addTo(typeForm).addTo(win); + return new Button(t("Create action"),typeForm).addTo(typeForm).addTo(win); } private Object addActionForm(HashMap params, Plan plan) { diff --git a/src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java b/src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java index ed547a5..f2b78b9 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java +++ b/src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java @@ -43,8 +43,8 @@ public class ConditionalAction extends Action { for (Condition condition : conditions) condition.link("li",params.get(CONTEXT)).addTo(list); list.addTo(fieldset); } - String formId = "action-prop-form-"+id; - Form form = new Form(formId); + + Form form = new Form("action-prop-form-"+id); new Input(REALM,REALM_ACTIONS).hideIn(form); new Input(ID,params.get(ID)).hideIn(form); new Input(ACTION,ACTION_UPDATE).hideIn(form); @@ -54,7 +54,7 @@ public class ConditionalAction extends Action { List> classes = List.of(TrainSelect.class); for (Class clazz : classes) select.addOption(clazz.getSimpleName()); select.addTo(form); - return new Button(t("Add condition"),"return submitForm('"+formId+"');").addTo(form).addTo(fieldset); + return new Button(t("Add condition"),form).addTo(form).addTo(fieldset); } @Override diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetSpeed.java b/src/main/java/de/srsoftware/web4rail/actions/SetSpeed.java index b6be90b..ab849ae 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/SetSpeed.java +++ b/src/main/java/de/srsoftware/web4rail/actions/SetSpeed.java @@ -45,8 +45,7 @@ public class SetSpeed extends Action{ @Override public Window properties(HashMap params) { Window win = super.properties(params); - String formId = "action-prop-form-"+id; - Form form = new Form(formId); + Form form = new Form("action-prop-form-"+id); new Input(REALM,REALM_ACTIONS).hideIn(form); new Input(ID,params.get(ID)).hideIn(form); new Input(ACTION,ACTION_UPDATE).hideIn(form); @@ -54,7 +53,7 @@ public class SetSpeed extends Action{ Label label = new Label(t("Set speed to")+NBSP); new Input(MAX_SPEED, maxSpeed).addTo(label).content(NBSP+t("km/h")); label.addTo(form); - new Button(t("Apply"),"return submitForm('"+formId+"');").addTo(form).addTo(win); + new Button(t("Apply"),form).addTo(form).addTo(win); return win; } diff --git a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java index 3f45b7a..a3d1427 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java @@ -56,16 +56,21 @@ public abstract class Condition implements Constants { } public JSONObject json() { - return new JSONObject().put(TYPE, getClass().getSimpleName()); + JSONObject json = new JSONObject().put(TYPE, getClass().getSimpleName()); + if (inverted) json.put(INVERTED, true); + return json; } public static Condition load(JSONObject json) { String type = json.getString(TYPE); + Condition condition = null; switch (type) { case "TrainSelect": - return TrainSelect.load(json); + condition = TrainSelect.load(json); + break; } - return null; + if (condition != null) condition.inverted = json.has(INVERTED) && json.getBoolean(INVERTED); + return condition; } public Tag link(String tagClass,String context) { diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index c197c61..cba9554 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -25,6 +25,7 @@ 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.actions.Action.Context; import de.srsoftware.web4rail.tags.Button; import de.srsoftware.web4rail.tags.Checkbox; import de.srsoftware.web4rail.tags.Fieldset; @@ -407,6 +408,7 @@ public class Train implements Constants { if (route != null) route.unlock().setSignals(Signal.STOP); HashSet routes = block.routes(); Vector availableRoutes = new Vector(); + Context context = new Context(this); for (Route rt : routes) { if (rt == route) continue; // andere Route als zuvor wählen if (rt.path().firstElement() != block) continue; // keine Route wählen, die nicht vom aktuellen Block des Zuges startet @@ -419,6 +421,7 @@ public class Train implements Constants { LOG.debug("{} is not free!",rt); continue; } + if (!rt.allowed(context)) continue; availableRoutes.add(rt); } Random rand = new Random(); diff --git a/src/main/java/de/srsoftware/web4rail/tags/Button.java b/src/main/java/de/srsoftware/web4rail/tags/Button.java index 4634921..492c082 100644 --- a/src/main/java/de/srsoftware/web4rail/tags/Button.java +++ b/src/main/java/de/srsoftware/web4rail/tags/Button.java @@ -22,6 +22,10 @@ public class Button extends Tag { attr("onclick",action).content(text); } + public Button(String text,Form form) { + this(text,"return submitForm('"+form.get("id")+"');"); + } + public Button(String text, Map props) { this(text,"request("+(new JSONObject(props).toString().replace("\"", "'"))+")"); }