From 7eabaf94492b07451dcc21a58e9774fb4fb3f5b6 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sun, 1 Nov 2020 03:40:28 +0100 Subject: [PATCH] added delayed action --- pom.xml | 2 +- .../srsoftware/web4rail/actions/Action.java | 36 ++++- .../web4rail/actions/ActionList.java | 65 +++------ .../web4rail/actions/DelayedAction.java | 123 ++++++++++++++++++ .../de/srsoftware/web4rail/tiles/Tile.java | 2 +- 5 files changed, 177 insertions(+), 51 deletions(-) create mode 100644 src/main/java/de/srsoftware/web4rail/actions/DelayedAction.java diff --git a/pom.xml b/pom.xml index 23709bd..f5df62d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.9.4 + 0.9.5 Web4Rail jar Java Model Railway Control diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java index d6955d5..c5568db 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/Action.java +++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java @@ -19,6 +19,7 @@ import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.tiles.Contact; public abstract class Action implements Constants { + private static final HashMap actions = new HashMap(); public static final Logger LOG = LoggerFactory.getLogger(Action.class); protected int id; @@ -42,6 +43,31 @@ public abstract class Action implements Constants { public Action() { id = Application.createId(); + actions.put(id, this); + } + + public static Action create(String type) { + switch (type) { // TODO: das kann man mit Reflection generischer lösen + case "ConditionalAction": + return new ConditionalAction(); + case "FinishRoute": + return new FinishRoute(); + case "SetSignalsToStop": + return new SetSignalsToStop(); + case "SetSpeed": + return new SetSpeed(0); + case "TurnTrain": + return new TurnTrain(); + case "StopAuto": + return new StopAuto(); + case "PowerOff": + return new PowerOff(); + case "SetRelay": + return new SetRelay(); + case "DelayedAction": + return new DelayedAction(); + } + return null; } public abstract boolean fire(Context context) throws IOException; @@ -54,8 +80,8 @@ public abstract class Action implements Constants { return new JSONObject().put(TYPE, getClass().getSimpleName()); } - protected Tag link(int actionId, String context) { - Map props = Map.of(REALM,REALM_ACTIONS,ID,actionId+"/"+id,ACTION,ACTION_PROPS,CONTEXT,context); + protected Tag link(Integer parentId, String context) { + Map props = Map.of(REALM,REALM_ACTIONS,ID,parentId+"/"+id,ACTION,ACTION_PROPS,CONTEXT,context); String action = "request("+(new JSONObject(props).toString().replace("\"", "'"))+")"; return new Tag("span").content(toString()+NBSP).attr("onclick", action); } @@ -79,6 +105,8 @@ public abstract class Action implements Constants { return SetRelay.load(json); case "TurnTrain": return new TurnTrain(); + case "DelayedAction": + return DelayedAction.load(json); } LOG.error("Found unknwon action \"{}\" in json!",clazz); return null; @@ -100,4 +128,8 @@ public abstract class Action implements Constants { protected Object update(HashMap params) { return t("Nothing changed"); } + + public static Action get(int actionId) { + return actions.get(actionId); + } } diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java index a3d4e74..7fa5c9c 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/ActionList.java +++ b/src/main/java/de/srsoftware/web4rail/actions/ActionList.java @@ -64,10 +64,11 @@ public class ActionList extends Vector implements Constants{ TurnTrain.class, StopAuto.class, PowerOff.class, - SetRelay.class + SetRelay.class, + DelayedAction.class ); for (Class clazz : classes) select.addOption(clazz.getSimpleName()); - select.addTo(new Label("Action type:")).addTo(typeForm); + select.addTo(new Label(t("Action type:")+NBSP)).addTo(typeForm); return new Button(t("Create action"),typeForm).addTo(typeForm).addTo(win); } @@ -77,37 +78,14 @@ public class ActionList extends Vector implements Constants{ String context = params.get(CONTEXT); if (type == null) return actionTypeForm(win,context); - switch (type) { // TODO: das kann man mit Reflection generischer lösen - case "ConditionalAction": - add(new ConditionalAction()); - break; - case "FinishRoute": - add(new FinishRoute()); - break; - case "SetSignalsToStop": - add(new SetSignalsToStop()); - break; - case "SetSpeed": - add(new SetSpeed(0)); - break; - case "TurnTrain": - add(new TurnTrain()); - break; - case "StopAuto": - add(new StopAuto()); - break; - case "PowerOff": - add(new PowerOff()); - break; - case "SetRelay": - add(new SetRelay()); - break; - default: - actionTypeForm(win,context); - new Tag("span").content(t("Unknown action type: {}",type)).addTo(win); - return win; - } - return plan.showContext(params); + Action action = Action.create(type); + if (action instanceof Action) { + add(action); + return plan.showContext(params); + } + actionTypeForm(win,context); + new Tag("span").content(t("Unknown action type: {}",type)).addTo(win); + return win; } public void addTo(Tag link, String context) { @@ -163,13 +141,6 @@ public class ActionList extends Vector implements Constants{ } } } - - private Action getAction(int actionId) { - for (Action action : this) { - if (action.id == actionId) return action; - } - return null; - } public int id() { return id; @@ -207,11 +178,11 @@ public class ActionList extends Vector implements Constants{ Integer listId = actionListId(params); if (listId == null) return t("No action list id passed to ActionList.process()!"); ActionList actionList = actionLists.get(listId); - if (actionList == null) return t("No action list with id {} found!",listId); Integer actionId = actionId(params); String action = params.get(ACTION); if (action == null) return t("No action passed to ActionList.process()!"); + if (actionList == null && !List.of(ACTION_UPDATE,ACTION_PROPS).contains(action)) return t("No action list with id {} found!",listId); switch (action) { case ACTION_ADD: @@ -221,16 +192,16 @@ public class ActionList extends Vector implements Constants{ case ACTION_MOVE: return actionList.moveUp(actionId) ? plan.showContext(params) : t("No action with id {} found!",actionId); case ACTION_PROPS: - return actionList.propsOf(params); + return propsOf(params); case ACTION_UPDATE: - return actionList.update(actionId,params,plan); + return update(actionId,params,plan); } return t("Unknown action: {}",action); } - private Object propsOf(HashMap params) { + private static Object propsOf(HashMap params) { int actionId = actionId(params); - Action action = getAction(actionId); + Action action = Action.get(actionId); if (action != null) return action.properties(params); return t("No action with id {} found!",actionId); } @@ -239,8 +210,8 @@ public class ActionList extends Vector implements Constants{ return Translation.get(Application.class, text, fills); } - private Object update(int actionId, HashMap params, Plan plan) { - Action action = getAction(actionId); + private static Object update(int actionId, HashMap params, Plan plan) { + Action action = Action.get(actionId); if (action != null) { plan.stream(action.update(params).toString()); return plan.showContext(params); diff --git a/src/main/java/de/srsoftware/web4rail/actions/DelayedAction.java b/src/main/java/de/srsoftware/web4rail/actions/DelayedAction.java new file mode 100644 index 0000000..9fb5112 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/actions/DelayedAction.java @@ -0,0 +1,123 @@ +package de.srsoftware.web4rail.actions; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; + +import org.json.JSONObject; + +import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.tags.Button; +import de.srsoftware.web4rail.tags.Form; +import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Label; +import de.srsoftware.web4rail.tags.Select; + +public class DelayedAction extends Action{ + + public static final String DELAY = "delay"; + private static final int DEFAULT_DELAY = 1000; + private int delay = DEFAULT_DELAY; + private Action action = null; + + @Override + public boolean fire(Context context) { + new Thread() { + public void run() { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + } + if (action != null) try { + action.fire(context); + } catch (IOException e) { + e.printStackTrace(); + } + }; + }.start(); + return true; + } + + @Override + public JSONObject json() { + JSONObject json = super.json(); + json.put(DELAY, delay); + json.put(ACTION, action.json()); + return json; + } + + public static DelayedAction load(JSONObject json) { + DelayedAction da = new DelayedAction(); + da.delay = json.getInt(DELAY); + da.action = Action.load(json.getJSONObject(ACTION)); + return da; + } + + @Override + public Window properties(HashMap params) { + Window win = super.properties(params); + 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); + new Input(CONTEXT,params.get(CONTEXT)).hideIn(form); + + if (action == null) { + Select select = new Select(TYPE); + List> classes = List.of( + ConditionalAction.class, + SetSpeed.class, + SetSignalsToStop.class, + FinishRoute.class, + TurnTrain.class, + StopAuto.class, + PowerOff.class, + SetRelay.class, + DelayedAction.class + ); + for (Class clazz : classes) select.addOption(clazz.getSimpleName()); + select.addTo(new Label(t("Action type:")+NBSP)).addTo(form); + } else { + action.link(0, params.get(CONTEXT)).addTo(new Label(t("Action: "))).addTo(form); + } + Label label = new Label(t("Delay:")+NBSP); + new Input(DELAY, delay).numeric().addTo(label).content(NBSP+t("miliseconds")); + label.addTo(form); + new Button(t("Apply"),form).addTo(form).addTo(win); + return win; + } + + @Override + public String toString() { + if (action == null) return t("Click here to set up delayed action!"); + return t("Wait {} ms, then {}",delay,action); + } + + @Override + protected Object update(HashMap params) { + LOG.debug("update: {}",params); + + String type = params.get(TYPE); + if (type != null) action = Action.create(type); + + String error = null; + String ms = params.get(DELAY); + if (ms == null) { + ms = ""+DEFAULT_DELAY; + } else { + try { + int d = Integer.parseInt(ms); + if (d<0) error = t("Delay must not be less than zero!"); + if (error == null) { + this.delay = d; + return t("Action updated!"); + } + } catch (NumberFormatException e) { + error = t("Not a valid number!"); + } + } + Window win = properties(params); + return new Tag("span").content(error).addTo(win); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java index 7100365..11ada60 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java @@ -337,7 +337,7 @@ public abstract class Tile implements Constants{ } public String title() { - return getClass().getSimpleName(); + return getClass().getSimpleName() + " @ ("+x+", "+y+")"; } @Override