working on new function mapping
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>1.4.43</version>
|
<version>1.4.44</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>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|||||||
@@ -246,6 +246,25 @@ public class Decoder extends BaseClass implements Constants, Device {
|
|||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void queue() {
|
||||||
|
init();
|
||||||
|
plan.queue(new Command("SET {} GL "+address()+" "+(reverse ? 0 : 1)+" "+step+" "+protocol().steps+functions()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Reply reply) {
|
||||||
|
super.onFailure(reply);
|
||||||
|
plan.stream(t("Failed to send command to {}: {}",this,reply.message()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queue(double speed, boolean reverse) {
|
||||||
|
step = (int)(speed*proto.steps);
|
||||||
|
this.reverse = reverse;
|
||||||
|
queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Select selector(boolean freeOnly) {
|
public static Select selector(boolean freeOnly) {
|
||||||
Select selector = new Select(REALM_DECODER);
|
Select selector = new Select(REALM_DECODER);
|
||||||
List<Decoder> decoders = BaseClass.listElements(Decoder.class);
|
List<Decoder> decoders = BaseClass.listElements(Decoder.class);
|
||||||
@@ -258,6 +277,12 @@ public class Decoder extends BaseClass implements Constants, Device {
|
|||||||
return selector;
|
return selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFunction(Integer function, boolean enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
if (enabledFunctions.add(function)) queue();
|
||||||
|
} else if (enabledFunctions.remove(function)) queue();
|
||||||
|
}
|
||||||
|
|
||||||
public Decoder setLoco(Locomotive locomotive, boolean log) {
|
public Decoder setLoco(Locomotive locomotive, boolean log) {
|
||||||
loco = locomotive;
|
loco = locomotive;
|
||||||
if (log) addLogEntry(t("Mounted into \"{}\".",loco));
|
if (log) addLogEntry(t("Mounted into \"{}\".",loco));
|
||||||
@@ -316,21 +341,8 @@ public class Decoder extends BaseClass implements Constants, Device {
|
|||||||
return isSet(loco) ? loco.properties() : properties();
|
return isSet(loco) ? loco.properties() : properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queue(double speed, boolean reverse) {
|
|
||||||
step = (int)(speed*proto.steps);
|
|
||||||
this.reverse = reverse;
|
|
||||||
queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void queue() {
|
|
||||||
init();
|
|
||||||
plan.queue(new Command("SET {} GL "+address()+" "+(reverse ? 0 : 1)+" "+step+" "+protocol().steps+functions()) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Reply reply) {
|
|
||||||
super.onFailure(reply);
|
|
||||||
plan.stream(t("Failed to send command to {}: {}",this,reply.message()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ public class Function extends BaseClass{
|
|||||||
if (json.has(DIRECTION)) json.getJSONArray(DIRECTION).forEach(o -> setDirection(o.toString(), true));
|
if (json.has(DIRECTION)) json.getJSONArray(DIRECTION).forEach(o -> setDirection(o.toString(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean is(String type) {
|
||||||
|
return this.type.equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDirectional() {
|
public boolean isDirectional() {
|
||||||
return directional;
|
return directional;
|
||||||
}
|
}
|
||||||
@@ -50,7 +54,6 @@ public class Function extends BaseClass{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public JSONObject json() {
|
public JSONObject json() {
|
||||||
JSONArray directions = new JSONArray();
|
JSONArray directions = new JSONArray();
|
||||||
if (directional) directions.put(DIRECTIONAL);
|
if (directional) directions.put(DIRECTIONAL);
|
||||||
@@ -99,9 +102,13 @@ public class Function extends BaseClass{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return type+"("+(forward?BaseClass.t("forward"):"")+(reverse?" "+BaseClass.t("reverse"):"")+(directional?" "+BaseClass.t("directional"):"").trim()+")";
|
return (BaseClass.isSet(name)?name+":":"") +type+"("+(forward?BaseClass.t("forward"):"")+(reverse?" "+BaseClass.t("reverse"):"")+(directional?" "+BaseClass.t("directional"):"").trim()+")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.io.FileReader;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.srsoftware.web4rail.moving;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -80,7 +81,8 @@ public class Locomotive extends Car implements Constants{
|
|||||||
return Locomotive.manager();
|
return Locomotive.manager();
|
||||||
}
|
}
|
||||||
|
|
||||||
return t("Unknown action: {}",params.getString(ACTION));
|
String message = t("Unknown action: {}",params.getString(ACTION));
|
||||||
|
return (isNull(loco)) ? message : loco.properties(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDecoderButtons(Window props) {
|
private void addDecoderButtons(Window props) {
|
||||||
@@ -185,9 +187,14 @@ public class Locomotive extends Car implements Constants{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isSet(train)) {
|
if (isSet(train)) {
|
||||||
params.put(ACTION, HEADLIGHT);
|
for (Entry<String, Boolean> fEntry : train.functions().entrySet()) {
|
||||||
//headlight = new Button(t("Headlight"), params);
|
String fName = fEntry.getKey();
|
||||||
|
params.put(ACTION, ACTION_TOGGLE_FUNCTION);
|
||||||
|
params.put(FUNCTION, fName);
|
||||||
|
Button btn = new Button(fName,params);
|
||||||
|
if (fEntry.getValue() == true) btn.clazz("active"); // == true is required, as getValue may return null
|
||||||
|
btn.addTo(functions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
functions.addTo(fieldset);
|
functions.addTo(fieldset);
|
||||||
@@ -257,6 +264,14 @@ public class Locomotive extends Car implements Constants{
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashSet<String> functionNames() {
|
||||||
|
HashSet<String> names = new HashSet<>();
|
||||||
|
for (HashMap<Integer, Function> map : functions.values()) {
|
||||||
|
for (Function f : map.values()) names.add(f.name());
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isDirectional(int index) {
|
private boolean isDirectional(int index) {
|
||||||
for (HashMap<Integer, Function> value : functions.values()) {
|
for (HashMap<Integer, Function> value : functions.values()) {
|
||||||
Function f = value.get(index);
|
Function f = value.get(index);
|
||||||
@@ -390,6 +405,25 @@ public class Locomotive extends Car implements Constants{
|
|||||||
if (log) addLogEntry(t("Mounted decoder \"{}\".",decoder));
|
if (log) addLogEntry(t("Mounted decoder \"{}\".",decoder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFunction(String name, boolean newVal, boolean first, boolean last) {
|
||||||
|
if (isNull(decoder)) return;
|
||||||
|
for (HashMap<Integer, Function> map : functions.values()) {
|
||||||
|
for (Entry<Integer, Function> entry : map.entrySet()) {
|
||||||
|
Function function = entry.getValue();
|
||||||
|
|
||||||
|
|
||||||
|
if (name.equals(function.name())) {
|
||||||
|
boolean setVal = newVal;
|
||||||
|
if (function.is(HEADLIGHT) && !first) setVal = false;
|
||||||
|
if (function.is(TAILLIGHT) && !last) setVal = false;
|
||||||
|
|
||||||
|
decoder.setFunction(entry.getKey(),setVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the speed of the locomotive to the given velocity in [plan.speedUnit]s
|
* Sets the speed of the locomotive to the given velocity in [plan.speedUnit]s
|
||||||
* @param newSpeed
|
* @param newSpeed
|
||||||
@@ -416,12 +450,13 @@ public class Locomotive extends Car implements Constants{
|
|||||||
return properties();
|
return properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object toggleFunction(Params params) {
|
private Window toggleFunction(Params params) {
|
||||||
Integer index = params.getInt(FUNCTION);
|
Integer index = params.getInt(FUNCTION);
|
||||||
if (isNull(index)) return t("No function number provided!");
|
Vector<String> errors = new Vector<String>();
|
||||||
if (isNull(decoder)) return t("{} has no decoder!",this);
|
if (isNull(index)) errors.add(t("No function number provided!"));
|
||||||
decoder.toggleFunction(index);
|
if (isNull(decoder)) errors.add(t("{} has no decoder!",this));
|
||||||
return t("Unknown function: {}",params);
|
if (errors.isEmpty()) decoder.toggleFunction(index);
|
||||||
|
return properties(errors.toArray(new String[errors.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object turn() {
|
public Object turn() {
|
||||||
|
|||||||
@@ -7,14 +7,17 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -98,6 +101,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
private Route nextPreparedRoute;
|
private Route nextPreparedRoute;
|
||||||
|
|
||||||
private BrakeProcess brake;
|
private BrakeProcess brake;
|
||||||
|
private HashMap<String,Boolean> functions = new HashMap<>();
|
||||||
|
|
||||||
public static Object action(Params params, Plan plan) throws IOException {
|
public static Object action(Params params, Plan plan) throws IOException {
|
||||||
String action = params.getString(ACTION);
|
String action = params.getString(ACTION);
|
||||||
@@ -144,6 +148,8 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
return train.stopNow();
|
return train.stopNow();
|
||||||
case ACTION_TIMES:
|
case ACTION_TIMES:
|
||||||
return train.removeBrakeTimes();
|
return train.removeBrakeTimes();
|
||||||
|
case ACTION_TOGGLE_FUNCTION:
|
||||||
|
return train.toggleFunction(params);
|
||||||
case ACTION_TOGGLE_SHUNTING:
|
case ACTION_TOGGLE_SHUNTING:
|
||||||
train.shunting = !train.shunting;
|
train.shunting = !train.shunting;
|
||||||
return train.properties();
|
return train.properties();
|
||||||
@@ -152,7 +158,8 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
case ACTION_UPDATE:
|
case ACTION_UPDATE:
|
||||||
return train.update(params);
|
return train.update(params);
|
||||||
}
|
}
|
||||||
return t("Unknown action: {}",params.getString(ACTION));
|
String message = t("Unknown action: {}",action);
|
||||||
|
return train.properties(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Train add(Car car) {
|
public Train add(Car car) {
|
||||||
@@ -192,12 +199,11 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String brakeId(boolean reversed) {
|
public String brakeId(boolean reversed) {
|
||||||
TreeSet<String> carIds = new TreeSet<String>();
|
TreeSet<String> locoIds = new TreeSet<String>();
|
||||||
cars.stream()
|
locos()
|
||||||
.filter(car -> car instanceof Locomotive)
|
.map(loco -> loco.id()+":"+(loco.orientation == reversed ? "r":"f"))
|
||||||
.map(car -> car.id()+":"+(car.orientation == reversed ? "r":"f"))
|
.forEach(locoIds::add);
|
||||||
.forEach(carIds::add);
|
String brakeId = md5sum(locoIds);
|
||||||
String brakeId = md5sum(carIds);
|
|
||||||
LOG.debug("generated new {} brake id for {}: {}",reversed?"backward":"forward",this,brakeId);
|
LOG.debug("generated new {} brake id for {}: {}",reversed?"backward":"forward",this,brakeId);
|
||||||
return brakeId;
|
return brakeId;
|
||||||
}
|
}
|
||||||
@@ -527,11 +533,18 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
return setSpeed(speed+steps);
|
return setSpeed(speed+steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Boolean> functions() {
|
||||||
|
Set<String> oldKeys = new HashSet<>(functions.keySet());
|
||||||
|
locos().flatMap(loco -> loco.functionNames().stream()).forEach(name -> {
|
||||||
|
if (!functions.containsKey(name)) functions.put(name, false);
|
||||||
|
oldKeys.remove(name);
|
||||||
|
});
|
||||||
|
oldKeys.forEach(name -> functions.remove(name));
|
||||||
|
return functions;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasLoco() {
|
private boolean hasLoco() {
|
||||||
for (Car c:cars) {
|
return locos().count() > 0;
|
||||||
if (c instanceof Locomotive) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNextPreparedRoute() {
|
public boolean hasNextPreparedRoute() {
|
||||||
@@ -642,6 +655,10 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream<Locomotive> locos() {
|
||||||
|
return cars.stream().filter(c -> c instanceof Locomotive).map(c -> (Locomotive)c);
|
||||||
|
}
|
||||||
|
|
||||||
public static Object manager() {
|
public static Object manager() {
|
||||||
Window win = new Window("train-manager", t("Train manager"));
|
Window win = new Window("train-manager", t("Train manager"));
|
||||||
new Tag("h4").content(t("known trains")).addTo(win);
|
new Tag("h4").content(t("known trains")).addTo(win);
|
||||||
@@ -742,7 +759,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
Tag directionLi = null;
|
Tag directionLi = null;
|
||||||
if (isSet(direction)) directionLi = new Tag("li").content(t("Direction: heading {}",direction)+NBSP);
|
if (isSet(direction)) directionLi = new Tag("li").content(t("Direction: heading {}",direction)+NBSP);
|
||||||
if (isNull(directionLi)) directionLi = new Tag("li");
|
if (isNull(directionLi)) directionLi = new Tag("li");
|
||||||
button(t("reverse"), Map.of(ACTION,ACTION_REVERSE)).title(t("Turns the train, as if it went through a loop.")).addTo(directionLi).addTo(propList);
|
button(t("reverse train"), Map.of(ACTION,ACTION_REVERSE)).title(t("Turns the train, as if it went through a loop.")).addTo(directionLi).addTo(propList);
|
||||||
|
|
||||||
Tag dest = new Tag("li").content(t("Destination")+COL);
|
Tag dest = new Tag("li").content(t("Destination")+COL);
|
||||||
if (isSet(destination)) {
|
if (isSet(destination)) {
|
||||||
@@ -927,7 +944,7 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
LOG.debug("{}.setSpeed({})",this,newSpeed);
|
LOG.debug("{}.setSpeed({})",this,newSpeed);
|
||||||
speed = Math.min(newSpeed,maxSpeed());
|
speed = Math.min(newSpeed,maxSpeed());
|
||||||
if (speed < 0) speed = 0;
|
if (speed < 0) speed = 0;
|
||||||
cars.stream().filter(c -> c instanceof Locomotive).forEach(car -> ((Locomotive)car).setSpeed(speed));
|
locos().forEach(loco -> loco.setSpeed(speed));
|
||||||
plan.stream(t("Set {} to {} {}",this,speed,speedUnit));
|
plan.stream(t("Set {} to {} {}",this,speed,speedUnit));
|
||||||
return properties();
|
return properties();
|
||||||
}
|
}
|
||||||
@@ -1048,6 +1065,22 @@ public class Train extends BaseClass implements Comparable<Train> {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object toggleFunction(Params params) {
|
||||||
|
String name = params.getString(FUNCTION);
|
||||||
|
String error = isNull(name) ? t("No function name passed to toggleFunction(…)") : null;
|
||||||
|
if (isNull(error)) {
|
||||||
|
boolean newVal = functions.get(name) != true;
|
||||||
|
functions.put(name, newVal);
|
||||||
|
List<Locomotive> locos = locos().collect(Collectors.toList());
|
||||||
|
for (int i = 0; i<locos.size(); i++) {
|
||||||
|
boolean first = i==0;
|
||||||
|
boolean last = i==locos.size()-1;
|
||||||
|
locos.get(i).setFunction(name,newVal,first,last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties(error);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name();
|
return name();
|
||||||
|
|||||||
Reference in New Issue
Block a user