2021-05-18 10:58:39 -07:00
|
|
|
package com.rusefi.ui.lua;
|
|
|
|
|
|
|
|
import com.opensr5.ConfigurationImage;
|
|
|
|
import com.rusefi.binaryprotocol.BinaryProtocol;
|
|
|
|
import com.rusefi.config.generated.Fields;
|
2021-11-23 14:16:33 -08:00
|
|
|
import com.rusefi.io.ConnectionStatusLogic;
|
2021-10-22 08:12:55 -07:00
|
|
|
import com.rusefi.io.LinkManager;
|
2021-05-18 10:58:39 -07:00
|
|
|
import com.rusefi.ui.MessagesPanel;
|
|
|
|
import com.rusefi.ui.UIContext;
|
2022-10-15 11:36:41 -07:00
|
|
|
import com.rusefi.core.preferences.storage.Node;
|
2021-10-19 07:51:59 -07:00
|
|
|
import com.rusefi.ui.util.URLLabel;
|
2021-05-18 10:58:39 -07:00
|
|
|
import com.rusefi.ui.widgets.AnyCommand;
|
2021-11-25 07:18:50 -08:00
|
|
|
import neoe.formatter.lua.LuaFormatter;
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
import java.awt.*;
|
2021-11-25 07:18:50 -08:00
|
|
|
import java.awt.event.ActionEvent;
|
2021-05-18 10:58:39 -07:00
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
2021-08-31 09:32:05 -07:00
|
|
|
import static com.rusefi.ui.util.UiUtils.trueLayout;
|
|
|
|
|
2021-05-18 10:58:39 -07:00
|
|
|
public class LuaScriptPanel {
|
|
|
|
private final UIContext context;
|
|
|
|
private final JPanel mainPanel = new JPanel(new BorderLayout());
|
|
|
|
private final AnyCommand command;
|
2021-11-11 14:47:22 -08:00
|
|
|
private final TextEditor scriptText = new TextEditor();
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
public LuaScriptPanel(UIContext context, Node config) {
|
|
|
|
this.context = context;
|
2021-08-31 06:35:30 -07:00
|
|
|
command = AnyCommand.createField(context, config, true, true);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
// Upper panel: command entry, etc
|
|
|
|
JPanel upperPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
|
|
|
|
|
|
|
JButton writeButton = new JButton("Write to ECU");
|
|
|
|
JButton resetButton = new JButton("Reset/Reload Lua");
|
2021-11-25 07:18:50 -08:00
|
|
|
JButton formatButton = new JButton("Format");
|
2022-02-23 14:02:56 -08:00
|
|
|
JButton burnButton = new JButton("Burn to ECU");
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-11-11 16:15:36 -08:00
|
|
|
MessagesPanel mp = new MessagesPanel(null, config);
|
|
|
|
|
|
|
|
writeButton.addActionListener(e -> {
|
|
|
|
write();
|
|
|
|
// resume messages on 'write new script to ECU'
|
|
|
|
mp.setPaused(false);
|
|
|
|
});
|
2021-05-18 10:58:39 -07:00
|
|
|
resetButton.addActionListener(e -> resetLua());
|
|
|
|
|
2021-11-25 07:18:50 -08:00
|
|
|
formatButton.addActionListener(new ActionListener() {
|
|
|
|
@Override
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
String sourceCode = scriptText.getText();
|
|
|
|
try {
|
|
|
|
String formatted = new LuaFormatter().format(sourceCode, new LuaFormatter.Env());
|
|
|
|
scriptText.setText(formatted);
|
|
|
|
} catch (Exception ignored) {
|
|
|
|
// todo: fix luaformatter no reason for exception
|
|
|
|
} }
|
|
|
|
});
|
|
|
|
|
2022-02-23 14:02:56 -08:00
|
|
|
burnButton.addActionListener(e -> {
|
|
|
|
LinkManager linkManager = context.getLinkManager();
|
|
|
|
|
|
|
|
linkManager.submit(() -> {
|
|
|
|
BinaryProtocol bp = linkManager.getCurrentStreamState();
|
|
|
|
bp.burn();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-11-25 07:18:50 -08:00
|
|
|
upperPanel.add(formatButton);
|
2021-05-18 10:58:39 -07:00
|
|
|
upperPanel.add(writeButton);
|
|
|
|
upperPanel.add(resetButton);
|
2022-02-23 14:02:56 -08:00
|
|
|
upperPanel.add(burnButton);
|
2021-08-31 06:35:30 -07:00
|
|
|
upperPanel.add(command.getContent());
|
2021-10-19 07:51:59 -07:00
|
|
|
upperPanel.add(new URLLabel("Lua Wiki", "https://github.com/rusefi/rusefi/wiki/Lua-Scripting"));
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
// Center panel - script editor and log
|
|
|
|
JPanel scriptPanel = new JPanel(new BorderLayout());
|
2021-11-11 14:47:22 -08:00
|
|
|
scriptPanel.add(scriptText.getControl(), BorderLayout.CENTER);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
//centerPanel.add(, BorderLayout.WEST);
|
|
|
|
JPanel messagesPanel = new JPanel(new BorderLayout());
|
|
|
|
messagesPanel.add(BorderLayout.NORTH, mp.getButtonPanel());
|
|
|
|
messagesPanel.add(BorderLayout.CENTER, mp.getMessagesScroll());
|
|
|
|
|
2021-11-23 14:16:33 -08:00
|
|
|
ConnectionStatusLogic.INSTANCE.addListener(isConnected -> {
|
2022-02-09 20:45:40 -08:00
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
try {
|
2021-11-23 14:16:33 -08:00
|
|
|
readFromECU();
|
2022-02-09 20:45:40 -08:00
|
|
|
} catch (Throwable e) {
|
|
|
|
System.out.println(e);
|
2021-11-23 14:16:33 -08:00
|
|
|
}
|
2022-02-09 20:45:40 -08:00
|
|
|
}
|
|
|
|
});
|
2021-11-23 14:16:33 -08:00
|
|
|
});
|
|
|
|
|
2022-02-09 20:45:40 -08:00
|
|
|
JSplitPane centerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scriptPanel, messagesPanel);
|
2021-08-31 09:32:05 -07:00
|
|
|
|
|
|
|
mainPanel.add(upperPanel, BorderLayout.NORTH);
|
|
|
|
mainPanel.add(centerPanel, BorderLayout.CENTER);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-08-31 09:32:05 -07:00
|
|
|
trueLayout(mainPanel);
|
2021-11-11 14:47:22 -08:00
|
|
|
SwingUtilities.invokeLater(() -> centerPanel.setDividerLocation(centerPanel.getSize().width / 2));
|
2021-05-18 10:58:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public JPanel getPanel() {
|
|
|
|
return mainPanel;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ActionListener getTabSelectedListener() {
|
2021-08-31 06:35:30 -07:00
|
|
|
return e -> {
|
|
|
|
if (command != null)
|
|
|
|
command.requestFocus();
|
2021-05-18 10:58:39 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-08-31 09:32:05 -07:00
|
|
|
void readFromECU() {
|
|
|
|
BinaryProtocol bp = context.getLinkManager().getCurrentStreamState();
|
2021-05-18 10:58:39 -07:00
|
|
|
|
|
|
|
if (bp == null) {
|
2021-08-31 09:32:05 -07:00
|
|
|
scriptText.setText("No ECU located");
|
2021-05-18 10:58:39 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConfigurationImage image = bp.getControllerConfiguration();
|
2021-09-18 13:47:16 -07:00
|
|
|
if (image == null) {
|
|
|
|
scriptText.setText("No configuration image");
|
|
|
|
return;
|
|
|
|
}
|
2022-10-23 13:39:18 -07:00
|
|
|
ByteBuffer luaScriptBuffer = image.getByteBuffer(Fields.LUASCRIPT.getOffset(), Fields.LUA_SCRIPT_SIZE);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-08-31 06:35:30 -07:00
|
|
|
byte[] scriptArr = new byte[Fields.LUA_SCRIPT_SIZE];
|
2021-05-18 10:58:39 -07:00
|
|
|
luaScriptBuffer.get(scriptArr);
|
|
|
|
|
2021-08-31 06:35:30 -07:00
|
|
|
int i = findNullTerminator(scriptArr);
|
|
|
|
scriptText.setText(new String(scriptArr, 0, i, StandardCharsets.US_ASCII));
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("StatementWithEmptyBody")
|
|
|
|
private static int findNullTerminator(byte[] scriptArr) {
|
2021-05-18 10:58:39 -07:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < scriptArr.length && scriptArr[i] != 0; i++) ;
|
2021-08-31 06:35:30 -07:00
|
|
|
return i;
|
2021-05-18 10:58:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void write() {
|
|
|
|
String script = scriptText.getText();
|
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
LinkManager linkManager = context.getLinkManager();
|
|
|
|
|
|
|
|
linkManager.submit(() -> {
|
|
|
|
BinaryProtocol bp = linkManager.getCurrentStreamState();
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
byte[] paddedScript = new byte[Fields.LUA_SCRIPT_SIZE];
|
|
|
|
byte[] scriptBytes = script.getBytes(StandardCharsets.US_ASCII);
|
|
|
|
System.arraycopy(scriptBytes, 0, paddedScript, 0, scriptBytes.length);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
int idx = 0;
|
|
|
|
int remaining;
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
do {
|
|
|
|
remaining = paddedScript.length - idx;
|
|
|
|
int thisWrite = Math.min(remaining, Fields.BLOCKING_FACTOR);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2022-10-23 13:39:18 -07:00
|
|
|
bp.writeData(paddedScript, idx, Fields.LUASCRIPT.getOffset() + idx, thisWrite);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
idx += thisWrite;
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2021-10-22 08:12:55 -07:00
|
|
|
remaining -= thisWrite;
|
|
|
|
} while (remaining > 0);
|
2021-05-18 10:58:39 -07:00
|
|
|
|
2022-02-23 14:02:56 -08:00
|
|
|
// need a way to modify script on the fly with shorter execution gaps to keep E65 CAN network happy
|
|
|
|
// todo: auto-burn on console close check box in case of Lua changes?
|
|
|
|
// todo: check box for auto-burn?
|
|
|
|
// bp.burn();
|
2021-10-22 08:12:55 -07:00
|
|
|
|
|
|
|
// Burning doesn't reload lua script, so we have to do it manually
|
|
|
|
resetLua();
|
|
|
|
});
|
2021-05-18 10:58:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void resetLua() {
|
|
|
|
this.context.getCommandQueue().write("luareset");
|
|
|
|
}
|
|
|
|
}
|