This commit is contained in:
parent
a8f456b807
commit
451ace3f5d
|
@ -0,0 +1,9 @@
|
|||
<component name="libraryTable">
|
||||
<library name="snakeyaml">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../java_tools/configuration_definition/lib/snakeyaml.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
|
@ -3,6 +3,8 @@
|
|||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/autotest/autotest.iml" filepath="$PROJECT_DIR$/autotest/autotest.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../java_tools/configuration_definition/configuration_definition.iml" filepath="$PROJECT_DIR$/../java_tools/configuration_definition/configuration_definition.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../java_tools/enum_to_string/enum_to_string.iml" filepath="$PROJECT_DIR$/../java_tools/enum_to_string/enum_to_string.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/io/io.iml" filepath="$PROJECT_DIR$/io/io.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/logging/logging.iml" filepath="$PROJECT_DIR$/logging/logging.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/models/models.iml" filepath="$PROJECT_DIR$/models/models.iml" />
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.rusefi.core.Pair;
|
|||
import com.rusefi.core.Sensor;
|
||||
import com.rusefi.core.SensorCentral;
|
||||
import com.rusefi.io.*;
|
||||
import com.rusefi.ui.livedocs.LiveDocsRegistry;
|
||||
import jssc.SerialPortException;
|
||||
|
||||
import java.io.EOFException;
|
||||
|
@ -141,6 +142,7 @@ public class BinaryProtocol implements BinaryProtocolCommands {
|
|||
String text = requestPendingMessages();
|
||||
if (text != null)
|
||||
listener.onDataArrived((text + "\r\n").getBytes());
|
||||
LiveDocsRegistry.INSTANCE.refresh(BinaryProtocol.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -271,7 +273,7 @@ public class BinaryProtocol implements BinaryProtocolCommands {
|
|||
*
|
||||
* @return null in case of IO issues
|
||||
*/
|
||||
private byte[] executeCommand(byte[] packet, String msg, boolean allowLongResponse) {
|
||||
public byte[] executeCommand(byte[] packet, String msg, boolean allowLongResponse) {
|
||||
if (isClosed)
|
||||
return null;
|
||||
try {
|
||||
|
|
|
@ -20,4 +20,5 @@ public interface BinaryProtocolCommands {
|
|||
char COMMAND_READ = 'R'; // 082 decimal
|
||||
char COMMAND_CHUNK_WRITE = 'C'; // pageChunkWrite
|
||||
char COMMAND_BURN = 'B'; // burnCommand
|
||||
char COMMAND_GET_STRUCT = '9'; // TS_GET_STRUCT
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class IoHelper {
|
|||
return packet;
|
||||
}
|
||||
|
||||
static int swap16(int x) {
|
||||
public static int swap16(int x) {
|
||||
return (((x & 0xFF) << 8) | ((x) >> 8));
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class IoHelper {
|
|||
}
|
||||
}
|
||||
|
||||
static void putShort(byte[] packet, int offset, int value) {
|
||||
public static void putShort(byte[] packet, int offset, int value) {
|
||||
int index = offset + 1;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
packet[index--] = (byte) value;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
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 int id;
|
||||
private final List<RefreshActions> actions;
|
||||
private final Field[] values;
|
||||
|
||||
public LiveDocHolder(int id, List<RefreshActions> actions, Field[] values) {
|
||||
this.id = id;
|
||||
this.actions = actions;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public void update(BinaryProtocol binaryProtocol, byte[] response) {
|
||||
for (RefreshActions action : actions)
|
||||
action.refresh(binaryProtocol, response);
|
||||
}
|
||||
|
||||
public abstract boolean isVisible();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getStructSize() {
|
||||
return Field.getStructureSize(values);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.rusefi.ui.livedocs;
|
||||
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.rusefi.binaryprotocol.BinaryProtocolCommands.COMMAND_GET_STRUCT;
|
||||
import static com.rusefi.binaryprotocol.BinaryProtocolCommands.RESPONSE_OK;
|
||||
import static com.rusefi.binaryprotocol.IoHelper.putShort;
|
||||
import static com.rusefi.binaryprotocol.IoHelper.swap16;
|
||||
|
||||
/**
|
||||
* Singleton map of all live documentation entities. Using this registry we know all the entities to update periodically.
|
||||
*/
|
||||
public enum LiveDocsRegistry {
|
||||
INSTANCE;
|
||||
|
||||
private final Map<Integer, LiveDocHolder> liveDocs = new HashMap<>();
|
||||
|
||||
public void register(LiveDocHolder holder) {
|
||||
liveDocs.put(holder.getId(), holder);
|
||||
}
|
||||
|
||||
public void refresh(BinaryProtocol binaryProtocol) {
|
||||
for (LiveDocHolder h : liveDocs.values()) {
|
||||
boolean visible = h.isVisible();
|
||||
System.out.println(h + ": " + visible);
|
||||
if (visible) {
|
||||
int liveDocRequestId = h.getId();
|
||||
int size = h.getStructSize();
|
||||
|
||||
byte packet[] = new byte[5];
|
||||
packet[0] = COMMAND_GET_STRUCT;
|
||||
putShort(packet, 1, swap16(liveDocRequestId)); // offset
|
||||
putShort(packet, 3, swap16(size));
|
||||
|
||||
byte[] responseWithCode = binaryProtocol.executeCommand(packet, "get LiveDoc", false);
|
||||
if (responseWithCode == null || responseWithCode.length != (size + 1) || responseWithCode[0] != RESPONSE_OK)
|
||||
continue;
|
||||
|
||||
byte [] response = new byte[size];
|
||||
|
||||
System.arraycopy(responseWithCode, 1, response, 0, size);
|
||||
|
||||
h.update(binaryProtocol, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.rusefi.ui.livedocs;
|
||||
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
|
||||
public abstract class RefreshActions {
|
||||
public abstract void refresh(BinaryProtocol bp, byte[] response);
|
||||
}
|
|
@ -8,6 +8,8 @@ import org.jetbrains.annotations.NotNull;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.rusefi.config.FieldType.*;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +48,33 @@ public class Field {
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds field by name, ignoring case
|
||||
*/
|
||||
public static Field findField(Field[] values, String instancePrefix, String fieldName) {
|
||||
Objects.requireNonNull(fieldName);
|
||||
for (Field f : values) {
|
||||
if (fieldName.equalsIgnoreCase(f.getName()))
|
||||
return f;
|
||||
}
|
||||
// 2nd pass - let's try to find field with prefix if it was not found without prefix
|
||||
if (!instancePrefix.isEmpty()) {
|
||||
fieldName = instancePrefix + "_" + fieldName;
|
||||
for (Field f : values) {
|
||||
if (fieldName.equalsIgnoreCase(f.getName()))
|
||||
return f;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No field " + fieldName);
|
||||
}
|
||||
|
||||
public static int getStructureSize(Field[] values) {
|
||||
Field last = values[values.length - 1];
|
||||
// todo: at the moment we do not support arrays and
|
||||
// todo: a lot of information is missing for example for Bit type, but this implementation is good enough for now
|
||||
return last.offset + 4;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -130,6 +159,18 @@ public class Field {
|
|||
'}';
|
||||
}
|
||||
|
||||
public Object getAnyValue(ConfigurationImage ci) {
|
||||
if (options == null) {
|
||||
// not enum field
|
||||
return getValue(ci);
|
||||
}
|
||||
if (type != INT8)
|
||||
throw new IllegalStateException("Unsupported enum " + type);
|
||||
int ordinal = ci.getByteBuffer(offset, type.getStorageSize()).get();
|
||||
return options[ordinal];
|
||||
}
|
||||
|
||||
// todo: rename to getNumberValue?
|
||||
@NotNull
|
||||
public Number getValue(ConfigurationImage ci) {
|
||||
Objects.requireNonNull(ci);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.rusefi.config.generated;
|
||||
|
||||
// this file was generated automatically by ConfigDefinition.jar based on integration/engine_state.txt Sun Jun 16 22:18:54 EDT 2019
|
||||
|
||||
import com.rusefi.config.*;
|
||||
|
||||
public class EngineState {
|
||||
public static final Field ISTCHARGEAIRMODEL = Field.create("ISTCHARGEAIRMODEL", 0, FieldType.BIT, 0);
|
||||
public static final Field AIRMASS = Field.create("AIRMASS", 4, FieldType.FLOAT);
|
||||
public static final Field ENGINECYCLEDURATIONMS = Field.create("ENGINECYCLEDURATIONMS", 8, FieldType.FLOAT);
|
||||
public static final Field TCHARGE_COFF = Field.create("TCHARGE_COFF", 12, FieldType.FLOAT);
|
||||
public static final Field AIRFLOW = Field.create("AIRFLOW", 16, FieldType.FLOAT);
|
||||
public static final Field MINRPMKCURRENTTPS = Field.create("MINRPMKCURRENTTPS", 20, FieldType.FLOAT);
|
||||
public static final Field[] VALUES = {
|
||||
ISTCHARGEAIRMODEL,
|
||||
AIRMASS,
|
||||
ENGINECYCLEDURATIONMS,
|
||||
TCHARGE_COFF,
|
||||
AIRFLOW,
|
||||
MINRPMKCURRENTTPS,
|
||||
};
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package com.rusefi.config.generated;
|
||||
|
||||
// this file was generated automatically by ConfigDefinition.jar based on integration\rusefi_config.txt Sun Jun 16 22:17:51 EDT 2019
|
||||
|
||||
import com.rusefi.config.*;
|
||||
|
||||
// this file was generated automatically by ConfigDefinition.jar based on integration\rusefi_config.txt Sun Jun 16 22:00:08 EDT 2019
|
||||
public class Fields {
|
||||
public static final int accelerometerSpiDevice_offset = 2736;
|
||||
public static final int acCutoffHighRpm_offset = 1498;
|
||||
|
@ -857,6 +858,9 @@ public class Fields {
|
|||
public static final int knockNoiseRpmBins_offset_hex = 750;
|
||||
public static final int knockVThreshold_offset = 1520;
|
||||
public static final int lcdThreadPeriodMs_offset = 720;
|
||||
public static final int LDS_CLT_INDEX = 0;
|
||||
public static final int LDS_IAT_INDEX = 1;
|
||||
public static final int LDS_SPEED_DENSITY_INDEX = 2;
|
||||
public static final int LE_COMMAND_LENGTH = 200;
|
||||
public static final int LIS302DLCsPin_offset = 2063;
|
||||
public static final int logFormat_offset = 496;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.rusefi.config.generated;
|
||||
|
||||
// this file was generated automatically by ConfigDefinition.jar based on integration/thermistor.txt Sun Jun 16 22:18:54 EDT 2019
|
||||
|
||||
import com.rusefi.config.*;
|
||||
|
||||
public class ThermistorState {
|
||||
public static final Field RESISTANCE = Field.create("RESISTANCE", 0, FieldType.FLOAT);
|
||||
public static final Field VOLTAGEMCU = Field.create("VOLTAGEMCU", 4, FieldType.FLOAT);
|
||||
public static final Field VOLTAGEBOARD = Field.create("VOLTAGEBOARD", 8, FieldType.FLOAT);
|
||||
public static final Field[] VALUES = {
|
||||
RESISTANCE,
|
||||
VOLTAGEMCU,
|
||||
VOLTAGEBOARD,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.rusefi.ldmp.generated;
|
||||
|
||||
import com.rusefi.ldmp.*;
|
||||
|
||||
public class ThermistorMeta {
|
||||
public static final Request[] CONTENT = new Request[]{
|
||||
new TextRequest("Analog_MCU_reads"),
|
||||
new FieldRequest("voltageMCU"),
|
||||
new TextRequest("from_pin"),
|
||||
new ConfigRequest("adcChannel"),
|
||||
new TextRequest("EOL"),
|
||||
new TextRequest("Analog_ECU_read"),
|
||||
new FieldRequest("voltageBoard"),
|
||||
new TextRequest("Rdivider"),
|
||||
new ConfigRequest("analogInputDividerCoefficient"),
|
||||
new TextRequest("EOL"),
|
||||
new TextRequest("Measured_resistance"),
|
||||
new FieldRequest("resistance"),
|
||||
};
|
||||
}
|
|
@ -5,12 +5,15 @@ import com.rusefi.FileLog;
|
|||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocolHolder;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.config.generated.ThermistorState;
|
||||
import com.rusefi.core.Sensor;
|
||||
import com.rusefi.core.SensorCentral;
|
||||
import com.rusefi.ui.config.ConfigField;
|
||||
import com.rusefi.ui.livedocs.LiveDocPanel;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
import com.rusefi.ui.widgets.IntGaugeLabel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.putgemin.VerticalFlowLayout;
|
||||
import org.scilab.forge.jlatexmath.TeXConstants;
|
||||
import org.scilab.forge.jlatexmath.TeXFormula;
|
||||
import org.scilab.forge.jlatexmath.TeXIcon;
|
||||
|
@ -21,6 +24,10 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import static com.rusefi.config.generated.Fields.LDS_CLT_INDEX;
|
||||
import static com.rusefi.config.generated.Fields.LDS_IAT_INDEX;
|
||||
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy 2013-2018
|
||||
*/
|
||||
|
@ -29,13 +36,21 @@ public class FormulasPane {
|
|||
private static final String NL2 = NL + "\\ " + NL; // two new lines
|
||||
private static final String NL3 = NL2 + "\\ " + NL; // two new lines
|
||||
|
||||
/**
|
||||
* this is the panel we expose to the outside world
|
||||
*/
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
private final JPanel centerProxy = new JPanel(new BorderLayout());
|
||||
private boolean isPaused;
|
||||
|
||||
private JPanel liveDocs = new JPanel(new VerticalFlowLayout());
|
||||
|
||||
public FormulasPane() {
|
||||
content.add(centerProxy, BorderLayout.CENTER);
|
||||
|
||||
liveDocs.add(LiveDocPanel.getThermistorPanel("Coolant Sensor", "CLT", LDS_CLT_INDEX, ThermistorState.VALUES));
|
||||
liveDocs.add(LiveDocPanel.getThermistorPanel("Intake Air Sensor", "IAT", LDS_IAT_INDEX, ThermistorState.VALUES));
|
||||
|
||||
centerProxy.add(new JLabel("Waiting for data..."), BorderLayout.CENTER);
|
||||
|
||||
JButton saveImage = UiUtils.createSaveImageButton();
|
||||
|
@ -147,6 +162,8 @@ public class FormulasPane {
|
|||
warning.setForeground(Color.red);
|
||||
centerProxy.add(warning, BorderLayout.NORTH);
|
||||
centerProxy.add(formulaLabel, BorderLayout.CENTER);
|
||||
|
||||
centerProxy.add(liveDocs, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package com.rusefi.ui.livedocs;
|
||||
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.Field;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.ldmp.ConfigRequest;
|
||||
import com.rusefi.ldmp.FieldRequest;
|
||||
import com.rusefi.ldmp.Request;
|
||||
import com.rusefi.ldmp.TextRequest;
|
||||
import com.rusefi.ldmp.generated.ThermistorMeta;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class LiveDocPanel {
|
||||
@NotNull
|
||||
public static JPanel getThermistorPanel(String title, String instancePrefix, final int id, Field[] values) {
|
||||
JPanel panel = new JPanel(new MigLayout());
|
||||
panel.setBorder(BorderFactory.createTitledBorder(title));
|
||||
|
||||
List<RefreshActions> actions = createComponents(panel, ThermistorMeta.CONTENT, values, instancePrefix);
|
||||
|
||||
LiveDocHolder holder = new LiveDocHolder(id, actions, values) {
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
boolean isVisible = !panel.getVisibleRect().isEmpty();
|
||||
return isVisible && isRecursivelyVisible(panel);
|
||||
}
|
||||
};
|
||||
|
||||
LiveDocsRegistry.INSTANCE.register(holder);
|
||||
return panel;
|
||||
}
|
||||
|
||||
static boolean isRecursivelyVisible(Container c) {
|
||||
Container parent = c.getParent();
|
||||
return c.isVisible() && (parent == null || isRecursivelyVisible(parent));
|
||||
}
|
||||
|
||||
private static List<RefreshActions> createComponents(JPanel panel, Request[] content, Field[] values, String instancePrefix) {
|
||||
List<RefreshActions> actionsList = new ArrayList<>();
|
||||
for (Request r : content) {
|
||||
if (r instanceof TextRequest) {
|
||||
TextRequest request = (TextRequest) r;
|
||||
if (request.isEol()) {
|
||||
panel.add(new JLabel(), "wrap");
|
||||
} else {
|
||||
panel.add(new JLabel(request.getValue().replaceAll("_", " ")));
|
||||
}
|
||||
} else if (r instanceof FieldRequest) {
|
||||
FieldRequest request = (FieldRequest) r;
|
||||
Field field = Field.findField(values, "", request.getField());
|
||||
JLabel label = new JLabel(field.getName());
|
||||
panel.add(label);
|
||||
actionsList.add(new RefreshActions() {
|
||||
@Override
|
||||
public void refresh(BinaryProtocol bp, byte[] response) {
|
||||
String value = field.getValue(new ConfigurationImage(response)).toString();
|
||||
label.setText(value);
|
||||
}
|
||||
});
|
||||
} else if (r instanceof ConfigRequest) {
|
||||
ConfigRequest request = (ConfigRequest) r;
|
||||
Field field = Field.findField(Fields.VALUES, instancePrefix, request.getField());
|
||||
|
||||
JLabel label = new JLabel(field.getName());
|
||||
actionsList.add(new RefreshActions() {
|
||||
@Override
|
||||
public void refresh(BinaryProtocol bp, byte[] response) {
|
||||
String value = field.getAnyValue(bp.getController()).toString();
|
||||
label.setText(value);
|
||||
}
|
||||
});
|
||||
panel.add(label);
|
||||
|
||||
} else {
|
||||
throw new UnsupportedOperationException(r.toString());
|
||||
}
|
||||
}
|
||||
return actionsList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.rusefi.ui.livedocs;
|
||||
|
||||
import com.rusefi.config.generated.ThermistorState;
|
||||
import com.rusefi.ui.livedocs.controls.Toolbox;
|
||||
import com.rusefi.ui.util.FrameHelper;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import static com.rusefi.config.generated.Fields.LDS_CLT_INDEX;
|
||||
import static com.rusefi.ui.livedocs.controls.Toolbox.setTransparentLineBorder;
|
||||
|
||||
public class LiveDocsSandbox {
|
||||
public static JLabel comment = new JLabel("Prototype Comments appear here");
|
||||
|
||||
public static void main(String[] args) {
|
||||
comment.setForeground(Color.blue);
|
||||
|
||||
JPanel panels = new JPanel(new MigLayout("gap 0, insets 0"));
|
||||
panels.add(LiveDocPanel.getThermistorPanel("Coolant Sensor", "CLT", LDS_CLT_INDEX, ThermistorState.VALUES), "wrap");
|
||||
panels.add(LiveDocPanel.getThermistorPanel("Intake Air Sensor", "CLT", LDS_CLT_INDEX, ThermistorState.VALUES), "wrap");
|
||||
|
||||
panels.add(getTChargePanel(), "wrap");
|
||||
|
||||
panels.add(comment);
|
||||
|
||||
new FrameHelper().showFrame(panels);
|
||||
}
|
||||
|
||||
private static Component getTChargePanel() {
|
||||
JPanel panel = new JPanel(new MigLayout("gap 0, insets 0"));
|
||||
panel.setBorder(BorderFactory.createTitledBorder("Air Charge Temperature"));
|
||||
panel.setBorder(BorderFactory.createLineBorder(Color.CYAN));
|
||||
|
||||
JPanel topPanel = new JPanel(new MigLayout());
|
||||
setTransparentLineBorder(topPanel);
|
||||
topPanel.add(new JLabel("top"));
|
||||
|
||||
JPanel bottomPanel = new JPanel(new MigLayout());
|
||||
setTransparentLineBorder(bottomPanel);
|
||||
bottomPanel.add(new JLabel("bottom"));
|
||||
|
||||
addBranch(panel, true, topPanel, bottomPanel);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static void addBranch(JPanel panel, boolean b, JPanel topPanel, JPanel bottomPanel) {
|
||||
//IfBranch branch;
|
||||
JPanel topWrapped = wrapWithOffset(topPanel);
|
||||
JPanel bottomWrapped = wrapWithOffset(bottomPanel);
|
||||
|
||||
topPanel.setBorder(BorderFactory.createLineBorder(Color.green));
|
||||
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.red));
|
||||
Toolbox.setEnabledRecursive(bottomPanel, false);
|
||||
|
||||
|
||||
panel.add(new JLabel("If xa"), "wrap");
|
||||
panel.add(topWrapped, "wrap");
|
||||
panel.add(new JLabel("else"), "wrap");
|
||||
panel.add(bottomWrapped, "wrap");
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JPanel wrapWithOffset(JPanel panel) {
|
||||
JPanel topWrapped = new JPanel(new FlowLayout());
|
||||
topWrapped.add(new JLabel("x"));
|
||||
topWrapped.add(panel);
|
||||
return topWrapped;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.rusefi.ui.livedocs.controls;
|
||||
|
||||
public class ConfigReference {
|
||||
final int value;
|
||||
|
||||
public ConfigReference(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.rusefi.ui.livedocs.controls;
|
||||
|
||||
import com.rusefi.ui.livedocs.LiveDocsSandbox;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
public class ConfigView {
|
||||
private final JLabel content;
|
||||
|
||||
public ConfigView(ConfigReference e) {
|
||||
content = new JLabel(Integer.toString(e.value));
|
||||
markLiveElement(content);
|
||||
content.setToolTipText("Configuration XXX");
|
||||
|
||||
content.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
LiveDocsSandbox.comment.setText("Mouse action shows tooltip");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static void markLiveElement(JComponent content) {
|
||||
content.setBackground(Color.lightGray);
|
||||
content.setOpaque(true);
|
||||
}
|
||||
|
||||
public JLabel getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.rusefi.ui.livedocs.controls;
|
||||
|
||||
import com.rusefi.ui.livedocs.LiveDocsSandbox;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import static com.rusefi.ui.livedocs.controls.ConfigView.markLiveElement;
|
||||
|
||||
public class LogicReference {
|
||||
private final JLabel content = new JLabel();
|
||||
|
||||
public LogicReference(double value, JComponent reference) {
|
||||
content.setText(Double.toString(value));
|
||||
markLiveElement(content);
|
||||
content.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
reference.setBorder(BorderFactory.createLineBorder(Color.red));
|
||||
LiveDocsSandbox.comment.setText("Mouse action highlights referenced element");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
Toolbox.setTransparentLineBorder(reference);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JLabel getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.rusefi.ui.livedocs.controls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Swing UI utilities
|
||||
*/
|
||||
public class Toolbox {
|
||||
public static void setTransparentLineBorder(JComponent reference) {
|
||||
reference.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
public static void setEnabledRecursive(Container panel, boolean value) {
|
||||
panel.setEnabled(value);
|
||||
Component[] com = panel.getComponents();
|
||||
for (int a = 0; a < com.length; a++) {
|
||||
Component element = com[a];
|
||||
if (element instanceof Container) {
|
||||
setEnabledRecursive((Container) element, value);
|
||||
} else {
|
||||
element.setEnabled(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,5 +20,6 @@
|
|||
<orderEntry type="module" module-name="autotest" />
|
||||
<orderEntry type="module" module-name="romraider" />
|
||||
<orderEntry type="library" name="jlatexmath" level="project" />
|
||||
<orderEntry type="module" module-name="configuration_definition" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,16 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="LiveDocsMetaParser" type="Application" factoryName="Application" nameIsGenerated="true">
|
||||
<option name="MAIN_CLASS_NAME" value="com.rusefi.ldmp.LiveDocsMetaParser" />
|
||||
<module name="configuration_definition" />
|
||||
<option name="PROGRAM_PARAMETERS" value=""../../firmware/controllers/sensors/thermistors.cpp"" />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="com.rusefi.ldmp.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -0,0 +1,45 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
public class ConfigRequest extends Request {
|
||||
//@NotNull
|
||||
private final String field;
|
||||
|
||||
public ConfigRequest(String field) {
|
||||
Objects.requireNonNull(field);
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfigRequest{" +
|
||||
"field='" + field + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ConfigRequest that = (ConfigRequest) o;
|
||||
return field.equals(that.field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaCode() {
|
||||
return withSimpleParameter("\"" + field + "\"");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FieldRequest extends Request {
|
||||
private final String field;
|
||||
|
||||
public FieldRequest(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FieldRequest{" +
|
||||
"field='" + field + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FieldRequest that = (FieldRequest) o;
|
||||
return field.equals(that.field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaCode() {
|
||||
return withSimpleParameter("\"" + field + "\"");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IfRequest extends Request {
|
||||
private final String variable;
|
||||
public List<Request> trueBlock = new ArrayList<>();
|
||||
public List<Request> falseBlock = new ArrayList<>();
|
||||
|
||||
public IfRequest(String variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IfRequest{" +
|
||||
"variable='" + variable + '\'' +
|
||||
", trueBlock=" + trueBlock +
|
||||
", falseBlock=" + falseBlock +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getVariable() {
|
||||
return variable;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Stack;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
public class LiveDocsMetaParser {
|
||||
private static final String DISPLAY_CONFIG = "DISPLAY_CONFIG";
|
||||
private static final String DISPLAY_FIELD = "DISPLAY_FIELD";
|
||||
private static final String DISPLAY_TEXT = "DISPLAY_TEXT";
|
||||
private static final String DISPLAY_SENSOR = "DISPLAY_SENSOR";
|
||||
private static final String DISPLAY_IF = "DISPLAY_IF";
|
||||
private static final String DISPLAY_ELSE = "DISPLAY_ELSE";
|
||||
private static final String DISPLAY_ENDIF = "DISPLAY_ENDIF";
|
||||
|
||||
private static String readLineByLine(String filePath) throws IOException {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
Stream<String> stream = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8);
|
||||
stream.forEach(s -> contentBuilder.append(s).append("\n"));
|
||||
return contentBuilder.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String fileName = args[0];
|
||||
String destinationPath = args[1];
|
||||
System.out.println(fileName);
|
||||
if (!new File(fileName).exists())
|
||||
throw new IllegalStateException("Not found " + fileName);
|
||||
String content = readLineByLine(fileName);
|
||||
List<Request> r = parse(content);
|
||||
System.out.println(r);
|
||||
|
||||
|
||||
String className = "ThermistorMeta";
|
||||
String javaCode = generateJavaCode(r, className);
|
||||
FileWriter fw = new FileWriter(destinationPath + "java_console/ui/src/com/rusefi/ldmp/generated/" + className + ".java");
|
||||
fw.write(javaCode);
|
||||
fw.close();
|
||||
}
|
||||
|
||||
public static List<Request> parse(String string) {
|
||||
Stack<List<Request>> stack = new Stack<>();
|
||||
|
||||
List<Request> result = new ArrayList<>();
|
||||
string = string.replaceAll("[()>]", " ");
|
||||
System.out.println(string);
|
||||
Scanner s = new Scanner(string);
|
||||
while (s.hasNext()) {
|
||||
String token = s.next();
|
||||
//System.out.println(token);
|
||||
if (DISPLAY_CONFIG.equals(token)) {
|
||||
if (s.hasNext()) {
|
||||
String config = s.next();
|
||||
System.out.println("REQ CONF " + config);
|
||||
result.add(new ConfigRequest(config));
|
||||
}
|
||||
} else if (DISPLAY_TEXT.equals(token)) {
|
||||
if (s.hasNext()) {
|
||||
String config = s.next();
|
||||
System.out.println("REQ TEXT " + config);
|
||||
result.add(new TextRequest(config));
|
||||
}
|
||||
} else if (DISPLAY_FIELD.equals(token)) {
|
||||
if (s.hasNext()) {
|
||||
String config = s.next();
|
||||
System.out.println("REQ FIELD " + config);
|
||||
result.add(new FieldRequest(config));
|
||||
}
|
||||
} else if (DISPLAY_IF.equals(token)) {
|
||||
if (s.hasNext()) {
|
||||
stack.push(result);
|
||||
|
||||
String variable = s.next();
|
||||
|
||||
|
||||
String config = s.next();
|
||||
System.out.println("REQ TEXT " + config);
|
||||
IfRequest ifRequest = new IfRequest(variable);
|
||||
result.add(ifRequest);
|
||||
|
||||
result = ifRequest.trueBlock;
|
||||
}
|
||||
} else if (DISPLAY_ELSE.equals(token)) {
|
||||
if (stack.isEmpty())
|
||||
throw new IllegalStateException("No IF statement on stack");
|
||||
List<Request> onStack = stack.peek();
|
||||
if (onStack.isEmpty())
|
||||
throw new IllegalStateException("Empty on stack");
|
||||
Request request = onStack.get(onStack.size() - 1);
|
||||
if (!(request instanceof IfRequest))
|
||||
throw new IllegalStateException("Something not right " + request);
|
||||
IfRequest ifRequest = (IfRequest) request;
|
||||
|
||||
result = ifRequest.falseBlock;
|
||||
} else if (DISPLAY_ENDIF.equals(token)) {
|
||||
if (stack.isEmpty())
|
||||
throw new IllegalStateException("No IF statement on stack");
|
||||
result = stack.pop();
|
||||
|
||||
} else if (DISPLAY_SENSOR.equals(token)) {
|
||||
if (s.hasNext()) {
|
||||
String config = s.next();
|
||||
System.out.println("REQ SENSOR " + config);
|
||||
result.add(new SensorRequest(config));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stack.isEmpty())
|
||||
throw new IllegalStateException("Unfinished");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String generateJavaCode(List<Request> r, String className) {
|
||||
StringBuilder java = new StringBuilder("package com.rusefi.ldmp.generated;" + EOL + EOL +
|
||||
"import com.rusefi.ldmp.*;" + EOL + EOL +
|
||||
"public class " + className + " {" + EOL +
|
||||
"\tpublic static final Request[] CONTENT = new Request[]{" + EOL);
|
||||
|
||||
for (Request request : r) {
|
||||
java.append(request.getJavaCode());
|
||||
}
|
||||
|
||||
java.append("\t};" + EOL +
|
||||
"}");
|
||||
|
||||
return java.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
public class Request {
|
||||
public String getJavaCode() {
|
||||
return withSimpleParameter("");
|
||||
}
|
||||
|
||||
protected String withSimpleParameter(String parameter) {
|
||||
return "\t\t\tnew " + getClass().getSimpleName() + "(" + parameter + ")," + EOL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
public class SensorRequest extends Request {
|
||||
private final String value;
|
||||
|
||||
public SensorRequest(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SensorRequest{" +
|
||||
"value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SensorRequest that = (SensorRequest) o;
|
||||
return value.equals(that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaCode() {
|
||||
return "/*sens*/" + EOL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.rusefi.ldmp;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
public class TextRequest extends Request {
|
||||
private final String value;
|
||||
|
||||
public TextRequest(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isEol() {
|
||||
return "EOL".equalsIgnoreCase(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TextRequest{" +
|
||||
"value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TextRequest that = (TextRequest) o;
|
||||
return value.equals(that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaCode() {
|
||||
return withSimpleParameter("\"" + value + "\"");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.rusefi.ldmp.test;
|
||||
|
||||
import com.rusefi.ldmp.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class LiveDocsMetaParserTest {
|
||||
@Test
|
||||
public void parseConfigElements() {
|
||||
List<Request> r = LiveDocsMetaParser.parse("\t\t// TCHARGE_MODE_RPM_TPS\n" +
|
||||
"\t\tfloat minRpmKcurrentTPS = interpolateMsg(\"minRpm\", tpMin, DISPLAY_CONFIG(tChargeMinRpmMinTps), tpMax,\n" +
|
||||
"\t\t\t\t/***display*/CONFIG(tChargeMinRpmMaxTps), tps);\n" +
|
||||
"\t\tfloat maxRpmKcurrentTPS = interpolateMsg(\"maxRpm\", tpMin, DISPLAY_CONFIG(tChargeMaxRpmMinTps), tpMax,\n" +
|
||||
"\t\t\t\tDISPLAY_CONFIG(tChargeMaxRpmMaxTps), tps);\n" +
|
||||
"\n" +
|
||||
"\t\tengine->engineState.Tcharge_coff = interpolateMsg(\"Kcurr\", rpmMin, minRpmKcurrentTPS, rpmMax, maxRpmKcurrentTPS, rpm);\n");
|
||||
assertEquals(3, r.size());
|
||||
assertEquals(new ConfigRequest("tChargeMinRpmMinTps"), r.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseDisplayConfig() {
|
||||
List<Request> r = LiveDocsMetaParser.parse("\t\t// DISPLAY_TEXT(interpolate(\")\n" +
|
||||
"+\t\tDISPLAY_SENSOR(RPM) DISPLAY_TEXT(TCHARGE_MODE_RPM_TPS)\n" +
|
||||
"\t\tfloat minRpmKcurrentTPS = interpolateMsg(\"minRpm\", tpMin, DISPLAY_CONFIG(tChargeMinRpmMinTps), tpMax,\n");
|
||||
assertEquals(4, r.size());
|
||||
// implementation has eaten the bracket :(
|
||||
assertEquals(new TextRequest("interpolate"), r.get(0));
|
||||
assertEquals(new SensorRequest("RPM"), r.get(1));
|
||||
|
||||
String javaCode = LiveDocsMetaParser.generateJavaCode(r, "xx");
|
||||
assertEquals("package com.rusefi.ldmp.generated;\n" +
|
||||
"\n" +
|
||||
"import com.rusefi.ldmp.*;\n" +
|
||||
"\n" +
|
||||
"public class xx {\n" +
|
||||
"\tpublic static final Request[] CONTENT = new Request[]{\n" +
|
||||
"\t\t\tnew TextRequest(\"interpolate\"),\n" +
|
||||
"/*sens*/\n" +
|
||||
"\t\t\tnew TextRequest(\"TCHARGE_MODE_RPM_TPS\"),\n" +
|
||||
"\t\t\tnew ConfigRequest(\"tChargeMinRpmMinTps\"),\n" +
|
||||
"\t};\n" +
|
||||
"}", javaCode);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testField() {
|
||||
List<Request> r = LiveDocsMetaParser.parse("tm->DISPLAY_FIELD(voltageMCU) = getVoltage(\"term\", config->adcChannel);");
|
||||
assertEquals(1, r.size());
|
||||
assertEquals(new FieldRequest("voltageMCU"), r.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseIf() {
|
||||
List<Request> r = LiveDocsMetaParser.parse("\tDISPLAY_IF(cond)\t// DISPLAY_TEXT(\"interpolate(\")\n" +
|
||||
"+\t\tDISPLAY_SENSOR(RPM)" +
|
||||
"/* DISPLAY_ELSE */ DISPLAY_TEXT(\"TCHARGE_MODE_RPM_TPS\")\n" +
|
||||
"\t\tfloat minRpmKcurrentTPS = interpolateMsg(\"minRpm\", tpMin, DISPLAY_CONFIG(tChargeMinRpmMinTps), tpMax,\n" +
|
||||
"/* DISPLAY_ENDIF */");
|
||||
|
||||
assertEquals(1, r.size());
|
||||
IfRequest ifRequest = (IfRequest) r.get(0);
|
||||
List<Request> trueBlock = ifRequest.trueBlock;
|
||||
assertEquals(2, trueBlock.size());
|
||||
assertEquals(new SensorRequest("RPM"), trueBlock.get(1));
|
||||
|
||||
List<Request> falseBlock = ifRequest.falseBlock;
|
||||
assertEquals(2, falseBlock.size());
|
||||
assertEquals(new ConfigRequest("tChargeMinRpmMinTps"), falseBlock.get(1));
|
||||
}
|
||||
}
|
|
@ -8,5 +8,6 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="junit" level="project" />
|
||||
<orderEntry type="library" name="snakeyaml" level="project" />
|
||||
</component>
|
||||
</module>
|
Loading…
Reference in New Issue