implemented conditions on routes
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>de.srsoftware</groupId>
|
<groupId>de.srsoftware</groupId>
|
||||||
<artifactId>web4rail</artifactId>
|
<artifactId>web4rail</artifactId>
|
||||||
<version>0.8.2</version>
|
<version>0.8.3</version>
|
||||||
<name>Web4Rail</name>
|
<name>Web4Rail</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<description>Java Model Railway Control</description>
|
<description>Java Model Railway Control</description>
|
||||||
|
|||||||
@@ -222,4 +222,4 @@ ul{
|
|||||||
|
|
||||||
.menu div.emergency{
|
.menu div.emergency{
|
||||||
background: #ffb561;
|
background: #ffb561;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ Added {} : {} hinzugefügt
|
|||||||
Add tile : Kachel hinzufügen
|
Add tile : Kachel hinzufügen
|
||||||
Analyze plan : Plan analysieren
|
Analyze plan : Plan analysieren
|
||||||
Apply : Übernehmen
|
Apply : Übernehmen
|
||||||
|
Conditions : Bedingungen
|
||||||
Contacts and actions : Kontakte und Aktionen
|
Contacts and actions : Kontakte und Aktionen
|
||||||
Destination\: {} from {} : Ziel: {} von {}
|
Destination\: {} from {} : Ziel: {} von {}
|
||||||
length\: : Länge:
|
length\: : Länge:
|
||||||
|
|||||||
@@ -28,9 +28,13 @@ import de.srsoftware.web4rail.actions.ActivateRoute;
|
|||||||
import de.srsoftware.web4rail.actions.FinishRoute;
|
import de.srsoftware.web4rail.actions.FinishRoute;
|
||||||
import de.srsoftware.web4rail.actions.SetSignalsToStop;
|
import de.srsoftware.web4rail.actions.SetSignalsToStop;
|
||||||
import de.srsoftware.web4rail.actions.SetSpeed;
|
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.moving.Train;
|
||||||
|
import de.srsoftware.web4rail.tags.Button;
|
||||||
import de.srsoftware.web4rail.tags.Form;
|
import de.srsoftware.web4rail.tags.Form;
|
||||||
import de.srsoftware.web4rail.tags.Input;
|
import de.srsoftware.web4rail.tags.Input;
|
||||||
|
import de.srsoftware.web4rail.tags.Select;
|
||||||
import de.srsoftware.web4rail.tiles.Block;
|
import de.srsoftware.web4rail.tiles.Block;
|
||||||
import de.srsoftware.web4rail.tiles.Contact;
|
import de.srsoftware.web4rail.tiles.Contact;
|
||||||
import de.srsoftware.web4rail.tiles.Shadow;
|
import de.srsoftware.web4rail.tiles.Shadow;
|
||||||
@@ -62,6 +66,7 @@ public class Route implements Constants{
|
|||||||
private Block startBlock = null,endBlock;
|
private Block startBlock = null,endBlock;
|
||||||
private static final String START_DIRECTION = "direction_start";
|
private static final String START_DIRECTION = "direction_start";
|
||||||
private static final String END_DIRECTION = "direction_end";
|
private static final String END_DIRECTION = "direction_end";
|
||||||
|
private Vector<Condition> conditions = new Vector<Condition>();
|
||||||
|
|
||||||
public Direction startDirection;
|
public Direction startDirection;
|
||||||
private Direction endDirection;
|
private Direction endDirection;
|
||||||
@@ -70,6 +75,7 @@ public class Route implements Constants{
|
|||||||
private static final String ACTIONS = "actions";
|
private static final String ACTIONS = "actions";
|
||||||
private static final String ACTION_LISTS = "action_lists";
|
private static final String ACTION_LISTS = "action_lists";
|
||||||
private static final String ROUTES = "routes";
|
private static final String ROUTES = "routes";
|
||||||
|
private static final String CONDITIONS = "conditions";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* process commands from the client
|
* process commands from the client
|
||||||
@@ -81,11 +87,10 @@ public class Route implements Constants{
|
|||||||
Route route = plan.route(Integer.parseInt(params.get(ID)));
|
Route route = plan.route(Integer.parseInt(params.get(ID)));
|
||||||
if (route == null) return t("Unknown route: {}",params.get(ID));
|
if (route == null) return t("Unknown route: {}",params.get(ID));
|
||||||
switch (params.get(ACTION)) {
|
switch (params.get(ACTION)) {
|
||||||
|
case ACTION_UPDATE:
|
||||||
|
return route.update(params);
|
||||||
case ACTION_PROPS:
|
case ACTION_PROPS:
|
||||||
return route.properties();
|
return route.properties();
|
||||||
case ACTION_UPDATE:
|
|
||||||
route.update(params);
|
|
||||||
return plan.html();
|
|
||||||
}
|
}
|
||||||
return t("Unknown action: {}",params.get(ACTION));
|
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<Class<? extends Condition>> classes = List.of(TrainSelect.class);
|
||||||
|
for (Class<? extends Condition> clazz : classes) select.addOption(clazz.getSimpleName());
|
||||||
|
select.addTo(form);
|
||||||
|
new Button(t("Add condition"),form).addTo(form).addTo(win);
|
||||||
|
}
|
||||||
|
|
||||||
private void addContactsTo(Window win) {
|
private void addContactsTo(Window win) {
|
||||||
if (!contacts.isEmpty()) {
|
if (!contacts.isEmpty()) {
|
||||||
new Tag("h4").content(t("Contacts and actions")).addTo(win);
|
new Tag("h4").content(t("Contacts and actions")).addTo(win);
|
||||||
@@ -168,7 +200,7 @@ public class Route implements Constants{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addFormTo(Window win) {
|
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(ACTION, ACTION_UPDATE).hideIn(form);
|
||||||
new Input(REALM,REALM_ROUTE).hideIn(form);
|
new Input(REALM,REALM_ROUTE).hideIn(form);
|
||||||
new Input(ID,id()).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);
|
new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).style("width: 80%").addTo(label);
|
||||||
label.addTo(form);
|
label.addTo(form);
|
||||||
|
|
||||||
new Tag("button").attr("type", "submit").content(t("Apply")).addTo(form);
|
new Button(t("Apply"),form).addTo(form).addTo(win);
|
||||||
form.addTo(win);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSignal(Signal signal) {
|
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() {
|
protected Route clone() {
|
||||||
Route clone = new Route();
|
Route clone = new Route();
|
||||||
clone.startBlock = startBlock;
|
clone.startBlock = startBlock;
|
||||||
@@ -309,6 +352,10 @@ public class Route implements Constants{
|
|||||||
json.put(START_DIRECTION, startDirection);
|
json.put(START_DIRECTION, startDirection);
|
||||||
json.put(END_DIRECTION, endDirection);
|
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();
|
JSONArray jTriggers = new JSONArray();
|
||||||
for (Entry<String, ActionList> entry : triggers.entrySet()) {
|
for (Entry<String, ActionList> entry : triggers.entrySet()) {
|
||||||
JSONObject trigger = new JSONObject();
|
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));
|
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(ACTION_LISTS)) loadActions(json.getJSONArray(ACTION_LISTS));
|
||||||
|
if (json.has(CONDITIONS)) loadConditions(json.getJSONArray(CONDITIONS));
|
||||||
return plan.registerRoute(this);
|
return plan.registerRoute(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,6 +427,14 @@ public class Route implements Constants{
|
|||||||
LOG.debug("json: {}",json.getClass());
|
LOG.debug("json: {}",json.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadConditions(JSONArray arr) {
|
||||||
|
for (int i=0; i<arr.length(); i++) {
|
||||||
|
JSONObject json = arr.getJSONObject(i);
|
||||||
|
Condition condition = Condition.load(json);
|
||||||
|
if (condition != null) conditions.add(condition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean lock() {
|
public boolean lock() {
|
||||||
ArrayList<Tile> lockedTiles = new ArrayList<Tile>();
|
ArrayList<Tile> lockedTiles = new ArrayList<Tile>();
|
||||||
try {
|
try {
|
||||||
@@ -424,6 +480,7 @@ public class Route implements Constants{
|
|||||||
addFormTo(win);
|
addFormTo(win);
|
||||||
addBasicPropertiesTo(win);
|
addBasicPropertiesTo(win);
|
||||||
addTurnoutsTo(win);
|
addTurnoutsTo(win);
|
||||||
|
addConditionsTo(win);
|
||||||
addContactsTo(win);
|
addContactsTo(win);
|
||||||
|
|
||||||
return win;
|
return win;
|
||||||
@@ -508,8 +565,16 @@ public class Route implements Constants{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(HashMap<String, String> params) {
|
public Object update(HashMap<String, String> params) {
|
||||||
LOG.debug("update({})",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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ public abstract class Action implements Constants {
|
|||||||
if (route == null) return;
|
if (route == null) return;
|
||||||
train = route.train;
|
train = route.train;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Context(Train train) {
|
||||||
|
this.train = train;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action() {
|
public Action() {
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ public class ActionList extends Vector<Action> implements Constants{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object actionTypeForm(Window win, String context) {
|
private Object actionTypeForm(Window win, String context) {
|
||||||
String formId ="add-action-to-"+id;
|
Form typeForm = new Form("add-action-to-"+id);
|
||||||
Tag typeForm = new Form(formId);
|
|
||||||
new Input(REALM, REALM_ACTIONS).hideIn(typeForm);
|
new Input(REALM, REALM_ACTIONS).hideIn(typeForm);
|
||||||
new Input(ID,id).hideIn(typeForm);
|
new Input(ID,id).hideIn(typeForm);
|
||||||
new Input(ACTION,ACTION_ADD).hideIn(typeForm);
|
new Input(ACTION,ACTION_ADD).hideIn(typeForm);
|
||||||
@@ -68,7 +67,7 @@ public class ActionList extends Vector<Action> implements Constants{
|
|||||||
);
|
);
|
||||||
for (Class<? extends Action> clazz : classes) select.addOption(clazz.getSimpleName());
|
for (Class<? extends Action> clazz : classes) select.addOption(clazz.getSimpleName());
|
||||||
select.addTo(new Label("Action type:")).addTo(typeForm);
|
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<String, String> params, Plan plan) {
|
private Object addActionForm(HashMap<String, String> params, Plan plan) {
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public class ConditionalAction extends Action {
|
|||||||
for (Condition condition : conditions) condition.link("li",params.get(CONTEXT)).addTo(list);
|
for (Condition condition : conditions) condition.link("li",params.get(CONTEXT)).addTo(list);
|
||||||
list.addTo(fieldset);
|
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(REALM,REALM_ACTIONS).hideIn(form);
|
||||||
new Input(ID,params.get(ID)).hideIn(form);
|
new Input(ID,params.get(ID)).hideIn(form);
|
||||||
new Input(ACTION,ACTION_UPDATE).hideIn(form);
|
new Input(ACTION,ACTION_UPDATE).hideIn(form);
|
||||||
@@ -54,7 +54,7 @@ public class ConditionalAction extends Action {
|
|||||||
List<Class<? extends Condition>> classes = List.of(TrainSelect.class);
|
List<Class<? extends Condition>> classes = List.of(TrainSelect.class);
|
||||||
for (Class<? extends Condition> clazz : classes) select.addOption(clazz.getSimpleName());
|
for (Class<? extends Condition> clazz : classes) select.addOption(clazz.getSimpleName());
|
||||||
select.addTo(form);
|
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
|
@Override
|
||||||
|
|||||||
@@ -45,8 +45,7 @@ public class SetSpeed extends Action{
|
|||||||
@Override
|
@Override
|
||||||
public Window properties(HashMap<String, String> params) {
|
public Window properties(HashMap<String, String> params) {
|
||||||
Window win = super.properties(params);
|
Window win = super.properties(params);
|
||||||
String formId = "action-prop-form-"+id;
|
Form form = new Form("action-prop-form-"+id);
|
||||||
Form form = new Form(formId);
|
|
||||||
new Input(REALM,REALM_ACTIONS).hideIn(form);
|
new Input(REALM,REALM_ACTIONS).hideIn(form);
|
||||||
new Input(ID,params.get(ID)).hideIn(form);
|
new Input(ID,params.get(ID)).hideIn(form);
|
||||||
new Input(ACTION,ACTION_UPDATE).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);
|
Label label = new Label(t("Set speed to")+NBSP);
|
||||||
new Input(MAX_SPEED, maxSpeed).addTo(label).content(NBSP+t("km/h"));
|
new Input(MAX_SPEED, maxSpeed).addTo(label).content(NBSP+t("km/h"));
|
||||||
label.addTo(form);
|
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;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,16 +56,21 @@ public abstract class Condition implements Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject json() {
|
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) {
|
public static Condition load(JSONObject json) {
|
||||||
String type = json.getString(TYPE);
|
String type = json.getString(TYPE);
|
||||||
|
Condition condition = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "TrainSelect":
|
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) {
|
public Tag link(String tagClass,String context) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ 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.actions.Action.Context;
|
||||||
import de.srsoftware.web4rail.tags.Button;
|
import de.srsoftware.web4rail.tags.Button;
|
||||||
import de.srsoftware.web4rail.tags.Checkbox;
|
import de.srsoftware.web4rail.tags.Checkbox;
|
||||||
import de.srsoftware.web4rail.tags.Fieldset;
|
import de.srsoftware.web4rail.tags.Fieldset;
|
||||||
@@ -407,6 +408,7 @@ public class Train implements Constants {
|
|||||||
if (route != null) route.unlock().setSignals(Signal.STOP);
|
if (route != null) route.unlock().setSignals(Signal.STOP);
|
||||||
HashSet<Route> routes = block.routes();
|
HashSet<Route> routes = block.routes();
|
||||||
Vector<Route> availableRoutes = new Vector<Route>();
|
Vector<Route> availableRoutes = new Vector<Route>();
|
||||||
|
Context context = new Context(this);
|
||||||
for (Route rt : routes) {
|
for (Route rt : routes) {
|
||||||
if (rt == route) continue; // andere Route als zuvor wählen
|
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
|
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);
|
LOG.debug("{} is not free!",rt);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!rt.allowed(context)) continue;
|
||||||
availableRoutes.add(rt);
|
availableRoutes.add(rt);
|
||||||
}
|
}
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ public class Button extends Tag {
|
|||||||
attr("onclick",action).content(text);
|
attr("onclick",action).content(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Button(String text,Form form) {
|
||||||
|
this(text,"return submitForm('"+form.get("id")+"');");
|
||||||
|
}
|
||||||
|
|
||||||
public Button(String text, Map<String, Object> props) {
|
public Button(String text, Map<String, Object> props) {
|
||||||
this(text,"request("+(new JSONObject(props).toString().replace("\"", "'"))+")");
|
this(text,"request("+(new JSONObject(props).toString().replace("\"", "'"))+")");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user