Browse Source

- added else branch to conditional actions

- implemented history for any object extending BaseClass (i.e. almost any)
- added distance() calculation method to base class
- Button "edit JSON" in Action Lists now hidden by default, can be enabled in plan properties

- fixed bugs:
    - updating json of DisplayText was not working properly
    - log output in Tile.isFreeFor was broken
lookup-tables
Stephan Richter 3 years ago
parent
commit
77166acf91
  1. 1
      .gitignore
  2. 4
      pom.xml
  3. 19
      resources/translations/Application.de.translation
  4. 2
      src/main/java/de/srsoftware/web4rail/Application.java
  5. 45
      src/main/java/de/srsoftware/web4rail/BaseClass.java
  6. 1
      src/main/java/de/srsoftware/web4rail/Constants.java
  7. 102
      src/main/java/de/srsoftware/web4rail/History.java
  8. 1
      src/main/java/de/srsoftware/web4rail/MaintnanceTask.java
  9. 11
      src/main/java/de/srsoftware/web4rail/Plan.java
  10. 6
      src/main/java/de/srsoftware/web4rail/Route.java
  11. 2
      src/main/java/de/srsoftware/web4rail/actions/Action.java
  12. 21
      src/main/java/de/srsoftware/web4rail/actions/ActionList.java
  13. 50
      src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java
  14. 8
      src/main/java/de/srsoftware/web4rail/actions/WaitForContact.java
  15. 3
      src/main/java/de/srsoftware/web4rail/conditions/ConditionList.java
  16. 2
      src/main/java/de/srsoftware/web4rail/tiles/Contact.java
  17. 4
      src/main/java/de/srsoftware/web4rail/tiles/Switch.java
  18. 8
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

1
.gitignore vendored

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
*.cu
*.routes
*.trains
*.history
/backup
/bin/
/Debug/

4
pom.xml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId>
<version>1.4.17</version>
<version>1.4.18</version>
<name>Web4Rail</name>
<packaging>jar</packaging>
<description>Java Model Railway Control</description>
@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
<dependency>
<groupId>de.srsoftware</groupId>
<artifactId>tools</artifactId>
<version>1.1.12</version>
<version>1.1.15</version>
<scope>compile</scope>
</dependency>
<dependency>

19
resources/translations/Application.de.translation

