started refactoring

This commit is contained in:
Stephan Richter
2021-06-17 20:55:07 +02:00
parent 002f08035b
commit 178d8f1622
14 changed files with 181 additions and 270 deletions

View File

@@ -82,6 +82,7 @@ public abstract class Action extends BaseClass {
@SuppressWarnings("unchecked")
public static <T extends Action> T create(String type,BaseClass parent) {
if (isNull(type)) return null;
try {
return (T) Class.forName(PREFIX+"."+type).getDeclaredConstructor(BaseClass.class).newInstance(parent);
} catch (Exception e) {

View File

@@ -74,7 +74,7 @@ public abstract class Condition extends BaseClass {
}
public static Condition create(String type) {
if (type == null) return null;
if (isNull(type)) return null;
try {
return (Condition) Class.forName(PREFIX+"."+type).getDeclaredConstructor().newInstance();
} catch (Exception e) {

View File

@@ -1,114 +0,0 @@
package de.srsoftware.web4rail.devices;
import java.util.HashMap;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Params;
public class Function extends BaseClass{
protected static final Logger LOG = LoggerFactory.getLogger(Function.class);
public static final String DIRECTIONAL = "directional";
public static final String FORWARD = "forward";
public static final String REVERSE = "reverse";
private boolean directional;
private boolean reverse;
private boolean forward;
private String type;
private String name;
public Function(String type, String name, Params dirs) {
this.type = type;
this.name = name;
for (Entry<String, Object> entry : dirs.entrySet()) setDirection(entry.getKey(), "on".equals(entry.getValue()));
}
public Function(JSONObject json) {
if (json.has(NAME)) name = json.getString(NAME);
if (json.has(TYPE)) type = json.getString(TYPE);
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() {
return directional;
}
public boolean isForward() {
return forward;
}
public boolean isReverse() {
return reverse;
}
public JSONObject json() {
JSONArray directions = new JSONArray();
if (directional) directions.put(DIRECTIONAL);
if (forward) directions.put(FORWARD);
if (reverse) directions.put(REVERSE);
JSONObject json = new JSONObject();
if (!directions.isEmpty()) json.put(DIRECTION, directions);
json.put(NAME, name);
if (isSet(type)) json.put(TYPE, type);
return json;
}
public static JSONObject json(HashMap<String, HashMap<Integer, Function>> functions) {
JSONObject json = new JSONObject();
for (Entry<String, HashMap<Integer, Function>> entry : functions.entrySet()) {
HashMap<Integer, Function> map = entry.getValue();
if (map.isEmpty()) continue;
String type = entry.getKey();
JSONObject list = new JSONObject();
for (Integer idx : map.keySet()) list.put(idx.toString(), map.get(idx).json());
json.put(type, list);
}
return json;
}
public String name() {
return name;
}
private void setDirection(String key,boolean value) {
switch (key) {
case DIRECTIONAL:
directional = value;
break;
case FORWARD:
forward = value;
break;
case REVERSE:
reverse = value;
break;
default:
LOG.debug("unknwon direction {}",key);
}
}
@Override
public String toString() {
return (BaseClass.isSet(name)?name+":":"") +type+"("+(forward?BaseClass.t("forward"):"")+(reverse?" "+BaseClass.t("reverse"):"")+(directional?" "+BaseClass.t("directional"):"").trim()+")";
}
public String type() {
return type;
}
}

View File

@@ -0,0 +1,5 @@
package de.srsoftware.web4rail.functions;
public class Coupler extends Function {
}

View File

@@ -0,0 +1,5 @@
package de.srsoftware.web4rail.functions;
public class CustomFunction extends Function {
}

View File

@@ -0,0 +1,69 @@
package de.srsoftware.web4rail.functions;
import java.util.List;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Params;
import de.srsoftware.web4rail.devices.Decoder;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Select;
public abstract class Function extends BaseClass{
public static final String NEW = "new_function";
private static final String PACKAGE = Function.class.getPackageName();
private static final String INDEX = "index";
static final String FORWARD = "forward";
static final String REVERSE = "reverse";
private int decoderFunction = 1;
public static Tag selector() {
Select selector = new Select(NEW);
selector.addOption("", t("Select function"));
for (Class<? extends Function> fun : List.of(HeadLight.class,TailLight.class,InteriorLight.class,Coupler.class,CustomFunction.class)) {
String className = fun.getSimpleName();
selector.addOption(className,t(className));
}
return selector;
}
public static Function create(String className) {
if (isNull(className)) return null;
try {
return (Function) Class.forName(PACKAGE+"."+className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Fieldset form(Decoder decoder) {
Fieldset fieldset = new Fieldset(name());
String prefix = "functions/"+id()+"/";
Select select = new Select(prefix+"index");
for (int i=1; i<=decoder.numFunctions(); i++) {
Tag option = select.addOption(i);
if (i == decoderFunction) option.attr("selected", "selected");
}
select.addTo(new Label(t("Decoder function")+COL)).addTo(fieldset);
return fieldset;
}
private String name() {
return t(getClass().getSimpleName());
}
@Override
public Object update(Params params) {
if (params.containsKey(INDEX)) decoderFunction = params.getInt(INDEX);
return super.update(params);
}
}

View File

@@ -0,0 +1,25 @@
package de.srsoftware.web4rail.functions;
import java.util.HashSet;
import org.json.JSONObject;
/**
* @author Stephan Richter
*
*/
public class FunctionList extends HashSet<Function>{
private static final long serialVersionUID = 8013610745085726979L;
public JSONObject json() {
// TODO Auto-generated method stub
return null;
}
public void load(JSONObject jsonObject) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,32 @@
package de.srsoftware.web4rail.functions;
import de.srsoftware.web4rail.Params;
import de.srsoftware.web4rail.devices.Decoder;
import de.srsoftware.web4rail.tags.Checkbox;
import de.srsoftware.web4rail.tags.Fieldset;
public class HeadLight extends Function {
private boolean forward,reverse;
public HeadLight() {
// TODO Auto-generated constructor stub
}
@Override
public Fieldset form(Decoder decoder) {
Fieldset fieldset = super.form(decoder);
String prefix = "functions/"+id()+"/";
new Checkbox(prefix+FORWARD, t(FORWARD), forward).addTo(fieldset);
new Checkbox(prefix+REVERSE, t(REVERSE), reverse).addTo(fieldset);
return fieldset;
}
@Override
public Object update(Params params) {
if (params.containsKey(FORWARD)) forward = "on".equals(params.get(FORWARD));
if (params.containsKey(REVERSE)) reverse = "on".equals(params.get(REVERSE));
return super.update(params);
}
}

View File

@@ -0,0 +1,5 @@
package de.srsoftware.web4rail.functions;
public class InteriorLight extends Function {
}

View File

@@ -0,0 +1,5 @@
package de.srsoftware.web4rail.functions;
public class TailLight extends Function {
}

View File

@@ -3,10 +3,8 @@ 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.Map.Entry;
import java.util.Vector;
import org.json.JSONObject;
@@ -17,9 +15,9 @@ import de.srsoftware.web4rail.Constants;
import de.srsoftware.web4rail.Params;
import de.srsoftware.web4rail.Plan;
import de.srsoftware.web4rail.devices.Decoder;
import de.srsoftware.web4rail.devices.Function;
import de.srsoftware.web4rail.functions.Function;
import de.srsoftware.web4rail.functions.FunctionList;
import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Checkbox;
import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Form;
import de.srsoftware.web4rail.tags.Input;
@@ -38,7 +36,7 @@ public class Locomotive extends Car implements Constants{
public static final String LOCOMOTIVE = "locomotive";
private static final String ACTION_MAPPING = "mapping";
private static final String FUNCTIONS = "functions";
private final HashMap<String,HashMap<Integer,Function>> functions = new HashMap<>();
private FunctionList functions = new FunctionList();
private int speed = 0;
//private TreeMap<Integer,Integer> cvs = new TreeMap<Integer, Integer>();
private Decoder decoder;
@@ -187,14 +185,7 @@ public class Locomotive extends Car implements Constants{
}
if (isSet(train)) {
for (Entry<String, Boolean> fEntry : train.functions().entrySet()) {
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);
@@ -224,39 +215,23 @@ public class Locomotive extends Car implements Constants{
new Input(REALM, REALM_LOCO).hideIn(form);
new Input(ACTION, ACTION_MAPPING).hideIn(form);
new Input(ID,id()).hideIn(form);
for (int i=0; i<decoder.numFunctions(); i++) functionMapping(i+1).addTo(form);
for (Function fun : functions) {
fun.form(decoder).addTo(form);
}
Fieldset newFun = new Fieldset(t("Add function"));
Function.selector().addTo(newFun).addTo(form);
return new Button(t("Save"), form).addTo(form).addTo(fieldset);
}
private Tag functionMapping(int index) {
Fieldset mapping = new Fieldset(t("Function {}",index));
Tag type = new Tag("div");
new Checkbox(functionName(index,TYPE,HEADLIGHT), t("Headlight"), isMapped(HEADLIGHT,index), true).addTo(type);
new Checkbox(functionName(index,TYPE,TAILLIGHT), t("Tail light"), isMapped(TAILLIGHT,index), true).addTo(type);
new Checkbox(functionName(index,TYPE,INTERIOR_LIGHT),t("Interior light"),isMapped(INTERIOR_LIGHT,index), true).addTo(type);
new Checkbox(functionName(index,TYPE,COUPLER),t("Coupler"),isMapped(COUPLER,index), true).addTo(type);
Tag dir = new Tag("div");
new Checkbox(functionName(index,DIRECTION,Function.DIRECTIONAL), t("directional"), isDirectional(index), true).addTo(dir);
new Checkbox(functionName(index,DIRECTION,Function.FORWARD), t("forward"), isForward(index), true).addTo(dir);
new Checkbox(functionName(index,DIRECTION,Function.REVERSE), t("reverse"), isReverse(index), true).addTo(dir);
Table table = new Table();
table.addRow(t("Name"),new Input(functionName(index,NAME), functionName(index)));
table.addHead(t("Type"),t("Direction"));
table.addRow(type,dir);
return table.addTo(mapping);
return mapping;
}
private String functionName(int index) {
for (HashMap<Integer, Function> value : functions.values()) {
Function f = value.get(index);
if (isSet(f)) return f.name();
}
return "F"+index;
}
private static String functionName(Object...parts) {
StringBuilder sb = new StringBuilder(FUNCTIONS);
@@ -264,50 +239,13 @@ public class Locomotive extends Car implements Constants{
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) {
for (HashMap<Integer, Function> value : functions.values()) {
Function f = value.get(index);
if (isSet(f) && f.isDirectional()) return true;
}
return false;
}
private boolean isForward(int index) {
for (HashMap<Integer, Function> value : functions.values()) {
Function f = value.get(index);
if (isSet(f) && f.isForward()) return true;
}
return false;
}
private boolean isReverse(int index) {
for (HashMap<Integer, Function> value : functions.values()) {
Function f = value.get(index);
if (isSet(f) && f.isReverse()) return true;
}
return false;
}
private boolean isMapped(String type, int funNum) {
HashMap<Integer, Function> fun = functions.get(type);
return isSet(fun) && fun.containsKey(funNum);
}
@Override
public JSONObject json() {
JSONObject json = super.json();
JSONObject loco = new JSONObject();
json.put(LOCOMOTIVE, loco);
if (isSet(decoder)) loco.put(Decoder.DECODER,decoder.json());
if (functions.size()>0) loco.put(FUNCTIONS,Function.json(functions));
if (functions.size()>0) loco.put(FUNCTIONS,functions.json());
return json;
}
@@ -329,22 +267,12 @@ public class Locomotive extends Car implements Constants{
}
if (isSet(decoder)) decoder.setLoco(this,false);
if (loco.has(FUNCTIONS)) loadFunctions(loco);
if (loco.has(FUNCTIONS)) functions.load(loco.getJSONObject(FUNCTIONS));
}
return this;
}
private void loadFunctions(JSONObject loco) {
JSONObject json = loco.getJSONObject(FUNCTIONS);
for (String type : json.keySet()) {
JSONObject map = json.getJSONObject(type);
HashMap<Integer, Function> funMap = functions.get(type);
if (isNull(funMap)) functions.put(type, funMap = new HashMap<>());
for (String idx : map.keySet()) funMap.put(Integer.parseInt(idx), new Function(map.getJSONObject(idx)));
}
}
public static Window manager() {
Window win = new Window("loco-manager", t("Locomotive manager"));
new Tag("h4").content(t("known locomotives")).addTo(win);
@@ -405,25 +333,6 @@ public class Locomotive extends Car implements Constants{
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
* @param newSpeed
@@ -486,33 +395,19 @@ public class Locomotive extends Car implements Constants{
return properties();
}
private void updateFunction(int num, Params settings) {
LOG.debug("Settings for function {}: {}",num,settings);
Params dirs = settings.getParams(DIRECTION);
Params types = settings.getParams(TYPE);
String name = settings.getString(NAME);
for (String type : types.keySet()) {
boolean enabled = "on".equals(types.get(type));
HashMap<Integer, Function> funList = functions.get(type);
if (enabled && isNull(funList)) {
funList = new HashMap<>();
functions.put(type, funList);
}
if (enabled) {
funList.put(num, new Function(type, name, dirs)); // TODO
} else {
if (isSet(funList)) {
funList.remove(num);
if (funList.isEmpty()) functions.remove(type);
}
private Object updateMapping(Params params) {
if (params.containsKey(Function.NEW)) {
String type = params.getString(Function.NEW);
if (!type.isEmpty()) {
Function newFun = Function.create(type);
if (isSet(newFun)) functions.add(newFun.register());
}
}
}
private Object updateMapping(Params params) {
if (params.containsKey(FUNCTIONS)) {
for (Entry<String, Object> entry : params.getParams(FUNCTIONS).entrySet()) {
updateFunction(Integer.parseInt(entry.getKey()),(Params) entry.getValue());
Params funs = params.getParams(FUNCTIONS);
for (String id : funs.keySet()) {
Function function = BaseClass.get(new Id(id));
if (isSet(function)) function.update(funs.getParams(id));
}
}
return properties();

View File

@@ -12,7 +12,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;
@@ -533,16 +532,6 @@ public class Train extends BaseClass implements Comparable<Train> {
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() {
return locos().count() > 0;
}
@@ -1068,16 +1057,7 @@ 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;
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);
}
}
// TODO
return properties(error);
}