bugfixes, improved action framework, added actions
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.srsoftware</groupId>
|
||||
<artifactId>web4rail</artifactId>
|
||||
<version>0.7.5</version>
|
||||
<version>0.7.6</version>
|
||||
<name>Web4Rail</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Java Model Railway Control</description>
|
||||
|
||||
@@ -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<String, String> params) throws IOException {
|
||||
if (tile != null) place(tile.update(params));
|
||||
private Tile update(Tile tile, HashMap<String, String> params) throws IOException {
|
||||
return tile == null ? null : tile.update(params);
|
||||
}
|
||||
|
||||
public void warn(Contact contact) {
|
||||
|
||||
@@ -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<String, Object> props = new HashMap<String, Object>(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<Action> 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<Action> 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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Tile> path = new Vector<Tile>();
|
||||
while (true) {
|
||||
if (route == null) {
|
||||
Thread.sleep(2000);
|
||||
if (stop) return;
|
||||
Train.this.start();
|
||||
path = route == null ? new Vector<Tile>() : 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<String, Object> 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();
|
||||
|
||||
@@ -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<String, Object> props) {
|
||||
super("button");
|
||||
attr("onclick","request("+(json.toString().replace("\"", "'"))+")").content(text);
|
||||
attr("onclick","request("+(new JSONObject(props).toString().replace("\"", "'"))+")").content(text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -180,8 +180,8 @@ public abstract class Tile implements Constants{
|
||||
return new Vector<Plan.Direction>();
|
||||
}
|
||||
|
||||
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()));
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user