2021-12-15 16:43:31 -08:00
|
|
|
package com.rusefi.output;
|
|
|
|
|
2023-01-06 09:09:11 -08:00
|
|
|
import com.rusefi.ConfigField;
|
2023-01-06 08:55:59 -08:00
|
|
|
import com.rusefi.ReaderState;
|
2023-06-16 13:20:19 -07:00
|
|
|
import com.rusefi.parse.TypesHelper;
|
2023-01-16 19:47:06 -08:00
|
|
|
import com.rusefi.output.variables.VariableRecord;
|
2023-07-02 21:56:19 -07:00
|
|
|
import com.rusefi.util.LazyFile;
|
2022-12-02 22:02:39 -08:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2021-12-15 16:43:31 -08:00
|
|
|
|
|
|
|
import java.io.IOException;
|
2022-12-02 20:48:21 -08:00
|
|
|
import java.util.ArrayList;
|
2022-12-02 21:53:02 -08:00
|
|
|
import java.util.HashMap;
|
2022-12-02 20:48:21 -08:00
|
|
|
import java.util.List;
|
2022-12-02 21:53:02 -08:00
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
2021-12-15 16:43:31 -08:00
|
|
|
|
2023-01-06 08:01:32 -08:00
|
|
|
import static com.rusefi.output.ConfigStructureImpl.ALIGNMENT_FILL_AT;
|
2021-12-15 16:43:31 -08:00
|
|
|
import static com.rusefi.output.DataLogConsumer.UNUSED;
|
|
|
|
import static com.rusefi.output.GetConfigValueConsumer.getCompareName;
|
|
|
|
|
2023-01-02 09:10:09 -08:00
|
|
|
/**
|
|
|
|
* here we generate C++ code needed for https://github.com/rusefi/rusefi/wiki/Lua-Scripting#getoutputname implementation
|
2023-01-16 13:39:08 -08:00
|
|
|
*
|
2023-01-02 09:10:09 -08:00
|
|
|
* @see GetConfigValueConsumer
|
|
|
|
*/
|
2021-12-15 16:43:31 -08:00
|
|
|
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
|
2022-04-15 10:47:14 -07:00
|
|
|
public class GetOutputValueConsumer implements ConfigurationConsumer {
|
2023-01-16 19:47:06 -08:00
|
|
|
private final List<VariableRecord> getterPairs = new ArrayList<>();
|
2021-12-15 16:43:31 -08:00
|
|
|
private final String fileName;
|
2023-07-02 21:56:19 -07:00
|
|
|
private final LazyFile.LazyFileFactory fileFactory;
|
2021-12-15 16:43:31 -08:00
|
|
|
|
2022-12-04 11:53:45 -08:00
|
|
|
public String currentSectionPrefix = "engine->outputChannels";
|
2023-06-10 17:32:28 -07:00
|
|
|
public boolean moduleMode;
|
|
|
|
public String currentEngineModule;
|
2023-01-16 13:39:08 -08:00
|
|
|
public String conditional;
|
2023-07-01 18:39:10 -07:00
|
|
|
public Boolean isPtr = false;
|
2022-12-04 11:53:45 -08:00
|
|
|
|
2023-07-02 21:56:19 -07:00
|
|
|
public GetOutputValueConsumer(String fileName, LazyFile.LazyFileFactory fileFactory) {
|
2021-12-15 16:43:31 -08:00
|
|
|
this.fileName = fileName;
|
2023-07-02 21:56:19 -07:00
|
|
|
this.fileFactory = fileFactory;
|
2021-12-15 16:43:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-01-06 08:55:59 -08:00
|
|
|
public void handleEndStruct(ReaderState state, ConfigStructure structure) throws IOException {
|
2023-01-06 07:52:09 -08:00
|
|
|
if (state.isStackEmpty()) {
|
2023-01-06 07:54:29 -08:00
|
|
|
PerFieldWithStructuresIterator iterator = new PerFieldWithStructuresIterator(state, structure.getTsFields(), "",
|
2023-01-06 08:11:50 -08:00
|
|
|
(readerState, cf, prefix) -> processOutput(cf, prefix), ".");
|
2021-12-15 16:43:31 -08:00
|
|
|
iterator.loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-06 09:09:11 -08:00
|
|
|
private String processOutput(ConfigField cf, String prefix) {
|
2021-12-15 16:43:31 -08:00
|
|
|
if (cf.getName().contains(UNUSED) || cf.getName().contains(ALIGNMENT_FILL_AT))
|
|
|
|
return "";
|
|
|
|
|
|
|
|
if (cf.isArray() || cf.isFromIterate() || cf.isDirective())
|
|
|
|
return "";
|
2024-04-20 11:06:26 -07:00
|
|
|
if (!TypesHelper.isPrimitive(cf.getTypeName()) && !TypesHelper.isBoolean(cf.getTypeName())) {
|
2021-12-15 16:43:31 -08:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
String userName = prefix + cf.getName();
|
2023-06-10 17:32:28 -07:00
|
|
|
String javaName;
|
|
|
|
if (moduleMode) {
|
|
|
|
javaName = "engine->module<" + currentEngineModule + ">()->" + prefix;
|
|
|
|
} else {
|
2023-07-01 18:39:10 -07:00
|
|
|
javaName = currentSectionPrefix + (isPtr ? "->" : ".") + prefix;
|
2023-06-10 17:32:28 -07:00
|
|
|
}
|
2021-12-15 16:43:31 -08:00
|
|
|
|
2023-06-10 17:32:28 -07:00
|
|
|
getterPairs.add(new VariableRecord(userName, javaName + cf.getName(), null, conditional));
|
2022-12-02 20:48:21 -08:00
|
|
|
|
2021-12-15 16:43:31 -08:00
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void endFile() throws IOException {
|
2023-07-02 21:56:19 -07:00
|
|
|
GetConfigValueConsumer.writeStringToFile(fileName, getContent(), fileFactory);
|
2021-12-15 16:43:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public String getContent() {
|
2022-12-02 21:53:02 -08:00
|
|
|
StringBuilder switchBody = new StringBuilder();
|
|
|
|
|
2023-01-16 19:47:06 -08:00
|
|
|
StringBuilder getterBody = getGetters(switchBody, getterPairs);
|
2022-12-02 21:53:02 -08:00
|
|
|
|
2022-12-02 22:06:41 -08:00
|
|
|
String fullSwitch = wrapSwitchStatement(switchBody);
|
2022-12-02 22:02:39 -08:00
|
|
|
|
2023-07-03 07:27:36 -07:00
|
|
|
return "#if !EFI_UNIT_TEST\n" +
|
|
|
|
GetConfigValueConsumer.getHeader(getClass()) +
|
2022-12-02 22:02:39 -08:00
|
|
|
"float getOutputValueByName(const char *name) {\n" +
|
|
|
|
fullSwitch +
|
2023-07-03 07:27:36 -07:00
|
|
|
getterBody + GetConfigValueConsumer.GET_METHOD_FOOTER +
|
|
|
|
"#endif\n";
|
2022-12-02 22:06:41 -08:00
|
|
|
}
|
2022-12-02 22:02:39 -08:00
|
|
|
|
2022-12-02 22:06:41 -08:00
|
|
|
@NotNull
|
|
|
|
static String wrapSwitchStatement(StringBuilder switchBody) {
|
|
|
|
String fullSwitch = switchBody.length() == 0 ? "" :
|
|
|
|
("\tint hash = djb2lowerCase(name);\n" +
|
2022-12-02 22:02:39 -08:00
|
|
|
|
2022-12-02 22:06:41 -08:00
|
|
|
"\tswitch(hash) {\n" + switchBody + "\t}\n");
|
|
|
|
return fullSwitch;
|
2022-12-02 22:02:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
2023-01-16 19:47:06 -08:00
|
|
|
static StringBuilder getGetters(StringBuilder switchBody, List<VariableRecord> getterPairs) {
|
2022-12-03 21:05:20 -08:00
|
|
|
HashMap<Integer, AtomicInteger> hashConflicts = getHashConflicts(getterPairs);
|
2022-12-02 22:02:39 -08:00
|
|
|
|
|
|
|
StringBuilder getterBody = new StringBuilder();
|
2023-01-16 19:47:06 -08:00
|
|
|
for (VariableRecord pair : getterPairs) {
|
|
|
|
String returnLine = "\t\treturn " + pair.getFullName() + ";\n";
|
|
|
|
String conditional = pair.getConditional();
|
2022-12-02 21:53:02 -08:00
|
|
|
|
2023-01-16 13:39:08 -08:00
|
|
|
String before = conditional == null ? "" : "#if " + conditional + "\n";
|
|
|
|
String after = conditional == null ? "" : "#endif\n";
|
|
|
|
|
2023-01-16 19:47:06 -08:00
|
|
|
int hash = HashUtil.hash(pair.getUserName());
|
2022-12-02 21:53:02 -08:00
|
|
|
if (hashConflicts.get(hash).get() == 1) {
|
2023-03-17 18:19:33 -07:00
|
|
|
switchBody.append("// " + pair.getUserName() + "\n");
|
2023-01-16 13:39:08 -08:00
|
|
|
switchBody.append(before);
|
2022-12-02 21:53:02 -08:00
|
|
|
switchBody.append("\t\tcase " + hash + ":\n");
|
|
|
|
switchBody.append("\t" + returnLine);
|
2023-01-16 13:39:08 -08:00
|
|
|
switchBody.append(after);
|
2022-12-02 21:53:02 -08:00
|
|
|
} else {
|
2023-01-16 19:47:06 -08:00
|
|
|
getterBody.append(getCompareName(pair.getUserName()));
|
2022-12-02 21:53:02 -08:00
|
|
|
getterBody.append(returnLine);
|
|
|
|
}
|
2022-12-02 20:48:21 -08:00
|
|
|
}
|
2022-12-02 22:02:39 -08:00
|
|
|
return getterBody;
|
|
|
|
}
|
2022-12-02 20:48:21 -08:00
|
|
|
|
2022-12-02 22:02:39 -08:00
|
|
|
@NotNull
|
2023-01-16 19:47:06 -08:00
|
|
|
static HashMap<Integer, AtomicInteger> getHashConflicts(List<VariableRecord> getterPairs) {
|
2022-12-02 22:02:39 -08:00
|
|
|
HashMap<Integer, AtomicInteger> hashConflicts = new HashMap<>();
|
2023-01-16 19:47:06 -08:00
|
|
|
for (VariableRecord pair : getterPairs) {
|
|
|
|
hashConflicts.computeIfAbsent(HashUtil.hash(pair.getUserName()), integer -> new AtomicInteger(0)).incrementAndGet();
|
2022-12-02 22:02:39 -08:00
|
|
|
}
|
|
|
|
return hashConflicts;
|
2021-12-15 16:43:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|