@ -7,6 +7,8 @@ Actions (On) : Aktionen (Ein) @@ -7,6 +7,8 @@ Actions (On) : Aktionen (Ein)
Actions (Off) : Aktionen (Aus)
Actions and contacts : Aktionen und Kontakte
Action type : Aktions-Typ
Actions in case conditions are fulfilled : Aktionen, wenn Bedingungen erfüllt sind
Actions in case conditions are <em>not</em> fulfilled : Aktionen, wenn Bedingungen <em>nicht</em> erfüllt sind
Actions will only fire, if all conditions are fullfilled. : Aktionen werden nur ausgeführt, wenn alle Bedingungen erfüllt sind.
ActivateRoute : Route aktivieren
add : hinzufügen
@ -16,6 +18,7 @@ add action : Aktion hinzufügen @@ -16,6 +18,7 @@ add action : Aktion hinzufügen
Add action to action list : Aktion zur Liste hinzufügen
add car : Waggon hinzufügen
Add condition : Bedingung hinzufügen
Add entry : Eintrag hinzufügen
add locomotive : Lok hinzufügen
add new aspect : neues Signalbild hinzufügen
add new car : neuen Waggon anlegen
@ -28,6 +31,7 @@ Address : Adresse @@ -28,6 +31,7 @@ Address : Adresse
Add tag "{}" to train : Markierung "{}" zu Zug hinzufügen
Add tile : Kachel hinzufügen
Add {} to destinations of train : {} zu den Zielen des Zugs hinzufügen
Allow editing JSON of action lists : Bearbeiten von Action-Lists per JSON-Editor erlauben
analyze : analysieren
Analyze : analysieren
Analyze may overwrite these routes! : Durch die Analyse können diese Fahrstraßen überschrieben werden!
@ -109,6 +113,7 @@ Current location\: {} : Aufenthaltsort: {} @@ -109,6 +113,7 @@ Current location\: {} : Aufenthaltsort: {}
Current orientation : aktuelle Fahrtrichtung
Current velocity\: {} {} : Aktuelle Geschwindigkeit: {} {}
custom fields : benutzerdefinierte Felder
Date/Time : Datum/Zeit
Decoder address : Decoder-Adresse
decouple : Abkuppeln
decoupler : decoupler
@ -130,6 +135,7 @@ disable {} : {} deaktivieren @@ -130,6 +135,7 @@ disable {} : {} deaktivieren
disabled routes : deaktivierte Fahrstraßen
DisableEnableBlock : Block (de)aktivieren
Display "{}" on {}. : „{}“ auf {} anzeigen.
Do you know, what you are doing? : Weißt du, was du da tust?
driven distance : zurückgelegte Strecke
Drop : Verwerfen
Drop brake times : Bremszeiten löschen
@ -138,10 +144,12 @@ due after : fällig ab @@ -138,10 +144,12 @@ due after : fällig ab
1) Duration between 5 {} steps during brake process. : 1) Zeit zwischen 5 {}-Schritten beim Bremsvorgang.
EAST : Osten
edit : bearbeiten
edit JSON : JSON bearbeiten
Editable properties : veränderliche Eigenschaften
editable train properties : veränderliche Zug-Eigenschaften
Edit json : JSON bearbeiten
Effect : Effekt
else\: : falls nicht:
Emergency : Notfall
empty train : leerer Zug
enable : aktivieren
@ -150,8 +158,9 @@ Engage {} : {} aktivieren @@ -150,8 +158,9 @@ Engage {} : {} aktivieren
EngageDecoupler : Entkuppler aktivieren
Enter new name for plan : Neuen Namen für den Plan eingeben
executed : ausgeführt
executed "{}" after {} : "{}" nach {} ausgeführt
extended address : erweiterte Adresse
export : exportieren
Event : Ereignis
Faster ({} {}) : {} {} schneller
Final speed after breaking, before halting : Endgeschwindigkeit nach Bremsvorgang, vor dem Anhalten
FinishRoute : Route abschließen
@ -167,12 +176,12 @@ Function : Funktion @@ -167,12 +176,12 @@ Function : Funktion
Hardware settings : Hardware-Einstellungen
Height : Höhe
Help : Hilfe
History : Logbuch
Hold : an lassen
(id\: {}, length\: {}) : (Id: {}, Länge: {})
if ({}) : falls ({})
If car of train\: inspect car number : Falls Fahrzeug aus Zug: Untersuche Fahrzeug Nummer
If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.
Falls aktiviert, wird die Strecke anhand von Zug- und Kachel-Länge hinter dem Zug freigegeben, Falls deaktiviert wird die Strecke hinter dem Zug erst bei Abschluss der Route freigegeben.
If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished. : Falls aktiviert, wird die Strecke anhand von Zug- und Kachel-Länge hinter dem Zug freigegeben, Falls deaktiviert wird die Strecke hinter dem Zug erst bei Abschluss der Route freigegeben.
internal contacts : interne Kontakte
Interval : Intervall
inverted : invertiert
@ -215,6 +224,7 @@ Minimum delay : minimale Verzögerung @@ -215,6 +224,7 @@ Minimum delay : minimale Verzögerung
Minimum and maximum times (in Miliseconds) trains with the respective tag have to wait in this block. : Minamle und maximale Block-Haltezeit (in Millisekunden) für Züge mit der entsprchender Markierung.
minimum starting voltage v<sub>min</sub> : Mindestanfahrspannung v<sub>min</sub>
Move tiles : Kacheln verschieben
move up : nach oben schieben
name : Name
new car : neuer Waggon
new contact : neuer Kontakt
@ -366,6 +376,7 @@ Text to display on clients : Text, welcher auf den Clients angezeigt werden soll @@ -366,6 +376,7 @@ Text to display on clients : Text, welcher auf den Clients angezeigt werden soll
Text to show on display : Text, welcher in der Anzeige dargestellt werden soll
Tile(s) : Kachel(n)
Tile(s) moved. : Kachel(n) verschoben.
Timeout : maximale Wartezeit5
Toggle : umschalten
toggle {} : {} umschalten
Toggle power : Stom umschalten
@ -429,4 +440,4 @@ Was not able to set all turnouts! : Konnte nicht alle Weichen stellen! @@ -429,4 +440,4 @@ Was not able to set all turnouts! : Konnte nicht alle Weichen stellen!
WEST : Westen
Width : Breite
{} within last {} blocks of train : {} ist in den letzten {} Blöcken des Zugs
Your plan currently has {} routes. : Ihr Plan hat im Moment {} Fahrstraßen.
Your plan currently has {} routes. : Ihr Plan hat im Moment {} Fahrstraßen.

