Version bump:
first functional version of new function mapping.
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>1.4.46</version>
|
||||
<version>1.5.0</version>
|
||||
<name>Web4Rail</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Java Model Railway Control</description>
|
||||
|
||||
@@ -45,7 +45,6 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
private static final String CV = "cv";
|
||||
private static final String NUM_FUNCTIONS = "numFunctions";
|
||||
private String type;
|
||||
private Locomotive loco;
|
||||
private int numFunctions = 2;
|
||||
private int step;
|
||||
private boolean reverse;
|
||||
@@ -78,22 +77,26 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
}
|
||||
|
||||
private Window dismount() {
|
||||
if (isNull(loco)) return properties();
|
||||
Locomotive locomotive = loco;
|
||||
Locomotive locomotive = parent();
|
||||
if (isNull(locomotive)) return properties();
|
||||
locomotive.removeDecoder(this);
|
||||
loco = null;
|
||||
parent(null);
|
||||
addLogEntry(t("Removed decoder from \"{}\".",locomotive));
|
||||
return locomotive.properties();
|
||||
}
|
||||
|
||||
public StringBuilder functions() {
|
||||
HashSet<Integer> enabledFunctions = new HashSet<>();
|
||||
for (Function fun : loco.functions()) {
|
||||
if (fun.enabled(this)) enabledFunctions.add(fun.index());
|
||||
}
|
||||
|
||||
Locomotive loco = parent();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i=1; i<=numFunctions; i++) sb.append(" ").append(enabledFunctions.contains(i)?1:0);
|
||||
|
||||
if (isSet(loco)) {
|
||||
HashSet<Integer> enabledFunctions = new HashSet<>();
|
||||
for (Function fun : loco.functions()) {
|
||||
if (fun.enabled(this)) enabledFunctions.add(fun.index());
|
||||
}
|
||||
|
||||
for (int i=1; i<=numFunctions; i++) sb.append(" ").append(enabledFunctions.contains(i)?1:0);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
@@ -162,6 +165,12 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
public int numFunctions() {
|
||||
return numFunctions ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locomotive parent() {
|
||||
BaseClass p = super.parent();
|
||||
return p instanceof Locomotive ? (Locomotive) p : null;
|
||||
}
|
||||
|
||||
private Window program(Params params) {
|
||||
String error = null;
|
||||
@@ -239,6 +248,7 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
formInputs.add(t("Protocol"),div);
|
||||
formInputs.add(t("Address"),new Tag("span").content(""+address()));
|
||||
formInputs.add(t("Number of functions"),new Input(NUM_FUNCTIONS,numFunctions).numeric());
|
||||
Locomotive loco = parent();
|
||||
if (isSet(loco)) formInputs.add(t("Locomotive"),loco.button(loco.name()));
|
||||
postForm.add(programming());
|
||||
return super.properties(preForm, formInputs, postForm, errorMessages);
|
||||
@@ -270,15 +280,15 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
selector.addOption(-1,t("no decoder"));
|
||||
selector.addOption(0,t("new decoder"));
|
||||
for (Decoder d: decoders) {
|
||||
if (freeOnly && isSet(d.loco)) continue;
|
||||
if (freeOnly && isSet(d.parent())) continue;
|
||||
selector.addOption(d.id(), d);
|
||||
}
|
||||
return selector;
|
||||
}
|
||||
|
||||
public Decoder setLoco(Locomotive locomotive, boolean log) {
|
||||
loco = locomotive;
|
||||
if (log) addLogEntry(t("Mounted into \"{}\".",loco));
|
||||
parent(locomotive);
|
||||
if (log) addLogEntry(t("Mounted into \"{}\".",locomotive));
|
||||
locomotive.setDecoder(this,log);
|
||||
return this;
|
||||
}
|
||||
@@ -332,11 +342,7 @@ public class Decoder extends BaseClass implements Constants, Device {
|
||||
if (params.containsKey(TYPE)) type = params.getString(TYPE);
|
||||
if (params.containsKey(Device.PROTOCOL)) setProtocol(Protocol.valueOf(params.getString(Device.PROTOCOL)));
|
||||
if (params.containsKey(NUM_FUNCTIONS)) numFunctions = params.getInt(NUM_FUNCTIONS);
|
||||
Locomotive loco = parent();
|
||||
return isSet(loco) ? loco.properties() : properties();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ public abstract class Function extends BaseClass{
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public boolean enabled(Decoder decoder) {
|
||||
return enabled;
|
||||
}
|
||||
@@ -101,8 +105,9 @@ public abstract class Function extends BaseClass{
|
||||
return selector;
|
||||
}
|
||||
|
||||
public void setState(boolean enabled) {
|
||||
public Function setState(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,4 +44,13 @@ public class FunctionList extends HashSet<Function> implements Constants{
|
||||
stream().filter(fun -> name.equals(fun.name())).forEach(fun -> fun.setState(enabled));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public HashSet<Function> with(String name) {
|
||||
HashSet<Function> subset = new HashSet<>();
|
||||
for (Function f: this) {
|
||||
if (f.name().equals(name)) subset.add(f);
|
||||
}
|
||||
return subset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
package de.srsoftware.web4rail.functions;
|
||||
|
||||
public class HeadLight extends DirectedFunction {
|
||||
import de.srsoftware.web4rail.devices.Decoder;
|
||||
import de.srsoftware.web4rail.moving.Locomotive;
|
||||
|
||||
public class HeadLight extends DirectedFunction {
|
||||
@Override
|
||||
public boolean enabled(Decoder decoder) {
|
||||
Locomotive loco = decoder.parent();
|
||||
if (isNull(loco) || !loco.isFirst()) return false;
|
||||
boolean result = isSet(loco) && loco.isFirst() && super.enabled(decoder);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package de.srsoftware.web4rail.functions;
|
||||
|
||||
public class TailLight extends DirectedFunction {
|
||||
import de.srsoftware.web4rail.devices.Decoder;
|
||||
import de.srsoftware.web4rail.moving.Locomotive;
|
||||
|
||||
public class TailLight extends DirectedFunction {
|
||||
@Override
|
||||
public boolean enabled(Decoder decoder) {
|
||||
Locomotive loco = decoder.parent();
|
||||
if (isNull(loco) || !loco.isLast()) return false;
|
||||
return super.enabled(decoder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
protected int maxSpeedReverse = 0;
|
||||
protected boolean orientation = FORWARD;
|
||||
protected long distanceCounter = 0;
|
||||
|
||||
private boolean isFirst,isLast;
|
||||
|
||||
public Car(String name) {
|
||||
this(name,null);
|
||||
@@ -146,6 +148,24 @@ public class Car extends BaseClass implements Comparable<Car>{
|
||||
public long drivenDistance() {
|
||||
return distanceCounter;
|
||||
}
|
||||
|
||||
public boolean isFirst() {
|
||||
return isFirst;
|
||||
}
|
||||
|
||||
public Car isFirst(boolean first) {
|
||||
isFirst = first;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isLast() {
|
||||
return isLast;
|
||||
}
|
||||
|
||||
public Car isLast(boolean last) {
|
||||
isLast = last;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JSONObject json() {
|
||||
JSONObject json = super.json();
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.srsoftware.web4rail.moving;
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
@@ -100,23 +101,24 @@ public class Locomotive extends Car implements Constants{
|
||||
public static Fieldset cockpit(BaseClass locoOrTrain) {
|
||||
int speed = 0;
|
||||
String realm = null;
|
||||
Train train = null;
|
||||
final Train train;
|
||||
final Locomotive loco;
|
||||
int maxSpeed = 0;
|
||||
String id = null;
|
||||
if (locoOrTrain instanceof Locomotive) {
|
||||
loco = (Locomotive) locoOrTrain;
|
||||
loco = (Locomotive) locoOrTrain;
|
||||
train = null;
|
||||
realm = REALM_LOCO;
|
||||
speed = loco.speed;
|
||||
maxSpeed = loco.orientation ? loco.maxSpeedForward : loco.maxSpeedReverse;
|
||||
id = "loco_"+loco.id();
|
||||
} else if (locoOrTrain instanceof Train) {
|
||||
loco = null;
|
||||
train = (Train)locoOrTrain;
|
||||
realm = REALM_TRAIN;
|
||||
speed = train.speed;
|
||||
maxSpeed = train.maxSpeed();
|
||||
id = "train_"+train.id();
|
||||
loco = null;
|
||||
} else return null;
|
||||
|
||||
HashMap<String,Object> params = new HashMap<String, Object>(Map.of(REALM,realm,ID,locoOrTrain.id()));
|
||||
@@ -178,7 +180,12 @@ public class Locomotive extends Car implements Constants{
|
||||
}
|
||||
|
||||
if (isSet(train)) {
|
||||
|
||||
train.functionNames().sorted().forEach(name -> {
|
||||
Button btn = train.button(name, Map.of(ACTION,ACTION_TOGGLE_FUNCTION,FUNCTION,name));
|
||||
if (train.functionEnabled(name)) btn.clazz("active");
|
||||
btn.addTo(functions);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
functions.addTo(fieldset);
|
||||
@@ -222,7 +229,7 @@ public class Locomotive extends Car implements Constants{
|
||||
return new Button(t("Save"), form).addTo(form).addTo(fieldset);
|
||||
}
|
||||
|
||||
private Stream<String> functionNames() {
|
||||
public Stream<String> functionNames() {
|
||||
return functions.stream().map(Function::name).sorted().distinct();
|
||||
}
|
||||
|
||||
@@ -230,6 +237,10 @@ public class Locomotive extends Car implements Constants{
|
||||
return functions;
|
||||
}
|
||||
|
||||
public HashSet<Function> functions(String name){
|
||||
return functions.with(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
JSONObject json = super.json();
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -29,6 +28,7 @@ import de.srsoftware.web4rail.Params;
|
||||
import de.srsoftware.web4rail.Plan;
|
||||
import de.srsoftware.web4rail.Plan.Direction;
|
||||
import de.srsoftware.web4rail.Route;
|
||||
import de.srsoftware.web4rail.functions.Function;
|
||||
import de.srsoftware.web4rail.tags.Button;
|
||||
import de.srsoftware.web4rail.tags.Checkbox;
|
||||
import de.srsoftware.web4rail.tags.Fieldset;
|
||||
@@ -100,7 +100,6 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
private Route nextPreparedRoute;
|
||||
|
||||
private BrakeProcess brake;
|
||||
private HashMap<String,Boolean> functions = new HashMap<>();
|
||||
|
||||
public static Object action(Params params, Plan plan) throws IOException {
|
||||
String action = params.getString(ACTION);
|
||||
@@ -532,6 +531,16 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
return setSpeed(speed+steps);
|
||||
}
|
||||
|
||||
public boolean functionEnabled(String name) {
|
||||
return locos().flatMap(
|
||||
loco -> loco.functions().stream().filter(f -> f.enabled() && f.name().equals(name))
|
||||
).findAny().isPresent();
|
||||
}
|
||||
|
||||
public Stream<String> functionNames() {
|
||||
return locos().flatMap(Locomotive::functionNames).distinct();
|
||||
}
|
||||
|
||||
private boolean hasLoco() {
|
||||
return locos().count() > 0;
|
||||
}
|
||||
@@ -1057,7 +1066,14 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
private Object toggleFunction(Params params) {
|
||||
String name = params.getString(FUNCTION);
|
||||
String error = isNull(name) ? t("No function name passed to toggleFunction(…)") : null;
|
||||
// TODO
|
||||
boolean enable = !functionEnabled(name);
|
||||
locos().forEach(loco -> {
|
||||
Function any = null;
|
||||
for (Function f : loco.functions(name)) {
|
||||
any = f.setState(enable);
|
||||
}
|
||||
if (isSet(any)) loco.decoder().queue();
|
||||
});
|
||||
return properties(error);
|
||||
}
|
||||
|
||||
@@ -1074,12 +1090,18 @@ public class Train extends BaseClass implements Comparable<Train> {
|
||||
*/
|
||||
public Train turn() {
|
||||
LOG.debug("{}.turn()",this);
|
||||
setSpeed(0);
|
||||
for (Car car : cars) car.turn();
|
||||
reverse(cars);
|
||||
updateEnds();
|
||||
for (Car car : cars) car.turn();
|
||||
return reverse();
|
||||
}
|
||||
|
||||
private void updateEnds() {
|
||||
for (Car car : cars) car.isFirst(false).isLast(false);
|
||||
cars.firstElement().isFirst(true);
|
||||
cars.lastElement().isLast(true);
|
||||
}
|
||||
|
||||
public void unTrace(Tile tile) {
|
||||
if (isSet(trace)) trace.remove(tile);
|
||||
if (isSet(stuckTrace)) stuckTrace.remove(tile);
|
||||
|
||||
Reference in New Issue
Block a user