use of com.thecoderscorner.menu.editorui.generator.plugin.CodePluginItem in project tcMenu by davetcc.
the class GenerateCodeDialog method showCodeGenerator.
public void showCodeGenerator(Stage stage, boolean modal) {
this.mainStage = stage;
BorderPane pane = new BorderPane();
pane.getStyleClass().add("background");
placeDirectoryAndEmbeddedPanels(pane);
centerPane = new VBox(5);
addTitleLabel(centerPane, "Select the input type:");
CodeGeneratorOptions genOptions = project.getGeneratorOptions();
var allItems = project.getMenuTree().getAllMenuItems();
reloadAllPlugins(platforms.getEmbeddedPlatformFromId(genOptions.getEmbeddedPlatform()));
CodePluginItem itemInput = findItemByUuidOrDefault(inputsSupported, genOptions.getLastInputUuid(), Optional.empty());
CodePluginItem itemDisplay = findItemByUuidOrDefault(displaysSupported, genOptions.getLastDisplayUuid(), Optional.empty());
CodePluginItem itemTheme = findItemByUuidOrDefault(themesSupported, genOptions.getLastThemeUuid(), Optional.of(DEFAULT_THEME_ID));
initialPlugins.addAll(List.of(itemInput.getId(), itemDisplay.getId(), itemTheme.getId()));
setAllPropertiesToLastValues(itemInput);
setAllPropertiesToLastValues(itemDisplay);
setAllPropertiesToLastValues(itemTheme);
currentInput = new UICodePluginItem(manager, itemInput, CHANGE, this::onInputChange, editorUI, allItems, 0, "inputPlugin");
currentInput.getStyleClass().add("uiCodeGen");
centerPane.getChildren().add(currentInput);
addTitleLabel(centerPane, "Select the display type:");
currentDisplay = new UICodePluginItem(manager, itemDisplay, CHANGE, this::onDisplayChange, editorUI, allItems, 0, "displayPlugin");
currentDisplay.getStyleClass().add("uiCodeGen");
centerPane.getChildren().add(currentDisplay);
if (itemTheme != null) {
themeTitle = addTitleLabel(centerPane, "Select a theme:");
currentTheme = new UICodePluginItem(manager, itemTheme, CHANGE, this::onThemeChange, editorUI, allItems, 0, "themePlugin");
currentTheme.setId("currentThemeUI");
currentTheme.getStyleClass().add("uiCodeGen");
if (!currentDisplay.getItem().isThemeNeeded()) {
currentTheme.setVisible(false);
currentTheme.setManaged(false);
themeTitle.setVisible(false);
themeTitle.setManaged(false);
}
centerPane.getChildren().add(currentTheme);
} else
currentTheme = null;
BorderPane remoteLabelPane = new BorderPane();
Label titleLbl = new Label("Select IoT/remote capabilities:");
titleLbl.setStyle("-fx-font-size: 16px; -fx-opacity: 0.6; -fx-font-weight: bold;");
remoteLabelPane.setLeft(titleLbl);
Button addRemoteCapabilityButton = new Button("Add another IoT/remote");
remoteLabelPane.setRight(addRemoteCapabilityButton);
addRemoteCapabilityButton.setOnAction(this::produceAnotherRemoteCapability);
centerPane.getChildren().add(remoteLabelPane);
List<String> remoteIds = genOptions.getLastRemoteCapabilitiesUuids();
if (remoteIds != null && !remoteIds.isEmpty()) {
int count = 0;
for (var remoteId : remoteIds) {
CodePluginItem itemRemote = findItemByUuidOrDefault(remotesSupported, remoteId, Optional.of(CoreCodeGenerator.NO_REMOTE_ID));
initialPlugins.add(itemRemote.getId());
setAllPropertiesToLastValues(itemRemote);
String pluginId = "remotePlugin" + count;
var currentRemote = new UICodePluginItem(manager, itemRemote, CHANGE, this::onRemoteChange, editorUI, allItems, count, pluginId);
currentRemote.getStyleClass().add("uiCodeGen");
centerPane.getChildren().add(currentRemote);
count++;
currentRemotes.add(currentRemote);
}
} else {
// did not exist before this, must be first run.
CodePluginItem itemRemote = findItemByUuidOrDefault(remotesSupported, "", Optional.empty());
String pluginId = "remotePlugin0";
var currentRemote = new UICodePluginItem(manager, itemRemote, CHANGE, this::onRemoteChange, editorUI, allItems, 0, pluginId);
currentRemote.getStyleClass().add("uiCodeGen");
centerPane.getChildren().add(currentRemote);
}
filterChoicesByPlatform(platformCombo.getValue());
ButtonBar buttonBar = new ButtonBar();
Button generateButton = new Button("Generate Code");
generateButton.setDefaultButton(true);
generateButton.setOnAction(this::onGenerateCode);
generateButton.setId("generateButton");
Button cancelButton = new Button("Cancel");
cancelButton.setCancelButton(true);
cancelButton.setOnAction(this::onCancel);
buttonBar.getButtons().addAll(cancelButton, generateButton);
ScrollPane scrollPane = new ScrollPane(centerPane);
scrollPane.setFitToWidth(true);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
pane.setCenter(scrollPane);
pane.setOpaqueInsets(new Insets(5));
pane.setBottom(buttonBar);
pane.setPrefSize(800, 750);
BorderPane.setMargin(buttonBar, new Insets(5));
BorderPane.setMargin(pane.getTop(), new Insets(5));
var title = "Code Generator:" + project.getFileName();
createDialogStateAndShow(stage, pane, title, modal);
}
use of com.thecoderscorner.menu.editorui.generator.plugin.CodePluginItem in project tcMenu by davetcc.
the class PluginRequiredFileProcessor method generatePluginsForCreator.
protected void generatePluginsForCreator(CodePluginItem item, Path directory) throws TcMenuConversionException {
var expando = new CodeParameter(CodeParameter.NO_TYPE, null, true, "");
var filteredSourceFiles = item.getRequiredSourceFiles().stream().filter(sf -> sf.getApplicability().isApplicable(context.getProperties())).collect(Collectors.toList());
for (var srcFile : filteredSourceFiles) {
try {
var fileName = expando.expandExpression(context, srcFile.getFileName());
// get the source (either from the plugin or from the tcMenu library)
String fileNamePart;
String fileData;
Path location = item.getConfig().getPath().resolve(fileName);
try (var sourceInputStream = new FileInputStream(location.toFile())) {
fileData = new String(sourceInputStream.readAllBytes());
fileNamePart = Paths.get(fileName).getFileName().toString();
} catch (Exception e) {
throw new TcMenuConversionException("Unable to locate file in plugin: " + srcFile, e);
}
Path resolvedOutputFile = directory.resolve(fileNamePart);
if (!srcFile.isOverwritable() && Files.exists(resolvedOutputFile)) {
uiLogger.accept(WARNING, "Source file " + srcFile.getFileName() + " already exists and overwrite is false, skipping");
} else {
uiLogger.accept(INFO, "Copy plugin file: " + srcFile.getFileName());
for (var cr : srcFile.getReplacementList()) {
if (cr.getApplicability().isApplicable(context.getProperties())) {
uiLogger.accept(DEBUG, "Plugin file replacement: " + cr.getFind() + " to " + cr.getReplace());
var replacement = StringHelper.escapeRex(expando.expandExpression(context, cr.getReplace()));
fileData = fileData.replaceAll(cr.getFind(), replacement);
}
}
Files.write(resolvedOutputFile, fileData.getBytes(), TRUNCATE_EXISTING, CREATE);
}
// and copy into the destination
} catch (Exception e) {
throw new TcMenuConversionException("Unexpected exception processing " + srcFile, e);
}
}
}
use of com.thecoderscorner.menu.editorui.generator.plugin.CodePluginItem in project tcMenu by davetcc.
the class GenerateCodeDialog method ensureIoFullyDeclared.
private void ensureIoFullyDeclared(CodePluginItem pluginItem) {
logger.log(INFO, "Checking for unmapped IO devices: " + pluginItem.getDescription());
var codeOptions = project.getGeneratorOptions();
// find any IO device declarations that do not match to an entry in the expanders
var anyIoWithoutEntries = pluginItem.getProperties().stream().filter(prop -> prop.getValidationRules() instanceof IoExpanderPropertyValidationRules).filter(prop -> codeOptions.getExpanderDefinitions().getDefinitionById(prop.getLatestValue()).isEmpty()).toList();
// nothing to do if list is empty
if (anyIoWithoutEntries.isEmpty()) {
logger.log(INFO, "All IO devices mapped");
return;
}
var allExpanders = new HashSet<>(codeOptions.getExpanderDefinitions().getAllExpanders());
// now we iterate through the unmapped expanders, which must be from prior to the automated support.
for (var customIo : anyIoWithoutEntries) {
if (StringHelper.isStringEmptyOrNull(customIo.getLatestValue())) {
// for empty strings, the previous assumption was using device IO. This is now explicitly defined
// as deviceIO
customIo.setLatestValue(InternalDeviceExpander.DEVICE_ID);
logger.log(INFO, "Device being mapped as internal: " + customIo.getLatestValue());
} else {
// otherwise, previously the assumption was using a custom defined expander in the sketch, now we'll
// actually add that to the sketch.
allExpanders.add(new CustomDeviceExpander(customIo.getLatestValue()));
logger.log(INFO, "Device being mapped as custom: " + customIo.getLatestValue());
}
}
project.setGeneratorOptions(new CodeGeneratorOptionsBuilder().withExisting(codeOptions).withExpanderDefinitions(new IoExpanderDefinitionCollection(allExpanders)).codeOptions());
logger.log(INFO, "Done mapping all IO devices");
}
use of com.thecoderscorner.menu.editorui.generator.plugin.CodePluginItem in project tcMenu by davetcc.
the class GenerateCodeDialog method selectPlugin.
private void selectPlugin(List<CodePluginItem> pluginItems, String changeWhat, BiConsumer<UICodePluginItem, CodePluginItem> eventHandler) {
Popup popup = new Popup();
List<UICodePluginItem> listOfComponents = pluginItems.stream().map(display -> new UICodePluginItem(manager, display, SELECT, (ui, item) -> {
popup.hide();
eventHandler.accept(ui, item);
}, 0, "pluginSel_" + display.getId())).toList();
VBox vbox = new VBox(5);
addTitleLabel(vbox, "Select the " + changeWhat + " to use:");
vbox.getChildren().addAll(listOfComponents);
BorderPane pane = new BorderPane();
pane.setCenter(vbox);
vbox.getStyleClass().add("popupWindow");
var scroll = new ScrollPane(pane);
scroll.setFitToWidth(true);
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scroll.setPrefSize(700, 600);
popup.getContent().add(scroll);
popup.setAutoHide(true);
popup.setOnAutoHide(event -> popup.hide());
popup.setHideOnEscape(true);
var stage = (Stage) (currentInput.getScene().getWindow());
popup.show(stage);
}
use of com.thecoderscorner.menu.editorui.generator.plugin.CodePluginItem in project tcMenu by davetcc.
the class CodeGeneratorCommand method call.
@Override
public Integer call() {
try {
var project = projectFileOrNull(projectFile);
System.out.format("Starting code generator for %s\n", project.getOptions().getApplicationName());
var prefsStore = new PrefsConfigurationStorage();
MenuEditorApp.createOrUpdateDirectoriesAsNeeded(prefsStore);
prefsStore.setLastRunVersion(new VersionInfo(prefsStore.getVersion()));
var platforms = new PluginEmbeddedPlatformsImpl();
DefaultXmlPluginLoader loader = new DefaultXmlPluginLoader(platforms, prefsStore, true);
loader.loadPlugins();
platforms.setInstallerConfiguration(new ArduinoLibraryInstaller(new OfflineDetector(), loader, prefsStore), prefsStore);
var embeddedPlatform = platforms.getEmbeddedPlatformFromId(project.getOptions().getEmbeddedPlatform());
var codeGen = platforms.getCodeGeneratorFor(embeddedPlatform, project.getOptions());
System.out.println("Preparing to execute generator");
List<CodePluginItem> allPlugins = loader.getLoadedPlugins().stream().flatMap(pluginLib -> pluginLib.getPlugins().stream()).collect(Collectors.toList());
List<CodePluginItem> plugins = new ArrayList<>();
plugins.add(getPluginOrDefault(allPlugins, project.getOptions().getLastInputUuid(), DEFAULT_INPUT_PLUGIN));
plugins.add(getPluginOrDefault(allPlugins, project.getOptions().getLastDisplayUuid(), DEFAULT_DISPLAY_PLUGIN));
for (var plugin : project.getOptions().getLastRemoteCapabilitiesUuids()) {
plugins.add(getPluginOrDefault(allPlugins, plugin, DEFAULT_REMOTE_PLUGIN));
}
if (project.getOptions().getLastThemeUuid() != null) {
plugins.add(getPluginOrDefault(allPlugins, project.getOptions().getLastThemeUuid(), DEFAULT_THEME_PLUGIN));
}
System.out.format("Executing code generator");
var location = Paths.get(loadedProjectFile.getParent());
codeGen.setLoggerFunction((level, s) -> {
if (verbose)
System.out.format("Gen: %s: %s\n", level, s);
});
codeGen.startConversion(location, plugins, project.getMenuTree(), Collections.emptyList(), project.getOptions());
return 0;
} catch (Exception ex) {
System.out.println("Error during code generation " + ex.getClass().getSimpleName() + " " + ex.getMessage());
if (verbose) {
ex.printStackTrace();
}
return -1;
}
}
Aggregations