2
src/main/java/de/srsoftware/web4rail/Application.java

@ -125,6 +125,8 @@ public class Application extends BaseClass{ @@ -125,6 +125,8 @@ public class Application extends BaseClass{
return Condition.action(params,plan);
case REALM_CU:
return plan.controlUnit().process(params);
case REALM_HISTORY:
return History.action(params);
case REALM_LOCO:
return Locomotive.action(params,plan);
case REALM_MAINTENANCE:

45
src/main/java/de/srsoftware/web4rail/BaseClass.java

@ -18,8 +18,9 @@ import org.json.JSONObject; @@ -18,8 +18,9 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.srsoftware.tools.translations.Translation;
import de.srsoftware.tools.Tag;
import de.srsoftware.tools.translations.Translation;
import de.srsoftware.web4rail.History.LogEntry;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.conditions.Condition;
@ -54,7 +55,7 @@ public abstract class BaseClass implements Constants{ @@ -54,7 +55,7 @@ public abstract class BaseClass implements Constants{
public static final Logger LOG = LoggerFactory.getLogger(BaseClass.class);
private static final String CUSTOM_FIELDS = "custom_Fields";
private static final String NEW_CUSTOM_FIELD_NAME = "new_custom_field_name";
protected HashMap<String,String> customFieldValues = new HashMap<String, String>();
protected HashMap<String,String> customFieldValues = new HashMap<String, String>();
private BaseClass parent;
public static class Context {
@ -308,6 +309,12 @@ public abstract class BaseClass implements Constants{ @@ -308,6 +309,12 @@ public abstract class BaseClass implements Constants{
}
}
public Window addLogEntry(String text) {
History.assign(new History.LogEntry(text),this);
return properties();
}
public Button button(String text,Map<String,String> additionalProps) {
return new Button(text,props(additionalProps));
}
@ -320,6 +327,25 @@ public abstract class BaseClass implements Constants{ @@ -320,6 +327,25 @@ public abstract class BaseClass implements Constants{
LOG.debug(tx, fills);
return false;
}
public static String distance(long l) {
String unit = Plan.lengthUnit;
if (DEFAULT_LENGTH_UNIT.equals(unit)) {
if (l > 1_000_000) {
l/=1_000_000;
unit = t("km");
} else
if (l > 1_000) {
l/=1_000;
unit = t("m");
} else
if (l > 10) {
l/=10;
unit = t("cm");
}
}
return l+NBSP+unit;
}
public Form form(String id,List<Map.Entry<String, Tag>> elements) {
Form form = new Form(id);
@ -503,6 +529,21 @@ public abstract class BaseClass implements Constants{ @@ -503,6 +529,21 @@ public abstract class BaseClass implements Constants{
new Button(t("Apply"),customForm).addTo(customForm).addTo(customFields);
customFields.addTo(win);
Fieldset history = new Fieldset(t("History"));
Form form = new Form("add-history-entry");
new Input(REALM, REALM_HISTORY).hideIn(form);
new Input(ACTION, ACTION_ADD).hideIn(form);
new Input(ID,id()).hideIn(form);
new TextArea(NOTES).addTo(form);
new Button(t("Add entry"), form).addTo(form);
form.addTo(history);
table = new Table();
table.addHead(t("Date/Time"),t("Event"));
for (LogEntry entry : History.getFor(this)) table.addRow(new SimpleDateFormat("YYYY-dd-MM HH:mm").format(entry.date()),entry.getText());
table.addTo(history).addTo(win);
return win;
}

1
src/main/java/de/srsoftware/web4rail/Constants.java

@ -46,6 +46,7 @@ public interface Constants { @@ -46,6 +46,7 @@ public interface Constants {
public static final String REALM_CONDITION = "condition";
public static final String REALM_CONTACT = "contact";
public static final String REALM_CU = "cu";
public static final String REALM_HISTORY = "history";
public static final String REALM_LOCO = "loco";
public static final String REALM_MAINTENANCE = "maintenance";
public static final String REALM_ROUTE = "route";

102
src/main/java/de/srsoftware/web4rail/History.java

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
package de.srsoftware.web4rail;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;
import org.json.JSONObject;
import de.srsoftware.web4rail.BaseClass.Id;
public class History {
private static HashMap<BaseClass.Id, Vector<LogEntry>> log = new HashMap<>();
static class LogEntry extends BaseClass {
private long timestamp;
private String text;
public LogEntry(String text) {
this.text = text;
timestamp = new Date().getTime();
}
public Date date() {
return new Date(timestamp);
}
public long getTime() {
return timestamp;
}
public String getText() {
return text;
}
};
public static LogEntry assign(LogEntry logEntry, BaseClass object) {
Id id = object.id();
Vector<LogEntry> list = log.get(id);
if (list == null) log.put(id, list = new Vector<>());
list.insertElementAt(logEntry,0);
return logEntry;
}
public static Vector<LogEntry> getFor(BaseClass object){
Vector<LogEntry> list = log.get(object.id());
return list != null ? list : new Vector<>();
}
public static Object action(HashMap<String, String> params) {
switch (params.get(Constants.ACTION)) {
case Constants.ACTION_ADD:
BaseClass object = BaseClass.get(Id.from(params));
return object != null ? object.addLogEntry(params.get(Constants.NOTES)) : BaseClass.t("Unknown object!");
}
return BaseClass.t("Unknown action: {}",params.get(Constants.ACTION));
}
public static void save(String filename) {
try {
FileWriter file = new FileWriter(filename, Constants.UTF8);
JSONObject json = new JSONObject();
log.entrySet().forEach(entry -> {
JSONObject list = new JSONObject();
entry.getValue().forEach(le -> list.put(le.timestamp+"", le.getText()));
json.put(entry.getKey().toString(), list);
});
json.write(file);
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void load(String filename) throws IOException {
BufferedReader file = new BufferedReader(new FileReader(filename, Constants.UTF8));
JSONObject json = new JSONObject(file.readLine());
file.close();
for (String id : json.keySet()) {
JSONObject o = json.getJSONObject(id);
Vector<LogEntry> entries = new Vector<>();
for (String time : o.keySet()) {
LogEntry le = new LogEntry(o.getString(time));
le.timestamp = Long.parseLong(time);
entries.add(le);
}
Collections.sort(entries, (a,b) -> Long.compare(b.timestamp, a.timestamp));
log.put(new Id(id), entries);
}
}
}

1
src/main/java/de/srsoftware/web4rail/MaintnanceTask.java

@ -84,6 +84,7 @@ public class MaintnanceTask extends BaseClass{ @@ -84,6 +84,7 @@ public class MaintnanceTask extends BaseClass{
Block block = train.currentBlock();
if (isSet(block)) plan.place(block);
}
car.addLogEntry(t("executed \"{}\" after {}",name,BaseClass.distance(lastExecutionDist)));
return car.properties();
}
return t("parent is not a car!");

11
src/main/java/de/srsoftware/web4rail/Plan.java

@ -157,12 +157,14 @@ public class Plan extends BaseClass{ @@ -157,12 +157,14 @@ public class Plan extends BaseClass{
private static final String FREE_BEHIND_TRAIN = "free_behind_train";
private static final String RENAME = "rename";
private static final String SPEED_STEP = "speed_step";
private static final String ALLOW_JSON_EDIT = "allow_json_edit";
private String name = DEFAULT_NAME;
private ControlUnit controlUnit = new ControlUnit(this); // the control unit, to which the plan is connected
private Contact learningContact;
private Configuration appConfig;
private LinkedList<EventListener> listeners = new LinkedList<>();
public static boolean allowJsonEdit = false;
/**
* creates a new plan, starts to send heart beats
@ -563,6 +565,9 @@ public class Plan extends BaseClass{ @@ -563,6 +565,9 @@ public class Plan extends BaseClass{
} catch (Exception e) {
LOG.warn("Was not able to establish connection to control unit!");
}
History.load(name+".history");
LoadCallback.fire();
}
@ -714,6 +719,7 @@ public class Plan extends BaseClass{ @@ -714,6 +719,7 @@ public class Plan extends BaseClass{
formInputs.add(t("Speed step"),new Input(SPEED_STEP, Train.defaultSpeedStep).attr("title", t("Speeds are always increadsed/decreased by this value")));
formInputs.add(t("Lower speed limit"),new Input(FINAL_SPEED, Train.defaultEndSpeed).attr("title", t("Final speed after breaking, before halting")));
formInputs.add(t("Free tiles behind train"),new Checkbox(FREE_BEHIND_TRAIN, t("If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished."), Route.freeBehindTrain));
formInputs.add(t("Allow editing JSON of action lists"),new Checkbox(ALLOW_JSON_EDIT, t("Do you know, what you are doing?"), allowJsonEdit ));
postForm.add(relayProperties());
postForm.add(routeProperties());
@ -859,6 +865,8 @@ public class Plan extends BaseClass{ @@ -859,6 +865,8 @@ public class Plan extends BaseClass{
file.write(json().toString());
file.close();
History.save(name+".history");
return t("Plan saved as \"{}\".",name);
}
@ -1026,7 +1034,8 @@ public class Plan extends BaseClass{ @@ -1026,7 +1034,8 @@ public class Plan extends BaseClass{
if (params.containsKey(LENGTH_UNIT)) lengthUnit = params.get(LENGTH_UNIT);
if (params.containsKey(SPEED_UNIT)) speedUnit = params.get(SPEED_UNIT);
if (params.containsKey(SPEED_STEP)) Train.defaultSpeedStep = Integer.parseInt(params.get(SPEED_STEP));
if (params.containsKey(FINAL_SPEED)) Train.defaultEndSpeed = Integer.parseInt(params.get(FINAL_SPEED));
if (params.containsKey(FINAL_SPEED)) Train.defaultEndSpeed = Integer.parseInt(params.get(FINAL_SPEED));
allowJsonEdit = "on".equalsIgnoreCase(params.get(ALLOW_JSON_EDIT));
Route.freeBehindTrain = "on".equalsIgnoreCase(params.get(FREE_BEHIND_TRAIN));
return t("Plan updated.");

6
src/main/java/de/srsoftware/web4rail/Route.java

@ -348,7 +348,7 @@ public class Route extends BaseClass { @@ -348,7 +348,7 @@ public class Route extends BaseClass {
setupActions = new ActionList(this);
triggeredActions.put(ROUTE_SETUP, setupActions);
}
setupActions.list().addTo(setup).addTo(list);
setupActions.listAt(setup).addTo(list);
Tag start = new Tag("li").content(t("Start actions")+COL);
ActionList startActions = triggeredActions.get(ROUTE_START);
@ -356,7 +356,7 @@ public class Route extends BaseClass { @@ -356,7 +356,7 @@ public class Route extends BaseClass {
startActions = new ActionList(this);
triggeredActions.put(ROUTE_START, startActions);
}
startActions.list().addTo(start).addTo(list);
startActions.listAt(start).addTo(list);
for (Contact c : contacts) {
Tag item = c.link("span", c).addTo(new Tag("li")).content(NBSP);
@ -365,7 +365,7 @@ public class Route extends BaseClass { @@ -365,7 +365,7 @@ public class Route extends BaseClass {
actions = new ActionList(this);
triggeredActions.put(c.trigger(), actions);
}
actions.list().addTo(item).addTo(list);
actions.listAt(item).addTo(list);
}
list.addTo(win);
return win;

2
src/main/java/de/srsoftware/web4rail/actions/Action.java

@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory; @@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.LoadCallback;
import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Form;
@ -110,6 +111,7 @@ public abstract class Action extends BaseClass { @@ -110,6 +111,7 @@ public abstract class Action extends BaseClass {
((ActionList)this).clear();
}
load(json);
LoadCallback.fire();
return context().properties();
}
Window win = new Window("json-import-export-"+id(), t("JSON code of {}",this));

21
src/main/java/de/srsoftware/web4rail/actions/ActionList.java

@ -123,23 +123,22 @@ public class ActionList extends Action implements Iterable<Action>{ @@ -123,23 +123,22 @@ public class ActionList extends Action implements Iterable<Action>{
return json;
}
public Tag list() {
Tag span = new Tag("span");
button(t("add action"), Map.of(ACTION, ACTION_ADD)).addTo(span);
button(t("export"), Map.of(ACTION, ACTION_SAVE)).addTo(span);
public <T extends Tag> T listAt(T parent) {
button(parent.is("fieldset") ? t("add action") : "+", Map.of(ACTION, ACTION_ADD)).title(t("add action")).addTo(parent);
if (plan.allowJsonEdit) button(t("edit JSON"), Map.of(ACTION, ACTION_SAVE)).addTo(parent);
if (!isEmpty()) {
Tag list = new Tag("ol");
for (Action action : actions) {
Tag item = action.link("span",action).addTo(new Tag("li")).content(NBSP);
action.button("-", Map.of(ACTION,ACTION_DROP)).addTo(item);
action.button("", Map.of(ACTION,ACTION_MOVE)).addTo(item);
if (action instanceof ActionList) ((ActionList) action).list().addTo(item);
action.button("", Map.of(ACTION,ACTION_MOVE)).title(t("move up")).addTo(item);
action.button("-", Map.of(ACTION,ACTION_DROP)).title(t("delete")).addTo(item);
if (action instanceof ActionList) ((ActionList) action).listAt(item);
item.addTo(list);
}
list.addTo(span);
list.addTo(parent);
}
return span;
return (T)parent;
}
public Action load(JSONObject json) {
@ -248,9 +247,7 @@ public class ActionList extends Action implements Iterable<Action>{ @@ -248,9 +247,7 @@ public class ActionList extends Action implements Iterable<Action>{
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm,String...errors) {
Fieldset fieldset = new Fieldset(t("Actions"));
list().addTo(fieldset);
postForm.add(fieldset);
preForm.add(listAt(new Fieldset(t("Actions")).clazz("actions")));
return super.properties(preForm, formInputs, postForm,errors);
}

50
src/main/java/de/srsoftware/web4rail/actions/ConditionalAction.java

@ -2,10 +2,13 @@ package de.srsoftware.web4rail.actions; @@ -2,10 +2,13 @@ package de.srsoftware.web4rail.actions;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Vector;
import org.json.JSONArray;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.conditions.Condition;
import de.srsoftware.web4rail.conditions.ConditionList;
@ -15,11 +18,14 @@ import de.srsoftware.web4rail.tags.Window; @@ -15,11 +18,14 @@ import de.srsoftware.web4rail.tags.Window;
public class ConditionalAction extends ActionList {
private static final String CONDITIONS = "conditions";
private static final String ELSE_ACTONS = "else_actions";
private ConditionList conditions = new ConditionList();
private ActionList elseActions;
public ConditionalAction(BaseClass parent) {
super(parent);
conditions.parent(this);
elseActions = new ActionList(parent);
}
public boolean equals(ConditionalAction other) {
@ -29,7 +35,7 @@ public class ConditionalAction extends ActionList { @@ -29,7 +35,7 @@ public class ConditionalAction extends ActionList {
@Override
public boolean fire(Context context,Object cause) {
for (Condition condition : conditions) {
if (!condition.fulfilledBy(context)) return true; // wenn die Bedingung nicht erfüllt ist, ist das kein Fehler!
if (!condition.fulfilledBy(context)) return elseActions.fire(context, cause);
}
return super.fire(context.clone(),cause); // actions, that happen within the conditional action list must not modify the global context.
}
@ -48,13 +54,27 @@ public class ConditionalAction extends ActionList { @@ -48,13 +54,27 @@ public class ConditionalAction extends ActionList {
JSONArray conditions = new JSONArray();
for (Condition condition : this.conditions) conditions.put(condition.json());
json.put(CONDITIONS, conditions);
if (!elseActions.isEmpty()) json.put(ELSE_ACTONS, elseActions.json());
return json;
}
@Override
public <T extends Tag> T listAt(T parent) {
T tag = super.listAt(parent);
if (!elseActions.isEmpty()) {
Tag div = new Tag("div").clazz("else");
new Tag("span").content(t("else:")+NBSP).addTo(div);
elseActions.listAt(div);
div.addTo(tag);
}
return tag;
}
@Override
public Action load(JSONObject json) {
super.load(json);
super.load(json);
if (json.has(CONDITIONS)) {
conditions.clear();
for (Object o : json.getJSONArray(CONDITIONS)) {
if (o instanceof JSONObject) {
JSONObject j = (JSONObject) o;
@ -66,13 +86,37 @@ public class ConditionalAction extends ActionList { @@ -66,13 +86,37 @@ public class ConditionalAction extends ActionList {
}
}
}
if (json.has(ELSE_ACTONS)) elseActions.load(json.getJSONObject(ELSE_ACTONS));
return this;
}
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm,String...errors) {
preForm.add(conditions.list());
return super.properties(preForm, formInputs, postForm,errors);
Window win = super.properties(preForm, formInputs, postForm,errors);
Optional<Fieldset> actionFieldSet = win.children()
.stream()
.filter(tag -> tag instanceof Fieldset)
.map(tag -> (Fieldset)tag)
.filter(fs -> "actions".equals(fs.get("class")))
.findFirst();
if (actionFieldSet.isPresent()) {
Vector<Tag> children = actionFieldSet.get().children();
children.insertElementAt(new Tag("h3").content(t("Actions in case conditions are fulfilled")),1);
LOG.debug("children: "+children);
Optional<Tag> elseTag = children.stream().filter(tag -> "else".equals(tag.get("class"))).findFirst();
if (elseTag.isPresent()) {
children = elseTag.get().children();
children.remove(0);
children.insertElementAt(new Tag("h3").content(t("Actions in case conditions are <em>not</em> fulfilled")),0);
} else {
children.add(new Tag("h3").content(t("Actions in case conditions are <em>not</em> fulfilled")));
elseActions.listAt(actionFieldSet.get());
}
}
return win;
}

8
src/main/java/de/srsoftware/web4rail/actions/WaitForContact.java

@ -69,14 +69,14 @@ public class WaitForContact extends ActionList { @@ -69,14 +69,14 @@ public class WaitForContact extends ActionList {
}
@Override
public Tag list() {
Tag list = super.list();
public <T extends Tag> T listAt(T parent) {
T list = super.listAt(parent);
for (Tag child : list.children()) {
if (child.is("ol")) {
break;
}
}
timeoutActions.list().addTo(new Tag("span").content(t("On timeout (after {} ms)",timeout)+":")).addTo(list);
timeoutActions.listAt(new Tag("span").content(t("On timeout (after {} ms)",timeout)+":")).addTo(list);
return list;
}
@ -103,7 +103,7 @@ public class WaitForContact extends ActionList { @@ -103,7 +103,7 @@ public class WaitForContact extends ActionList {
Fieldset fieldset = new Fieldset(t("Actions on timeout"));
fieldset.id("actions");
timeoutActions.list().addTo(fieldset);
timeoutActions.listAt(fieldset);
postForm.add(fieldset);
return super.properties(preForm, formInputs, postForm,errors);

3
src/main/java/de/srsoftware/web4rail/conditions/ConditionList.java

@ -31,6 +31,9 @@ public class ConditionList extends Condition implements Iterable<Condition>{ @@ -31,6 +31,9 @@ public class ConditionList extends Condition implements Iterable<Condition>{
this.conditions.addAll(conditions.conditions);
}
public void clear() {
conditions.clear();
}
public boolean fulfilledBy(Context context) {
for (Condition condition : conditions) {

2
src/main/java/de/srsoftware/web4rail/tiles/Contact.java

@ -189,7 +189,7 @@ public class Contact extends Tile{ @@ -189,7 +189,7 @@ public class Contact extends Tile{
formInputs.add(t("Address"),span);
Fieldset fieldset = new Fieldset(t("Actions")).id("props-actions");
actions.list().addTo(fieldset);
actions.listAt(fieldset);
postForm.add(fieldset);
return super.properties(preForm, formInputs, postForm,errors);
}

4
src/main/java/de/srsoftware/web4rail/tiles/Switch.java

@ -129,11 +129,11 @@ public class Switch extends Tile{ @@ -129,11 +129,11 @@ public class Switch extends Tile{
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm,String...errors) {
Fieldset fieldset = new Fieldset(t("Actions (On)"));
fieldset.id("actionsOn");
actionsOn.list().addTo(fieldset);
actionsOn.listAt(fieldset);
postForm.add(fieldset);
fieldset = new Fieldset(t("Actions (Off)"));
fieldset.id("actionsOff");
actionsOff.list().addTo(fieldset);
actionsOff.listAt(fieldset);
postForm.add(fieldset);
return super.properties(preForm, formInputs, postForm,errors);
}

8
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -149,18 +149,18 @@ public abstract class Tile extends BaseClass implements Comparable<Tile> { @@ -149,18 +149,18 @@ public abstract class Tile extends BaseClass implements Comparable<Tile> {
Train train = newTrain.train();
if (isSet(reservingTrain) && reservingTrain != train) {
LOG.debug("{} is reserved for {}",reservingTrain);
LOG.debug("{} is reserved for {}",this,reservingTrain);
return false; // nicht in reservierten Block einfahren!
}
if (isSet(lockingTrain) && lockingTrain != train) {
LOG.debug("{} is locked for {}",lockingTrain);
LOG.debug("{} is locked for {}",this,lockingTrain);
return false; // nicht in reservierten Block einfahren!
}
if (isSet(occupyingTrain) && occupyingTrain != train) {
LOG.debug("{} is occupied by {}",occupyingTrain);
return train.isShunting(); // nur in belegte Blöcke einfahren, wenn Rangiermodus aktiv!
LOG.debug("{} is occupied by {}",this,occupyingTrain);
return isSet(train) && train.isShunting(); // nur in belegte Blöcke einfahren, wenn Rangiermodus aktiv!
}
return true;

Loading…
Cancel
Save