Whatever we call it, no matter how we do it - we need live data / remote view into rusEFI actual state #3353
progress
This commit is contained in:
parent
9954ca5ab2
commit
08d115dd58
|
@ -0,0 +1,146 @@
|
||||||
|
package com.rusefi.livedata;
|
||||||
|
|
||||||
|
import com.devexperts.logging.Logging;
|
||||||
|
import com.rusefi.livedata.generated.CPP14Lexer;
|
||||||
|
import com.rusefi.livedata.generated.CPP14Parser;
|
||||||
|
import com.rusefi.livedata.generated.CPP14ParserBaseListener;
|
||||||
|
import com.rusefi.ui.livedata.Range;
|
||||||
|
import com.rusefi.ui.livedata.SourceCodePainter;
|
||||||
|
import com.rusefi.ui.livedata.VariableValueSource;
|
||||||
|
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.text.AttributeSet;
|
||||||
|
import javax.swing.text.StyleConstants;
|
||||||
|
import javax.swing.text.StyleContext;
|
||||||
|
import javax.swing.text.StyledDocument;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import static com.devexperts.logging.Logging.getLogging;
|
||||||
|
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
|
||||||
|
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
|
||||||
|
|
||||||
|
public class LiveDataParserPanel {
|
||||||
|
private static final Logging log = getLogging(LiveDataParserPanel.class);
|
||||||
|
|
||||||
|
private final JPanel content = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
|
public LiveDataParserPanel(VariableValueSource valueSource) {
|
||||||
|
JTextPane text = new JTextPane();
|
||||||
|
|
||||||
|
JScrollPane rightScrollPane = new JScrollPane(text,
|
||||||
|
VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
|
||||||
|
content.add(rightScrollPane);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String sourceCode = getContent(getClass(), "ac_control.cpp");
|
||||||
|
text.setText(sourceCode);
|
||||||
|
|
||||||
|
ParseTree tree = getParseTree(sourceCode);
|
||||||
|
|
||||||
|
StyleContext sc = StyleContext.getDefaultStyleContext();
|
||||||
|
|
||||||
|
StyledDocument style = text.getStyledDocument();
|
||||||
|
AttributeSet oldSet = style.getCharacterElement(0).getAttributes();
|
||||||
|
|
||||||
|
|
||||||
|
applyVariables(valueSource, sourceCode, new SourceCodePainter() {
|
||||||
|
@Override
|
||||||
|
public void paint(Color color, Range range) {
|
||||||
|
|
||||||
|
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Background, color);
|
||||||
|
style.setCharacterAttributes(range.getStart(), range.getLength(), s, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}, tree);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
log.warn("Error reading: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getContent(Class<?> clazz, String fileName) throws IOException, URISyntaxException {
|
||||||
|
URL cpp = clazz.getResource("/c_sources/" + fileName);
|
||||||
|
String line;
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(new File(cpp.toURI())))) {
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
result.append(line + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static ParseTree getParseTree(String sourceCode) throws IOException {
|
||||||
|
CharStream in = new ANTLRInputStream(new ByteArrayInputStream(sourceCode.getBytes()));
|
||||||
|
CPP14Parser parser = new CPP14Parser(new CommonTokenStream(new CPP14Lexer(in)));
|
||||||
|
return parser.translationUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void applyVariables(VariableValueSource valueSource, String s, SourceCodePainter painter, ParseTree tree) {
|
||||||
|
Stack<Boolean> currentState = new Stack<>();
|
||||||
|
currentState.add(Boolean.TRUE);
|
||||||
|
|
||||||
|
new ParseTreeWalker().walk(new CPP14ParserBaseListener() {
|
||||||
|
@Override
|
||||||
|
public void enterStatement(CPP14Parser.StatementContext ctx) {
|
||||||
|
String origin = getOrigin(ctx, s);
|
||||||
|
System.out.println("enter statement [" + origin + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterCondition(CPP14Parser.ConditionContext ctx) {
|
||||||
|
String conditionVariable = ctx.getText();
|
||||||
|
System.out.println("REQUESTING VALUE " + conditionVariable);
|
||||||
|
System.out.println("exp " + getOrigin(ctx.expression(), s));
|
||||||
|
|
||||||
|
Boolean state = (Boolean) valueSource.getValue(conditionVariable);
|
||||||
|
if (state == null) {
|
||||||
|
// todo: fail on unknown condition variables
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state) {
|
||||||
|
painter.paint(Color.GREEN, new Range(ctx));
|
||||||
|
} else {
|
||||||
|
painter.paint(Color.RED, new Range(ctx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterSelectionStatement(CPP14Parser.SelectionStatementContext ctx) {
|
||||||
|
super.enterSelectionStatement(ctx);
|
||||||
|
|
||||||
|
System.out.println("Else terminal " + ctx.Else());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enterJumpStatement(CPP14Parser.JumpStatementContext ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}, tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getOrigin(ParserRuleContext ctx, String s) {
|
||||||
|
Range range = new Range(ctx);
|
||||||
|
return s.substring(range.getStart(), range.getStop());
|
||||||
|
}
|
||||||
|
|
||||||
|
public JPanel getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.rusefi.ui.livedata;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
|
|
||||||
|
public class Range {
|
||||||
|
private final int start;
|
||||||
|
private final int stop;
|
||||||
|
|
||||||
|
public Range(int start, int stop) {
|
||||||
|
this.start = start;
|
||||||
|
this.stop = stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Range(ParserRuleContext context) {
|
||||||
|
this(context.start.getStartIndex(), context.stop.getStopIndex() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStop() {
|
||||||
|
return stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return stop - start;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.rusefi.ui.livedata;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public interface SourceCodePainter {
|
||||||
|
void paint(Color color, Range range);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.rusefi.ui.livedata;
|
||||||
|
|
||||||
|
public interface VariableValueSource {
|
||||||
|
Object getValue(String name);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.rusefi.livedata;
|
||||||
|
|
||||||
|
import com.rusefi.core.ValueSource;
|
||||||
|
import com.rusefi.ui.livedata.LiveDataParserTest;
|
||||||
|
import com.rusefi.ui.livedata.VariableValueSource;
|
||||||
|
import com.rusefi.ui.util.FrameHelper;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class LiveDataParserSandbox {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Map<String, Object> values = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
values.put("engineTooSlow", Boolean.TRUE);
|
||||||
|
values.put("engineTooFast", Boolean.FALSE);
|
||||||
|
|
||||||
|
VariableValueSource valueSource = new VariableValueSource() {
|
||||||
|
@Override
|
||||||
|
public Object getValue(String name) {
|
||||||
|
return values.get(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
new FrameHelper().showFrame(new LiveDataParserPanel(valueSource).getContent());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,6 @@
|
||||||
package com.rusefi.ui.livedata;
|
package com.rusefi.ui.livedata;
|
||||||
|
|
||||||
import com.rusefi.livedata.generated.CPP14Lexer;
|
import com.rusefi.livedata.LiveDataParserPanel;
|
||||||
import com.rusefi.livedata.generated.CPP14Parser;
|
|
||||||
import com.rusefi.livedata.generated.CPP14ParserBaseListener;
|
|
||||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
|
||||||
import org.antlr.v4.runtime.CharStream;
|
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
|
||||||
import org.antlr.v4.runtime.ParserRuleContext;
|
import org.antlr.v4.runtime.ParserRuleContext;
|
||||||
import org.antlr.v4.runtime.tree.ParseTree;
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||||
|
@ -13,11 +8,8 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
public class LiveDataParserTest {
|
public class LiveDataParserTest {
|
||||||
|
@ -27,14 +19,13 @@ public class LiveDataParserTest {
|
||||||
values.put("engineTooSlow", Boolean.TRUE);
|
values.put("engineTooSlow", Boolean.TRUE);
|
||||||
values.put("engineTooFast", Boolean.FALSE);
|
values.put("engineTooFast", Boolean.FALSE);
|
||||||
|
|
||||||
ValueSource valueSource = new ValueSource() {
|
VariableValueSource valueSource = new VariableValueSource() {
|
||||||
@Override
|
@Override
|
||||||
public Object getValue(String name) {
|
public Object getValue(String name) {
|
||||||
return values.get(name);
|
return values.get(name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
String s = "bool AcState::getAcState(DECLARE_ENGINE_PARAMETER_SIGNATURE) {\n" +
|
String s = "bool AcState::getAcState(DECLARE_ENGINE_PARAMETER_SIGNATURE) {\n" +
|
||||||
"\tauto rpm = Sensor::getOrZero(SensorType::Rpm);\n" +
|
"\tauto rpm = Sensor::getOrZero(SensorType::Rpm);\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
@ -51,85 +42,19 @@ public class LiveDataParserTest {
|
||||||
"\t} \n " +
|
"\t} \n " +
|
||||||
"return ff;\n" +
|
"return ff;\n" +
|
||||||
"}";
|
"}";
|
||||||
CharStream in = new ANTLRInputStream(new ByteArrayInputStream(s.getBytes()));
|
|
||||||
|
|
||||||
CPP14Parser parser = new CPP14Parser(new CommonTokenStream(new CPP14Lexer(in)));
|
SourceCodePainter painter = new SourceCodePainter() {
|
||||||
|
@Override
|
||||||
ParseTree tree = parser.translationUnit();
|
public void paint(Color color, Range range) {
|
||||||
|
System.out.println("paint " + color + " " + range);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ParseTree tree = LiveDataParserPanel.getParseTree(s);
|
||||||
new ParseTreeWalker().walk(new PrintCPP14ParserListener(), tree);
|
new ParseTreeWalker().walk(new PrintCPP14ParserListener(), tree);
|
||||||
|
|
||||||
|
|
||||||
Stack<Boolean> currentState = new Stack<>();
|
LiveDataParserPanel.applyVariables(valueSource, s, painter, tree);
|
||||||
currentState.add(Boolean.TRUE);
|
|
||||||
|
|
||||||
new ParseTreeWalker().walk(new CPP14ParserBaseListener() {
|
|
||||||
@Override
|
|
||||||
public void enterStatement(CPP14Parser.StatementContext ctx) {
|
|
||||||
String origin = getOrigin(ctx, s);
|
|
||||||
System.out.println("enter statement [" + origin + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enterCondition(CPP14Parser.ConditionContext ctx) {
|
|
||||||
String conditionVariable = ctx.getText();
|
|
||||||
System.out.println("REQUESTING VALUE " + conditionVariable);
|
|
||||||
System.out.println("exp " + getOrigin(ctx.expression(), s));
|
|
||||||
|
|
||||||
Boolean state = (Boolean) valueSource.getValue(conditionVariable);
|
|
||||||
if (state == null) {
|
|
||||||
// todo: fail on unknown condition variables
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state) {
|
|
||||||
//paint(Color.GREEN, ctx.)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enterSelectionStatement(CPP14Parser.SelectionStatementContext ctx) {
|
|
||||||
super.enterSelectionStatement(ctx);
|
|
||||||
|
|
||||||
System.out.println("Else terminal " + ctx.Else());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enterJumpStatement(CPP14Parser.JumpStatementContext ctx) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}, tree);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private String getOrigin(ParserRuleContext ctx, String s) {
|
|
||||||
Range range = new Range(ctx);
|
|
||||||
return s.substring(range.start, range.stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ValueSource {
|
|
||||||
Object getValue(String name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Range {
|
|
||||||
private final int start;
|
|
||||||
private final int stop;
|
|
||||||
|
|
||||||
public Range(int start, int stop) {
|
|
||||||
this.start = start;
|
|
||||||
this.stop = stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Range(ParserRuleContext context) {
|
|
||||||
this(context.start.getStartIndex(), context.stop.getStopIndex() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStop() {
|
|
||||||
return stop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
package com.rusefi.ui.livedata;
|
package com.rusefi.ui.livedata;
|
||||||
|
|
||||||
|
import com.rusefi.livedata.LiveDataParserPanel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
public class SourceReaderTest {
|
public class SourceReaderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testResourceLocated() throws URISyntaxException, FileNotFoundException {
|
public void testResourceLocated() throws URISyntaxException, IOException {
|
||||||
URL cpp = getClass().getResource("/c_sources/ac_control.cpp");
|
String fileName = "ac_control.cpp";
|
||||||
assertNotNull(cpp);
|
String content = LiveDataParserPanel.getContent(getClass(), fileName);
|
||||||
new FileReader(new File(cpp.toURI()));
|
assertNotNull(content);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue