Live Data progress: using field's context

This commit is contained in:
rusefi 2019-09-01 15:01:57 -04:00
parent 1ffaa8eea2
commit 33cc21225c
11 changed files with 131 additions and 62 deletions

View File

@ -264,6 +264,7 @@ DISPLAY(DISPLAY_IF(hasEtbPedalPositionSensor))
DISPLAY_TEXT(Pedal);
DISPLAY_SENSOR(PPS);
DISPLAY(DISPLAY_CONFIG(throttlePedalPositionAdcChannel));
DISPLAY_TEXT(eol);
DISPLAY_STATE(ETB_pid)

View File

@ -7,10 +7,10 @@ import java.util.Objects;
* <p>
* (c) Andrey Belomutskiy 2013-2019
*/
public class StateId {
public class LiveDataContext {
private final int id;
public StateId(int id) {
public LiveDataContext(int id) {
this.id = id;
}
@ -20,7 +20,7 @@ public class StateId {
@Override
public String toString() {
return "StateId{" +
return "LiveDataContext{" +
"id=" + id +
'}';
}
@ -29,7 +29,7 @@ public class StateId {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StateId stateId = (StateId) o;
LiveDataContext stateId = (LiveDataContext) o;
return id == stateId.id;
}

View File

@ -3,27 +3,29 @@ package com.rusefi.ui.livedocs;
import com.rusefi.binaryprotocol.BinaryProtocol;
import com.rusefi.config.Field;
import java.util.List;
public abstract class LiveDocHolder {
private final StateId id;
private final List<RefreshActions> actions;
private final LiveDataContext id;
private final RefreshActionsMap actions;
private final Field[] values;
public LiveDocHolder(StateId id, List<RefreshActions> actions, Field[] values) {
public LiveDocHolder(LiveDataContext id, com.rusefi.ui.livedocs.RefreshActionsMap actions, Field[] values) {
this.id = id;
this.actions = actions;
this.values = values;
}
public void update(BinaryProtocol binaryProtocol, byte[] response) {
for (RefreshActions action : actions)
public RefreshActionsMap getActions() {
return actions;
}
public void update(BinaryProtocol binaryProtocol, LiveDataContext context, byte[] response) {
for (RefreshActions action : actions.getActions().get(context))
action.refresh(binaryProtocol, response);
}
public abstract boolean isVisible();
public StateId getId() {
public LiveDataContext getId() {
return id;
}

View File

@ -27,13 +27,15 @@ public enum LiveDocsRegistry {
boolean visible = holder.isVisible();
System.out.println(holder + ": is_visible=" + visible);
if (visible) {
refresh(binaryProtocol, holder);
for (LiveDataContext context : holder.getActions().getActions().keySet()) {
refresh(binaryProtocol, holder, context);
}
}
}
}
private void refresh(BinaryProtocol binaryProtocol, LiveDocHolder holder) {
int liveDocRequestId = holder.getId().getId();
private void refresh(BinaryProtocol binaryProtocol, LiveDocHolder holder, LiveDataContext context) {
int liveDocRequestId = context.getId();
int size = holder.getStructSize();
byte packet[] = new byte[5];
@ -49,6 +51,6 @@ public enum LiveDocsRegistry {
System.arraycopy(responseWithCode, 1, response, 0, size);
holder.update(binaryProtocol, response);
holder.update(binaryProtocol, context, response);
}
}

View File

@ -0,0 +1,26 @@
package com.rusefi.ui.livedocs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RefreshActionsMap {
private final Map<LiveDataContext, List<RefreshActions>> actions = new HashMap<>();
public void put(LiveDataContext context, RefreshActions refreshAction) {
actions.putIfAbsent(context, new ArrayList<>());
actions.get(context).add(refreshAction);
}
public void addAll(RefreshActionsMap actions) {
for (Map.Entry<LiveDataContext, List<RefreshActions>> e : actions.actions.entrySet()) {
for (RefreshActions action : e.getValue())
put(e.getKey(), action);
}
}
public Map<LiveDataContext, List<RefreshActions>> getActions() {
return actions;
}
}

View File

@ -5,6 +5,8 @@ import com.rusefi.config.generated.EngineState;
import com.rusefi.config.generated.Fields;
import com.rusefi.config.generated.PidState;
import com.rusefi.config.generated.TriggerState;
import com.rusefi.ui.livedocs.LiveDataContext;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@ -26,25 +28,35 @@ public enum StateDictionary {
}
public Field[] getValue(String state) {
String indexFieldName = "LDS_" + state.toUpperCase() + "_STATE_INDEX";
java.lang.reflect.Field field = null;
try {
field = Fields.class.getField(indexFieldName);
} catch (NoSuchFieldException e) {
throw new IllegalStateException(e);
}
Objects.requireNonNull(field, "Field " + indexFieldName);
int indexValue;
try {
indexValue = (int) field.get(null);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
Field[] result = map.get(indexValue);
String indexFieldName = getContextIndexFieldName(state);
LiveDataContext indexValue = getStateContext(indexFieldName);
Field[] result = map.get(indexValue.getId());
if (result == null) {
throw new IllegalStateException("Nothing for " + indexFieldName + "/" + indexValue);
}
return result;
}
@NotNull
public static String getContextIndexFieldName(String state) {
return "LDS_" + state.toUpperCase() + "_STATE_INDEX";
}
public static LiveDataContext getStateContext(String contextIndexFieldName) {
java.lang.reflect.Field field;
try {
field = Fields.class.getField(contextIndexFieldName);
} catch (NoSuchFieldException e) {
throw new IllegalStateException(e);
}
Objects.requireNonNull(field, "Field " + contextIndexFieldName);
int indexValue;
try {
indexValue = (int) field.get(null);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
return new LiveDataContext(indexValue);
}
}

View File

@ -11,6 +11,7 @@ public class ElectronicThrottleMeta {
new TextRequest("eol"),
new TextRequest("Pedal"),
new SensorRequest("PPS"),
new ConfigRequest("throttlePedalPositionAdcChannel"),
new TextRequest("eol"),
new TextRequest("Output"),
new FieldRequest("ETB_pid", "output"),

View File

@ -6,15 +6,16 @@ import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Multi-line horizontal flow panel.
*
*
* <p>
* <p>
* (c) Andrey Belomutskiy 2013-2019
*/
public class ActionPanel {
List<RefreshActions> actionsList = new ArrayList<>();
private final RefreshActionsMap refreshActions = new RefreshActionsMap();
private final JPanel panel = new JPanel(new MigLayout());
private JPanel currentLinePanel;
@ -42,4 +43,16 @@ public class ActionPanel {
panel.add(currentLinePanel, "wrap");
}
}
public RefreshActionsMap getRefreshActions() {
return refreshActions;
}
public void actionsListAdd(LiveDataContext context, RefreshActions refreshAction) {
refreshActions.put(context, refreshAction);
}
public void actionsListAddAll(RefreshActionsMap actions) {
refreshActions.addAll(actions);
}
}

View File

@ -10,17 +10,16 @@ import java.util.List;
* (c) Andrey Belomutskiy 2013-2019
*/
public class IfConditionPanel {
private final List<RefreshActions> actionsList = new ArrayList<>();
private final RefreshActionsMap actionsList;
private final JPanel panel = new JPanel(new MigLayout());
public IfConditionPanel(JPanel result, List<RefreshActions> combined) {
public IfConditionPanel(JPanel result, RefreshActionsMap actionsList) {
// todo: do we really need this proxy panel or can we just use parameter value?
panel.add(result);
// todo: do we really need this list or can we just use parameter value?
actionsList.addAll(combined);
this.actionsList = actionsList;
}
public List<RefreshActions> getActionsList() {
public RefreshActionsMap getActionsList() {
return actionsList;
}

View File

@ -24,8 +24,6 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import static com.rusefi.config.Field.niceToString;
@ -38,13 +36,13 @@ public class LiveDocPanel {
private static final int LIVE_DATA_PRECISION = 2;
@NotNull
static JPanel createPanel(String title, String settingsInstancePrefix, final int integerId, Field[] values, Request[] content) {
StateId id = new StateId(integerId);
static JPanel createPanel(String title, String settingsInstancePrefix, final int defaultContextId, Field[] values, Request[] content) {
LiveDataContext defaultContext = new LiveDataContext(defaultContextId);
ActionPanel ap = createComponents(title, content, values, settingsInstancePrefix);
ActionPanel ap = createComponents(title, content, values, settingsInstancePrefix, defaultContext);
JPanel panel = ap.getPanel();
LiveDocHolder holder = new LiveDocHolder(id, ap.actionsList, values) {
LiveDocHolder holder = new LiveDocHolder(defaultContext, ap.getRefreshActions(), values) {
@Override
public boolean isVisible() {
boolean isVisible = !panel.getVisibleRect().isEmpty();
@ -61,7 +59,7 @@ public class LiveDocPanel {
return c.isVisible() && (parent == null || isRecursivelyVisible(parent));
}
private static ActionPanel createComponents(String title, Request[] content, Field[] values, String settingsInstancePrefix) {
private static ActionPanel createComponents(String title, Request[] content, Field[] values, String settingsInstancePrefix, LiveDataContext defaultContext) {
ActionPanel result = new ActionPanel(title);
for (Request r : content) {
@ -74,12 +72,13 @@ public class LiveDocPanel {
}
} else if (r instanceof FieldRequest) {
FieldRequest request = (FieldRequest) r;
LiveDataContext context = getFieldContext(defaultContext, request.getStateContext());
Field field = getField(values, request);
JLabel label = new JLabel("*");
label.setIcon(UiUtils.loadIcon("livedocs/variable.png"));
label.setToolTipText("Variable " + field.getName());
result.addControl(label);
result.actionsList.add(new RefreshActions() {
result.actionsListAdd(context, new RefreshActions() {
@Override
public void refresh(BinaryProtocol bp, byte[] response) {
Number fieldValue = field.getValue(new ConfigurationImage(response));
@ -94,19 +93,19 @@ public class LiveDocPanel {
JLabel label = new JLabel("*");
label.setIcon(UiUtils.loadIcon("livedocs/setting.png"));
label.setToolTipText(getTooltipText(field.getName()));
result.actionsList.add(new RefreshActions() {
result.addControl(label);
// todo: use different notification flow altogether since configuration has nothing to do with live data structures
result.actionsListAdd(new LiveDataContext(Fields.LDS_ENGINE_STATE_INDEX), new RefreshActions() {
@Override
public void refresh(BinaryProtocol bp, byte[] response) {
String value = field.getAnyValue(bp.getController()).toString();
label.setText(value);
}
});
result.addControl(label);
} else if (r instanceof SensorRequest) {
SensorRequest request = (SensorRequest) r;
Sensor sensor = Sensor.find(request.getValue());
JLabel label = new JLabel("*");
result.addControl(label);
label.setIcon(UiUtils.loadIcon("livedocs/gauge.png"));
label.setToolTipText("Sensor " + request.getValue());
label.addMouseListener(new MouseAdapter() {
@ -118,19 +117,19 @@ public class LiveDocPanel {
}
}
});
result.actionsList.add(new RefreshActions() {
result.addControl(label);
SensorCentral.getInstance().addListener(sensor, new SensorCentral.SensorListener() {
@Override
public void refresh(BinaryProtocol bp, byte[] response) {
double value = SensorCentral.getInstance().getValue(sensor);
public void onSensorUpdate(double value) {
label.setText(niceToString(value, LIVE_DATA_PRECISION));
}
});
} else if (r instanceof IfRequest) {
IfRequest request = (IfRequest) r;
IfConditionPanel panel = createIfRequestPanel(request, values);
IfConditionPanel panel = createIfRequestPanel(request, values, defaultContext);
result.actionsList.addAll(panel.getActionsList());
result.actionsListAddAll(panel.getActionsList());
result.addControl(panel.getPanel());
} else {
@ -140,6 +139,15 @@ public class LiveDocPanel {
return result;
}
private static LiveDataContext getFieldContext(LiveDataContext defaultContext, String stateContext) {
if (stateContext.isEmpty()) {
return defaultContext;
} else {
String indexFieldName = StateDictionary.getContextIndexFieldName(stateContext);
return StateDictionary.getStateContext(indexFieldName);
}
}
private static Field getField(Field[] defaultContext, FieldRequest request) {
Field[] context;
if (request.getStateContext().isEmpty()) {
@ -158,8 +166,7 @@ public class LiveDocPanel {
return "Configuration " + dialogField.getUiName() + " (" + configurationFieldName + ")";
}
private static IfConditionPanel createIfRequestPanel(IfRequest request, Field[] values) {
private static IfConditionPanel createIfRequestPanel(IfRequest request, Field[] values, LiveDataContext defaultContext) {
Field conditionField = Field.findField(values, "", request.getVariable());
JPanel result = new JPanel(new VerticalFlowLayout());
@ -168,16 +175,18 @@ public class LiveDocPanel {
result.add(conditionLabel);
ActionPanel trueAP = createComponents("", request.trueBlock.toArray(new Request[0]), values, "");
ActionPanel falseAP = createComponents("", request.falseBlock.toArray(new Request[0]), values, "");
ActionPanel trueAP = createComponents("", request.trueBlock.toArray(new Request[0]), values, "", defaultContext);
ActionPanel falseAP = createComponents("", request.falseBlock.toArray(new Request[0]), values, "", defaultContext);
result.add(trueAP.getPanel());
result.add(falseAP.getPanel());
List<RefreshActions> combined = new ArrayList<>(trueAP.actionsList);
combined.addAll(falseAP.actionsList);
RefreshActionsMap combined = trueAP.getRefreshActions();
combined.addAll(falseAP.getRefreshActions());
combined.add(new RefreshActions() {
LiveDataContext context = getFieldContext(defaultContext, request.getStateContext());
combined.put(context, new RefreshActions() {
@Override
public void refresh(BinaryProtocol bp, byte[] response) {
int value = (int) conditionField.getValue(new ConfigurationImage(response));

View File

@ -23,6 +23,10 @@ public class IfRequest extends Request {
this.falseBlock.addAll(Arrays.asList(falseBlock));
}
public String getStateContext() {
return stateContext;
}
@Override
public String toString() {
return "IfRequest{" +