Files
PIC-Simu/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java
2024-06-02 20:58:20 +02:00

536 lines
16 KiB
Java

package fabrik.simulator.pic16f84;
import com.gluonhq.charm.glisten.control.ToggleButtonGroup;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Controller_Frontend {
private int [] prog;
private int [][] read;
private int [] ind;
private double executionTimeMultiplier = 1;
@FXML
private ComboBox<String> executionTimeComboBox;
@FXML
private Button stepintoButton;
@FXML
private TableView<Table.DataEntry> tableView;
@FXML
private ListView<String> lstContentListView;
@FXML
private Label pclLabel;
@FXML
private Label statusLabel;
@FXML
private Label fsrLabel;
@FXML
private Label pclathLabel;
@FXML
private Label intconLabel;
@FXML
private Button stepButton;
@FXML
private Button autoRunGUI;
@FXML
private Button stopButton;
@FXML
private Label totalExecutionTimeLabel;
@FXML
private CheckBox wdtCheck;
private static volatile boolean isAutoRunActive = false;
private static volatile boolean isSleeping = false;
public static boolean isSleeping (){
return isSleeping;
}
public static void stopRunFromBackend(String message){
isAutoRunActive = false;
if (isSleeping)
wakeUpFromSleep();
else
DataRegister.resetPC();
// Stage stoppedStage = new Stage();
// stoppedStage.setTitle("Programm unterbrochen!");
// VBox vbox = new VBox();
// vbox.setAlignment(javafx.geometry.Pos.CENTER);
// Label grundlabel = new Label("Grund: " + message);
// grundlabel.setStyle("-fx-font-size: 16px; -fx-font-weight: bold;");
// Label ueberlabel = new Label("Programm unterbrochen!");
// vbox.getChildren().add(ueberlabel);
// vbox.getChildren().add(grundlabel);
// VBox.setMargin(grundlabel, new javafx.geometry.Insets(10, 10, 10, 10));
// Scene scene = new Scene(vbox, 300, 90);
// stoppedStage.setAlwaysOnTop(true);
// stoppedStage.setScene(scene);
// stoppedStage.show();
}
public static void sleep() {
isSleeping = true;
}
public static void wakeUpFromSleep() {
isSleeping = false;
}
@FXML
private void stopAutoRun(ActionEvent event) {
isAutoRunActive = false;
}
@FXML
private void autoRunGUI(ActionEvent event) {
if (!isAutoRunActive) {
isAutoRunActive = true;
}
Thread autoRunThread = new Thread(() -> {
try {
while (DataRegister.getPC() < prog.length && isAutoRunActive){
Platform.runLater(() -> {
try {
stepintoButton(null);
} catch (IOException e) {
e.printStackTrace();
}
});
Thread.sleep(80); //Verzögerungszeit in Millisekunden
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
autoRunThread.setDaemon(true);
autoRunThread.start();
}
private void updateExecutionTimeMultiplier() {
String selectedOption = executionTimeComboBox.getValue();
switch (selectedOption) {
case "8 MHZ":
executionTimeMultiplier = 0.5;
break;
case "4 MHZ":
executionTimeMultiplier = 1;
break;
case "1 MHZ":
executionTimeMultiplier = 4;
break;
case "500 HZ":
executionTimeMultiplier = 8;
break;
case "100 HZ":
executionTimeMultiplier = 40;
break;
case "32 HZ":
executionTimeMultiplier = 125;
break;
}
}
@FXML
private void stepintoButton(ActionEvent event) throws IOException {
if (lstContentListView.getItems().isEmpty()) {
// Datei ist nicht geladen oder leer
return;
}
int currentIndex;
// Aktuelle Zeile abrufen
if (!isSleeping)
currentIndex = ind[DataRegister.getPC()];
else
currentIndex = ind[DataRegister.getPC()]-1;
// Überprüfen, ob ein Breakpoint gesetzt ist testte
if (breakpoints.contains(currentIndex)) {
stopAutoRun(null);
System.out.println("Breakpoint erreicht bei Zeile: " + currentIndex);
return;
}
// Scrollen zur ausgewählten Zeile
lstContentListView.scrollTo(currentIndex -2);
// Zeile auswählen
lstContentListView.getSelectionModel().clearSelection();
lstContentListView.getSelectionModel().select(currentIndex);
String selectedRowStyle;
if (!isSleeping)
selectedRowStyle = "-fx-background-color: red; -fx-text-fill: white;";
else
selectedRowStyle = "-fx-background-color: teal; -fx-text-fill: white;";
markSelectedRow(currentIndex, selectedRowStyle);
if (!isSleeping) {
Commands.decode(prog[DataRegister.getPC()]);
DataRegister.increasePC();
}
else {
Commands.decode(0);
}
WatchdogTimer.testAndTrigger();
Table.refresh();
Stage stage = (Stage) stepintoButton.getScene().getWindow();
CreateWindow.refreshTable(stage);
IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons());
long totalExecutionTime = Commands.getTotalExecutionTime();
double adjustedTotalExecutionTime = totalExecutionTime * executionTimeMultiplier;
totalExecutionTimeLabel.setText("Total Execution Time: " + adjustedTotalExecutionTime + "µs");
}
private void markSelectedRow(int currentIndex, String selectedRowStyle) {
lstContentListView.setCellFactory(column -> new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(item);
if (getIndex() == currentIndex) {
setStyle(selectedRowStyle);
} else {
setStyle("");
}
}
});
}
private Set<Integer> breakpoints = new HashSet<>();
@FXML
protected void selectFileLST(ActionEvent event) throws IOException {
File selectedFile = chooseLSTFile();
stopAutoRun(null);
if(selectedFile != null){
DataRegister.initDataRegister();
DataRegister.resetPC();
initialize();
toggleLEDs(null);
IOPorts.reset();
for (ToggleButtonGroup toggleButtonGroup : allPORTbuttons) {
try {
toggleButtonGroup.getToggles().get(0).setSelected(true);
toggleButtonGroup.getToggles().get(1).setSelected(false);
IOPorts.setPORTfromUI(toggleButtonGroup);
} catch (NullPointerException ignored) {}
}
IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons());
Commands.resetTotalExecutionTime();
WatchdogTimer.reset();
wdtCheck.setSelected(false);
Table.refresh();
read = ParseFile.parseDatei(selectedFile.getAbsolutePath());
prog = read [0];
ind = read[1];
System.out.println(Arrays.toString(Arrays.stream(prog).toArray()));
displayLSTFileContent(selectedFile);
markSelectedRow(0, "-fx-background-color: red; -fx-text-fill: white;");
initializeBreakpoints();
}
}
private void initializeBreakpoints() {
lstContentListView.setCellFactory(createBreakpointCell());
}
private boolean checkBreakpoint(int pc) {
// Hier wird überprüft, ob ein Breakpoint am angegebenen Programmzähler gesetzt ist
return breakpoints.contains(pc);
}
private Callback<ListView<String>, ListCell<String>> createBreakpointCell() {
return listView -> new ListCell<String>() {
private final CheckBox breakpointCheckBox = new CheckBox();
{
breakpointCheckBox.setOnAction(event -> {
int index = getIndex();
if (breakpointCheckBox.isSelected()) {
breakpoints.add(index);
} else {
breakpoints.remove(index);
}
});
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setGraphic(null);
} else {
setText(item);
setGraphic(breakpointCheckBox);
breakpointCheckBox.setSelected(breakpoints.contains(getIndex()));
}
}
};
}
@FXML
protected void loadLSTFileContent(String fileContent) {
ObservableList<String> items = FXCollections.observableArrayList(fileContent.split("\n"));
lstContentListView.setItems(items);
}
private File chooseLSTFile() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open LST File");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("LST Files", "*.lst", "*.LST"),
new FileChooser.ExtensionFilter("All Files", "*.*"));
return fileChooser.showOpenDialog(null);
}
@FXML
private void displayLSTFileContent(File selectedFile) {
try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) {
ObservableList<String> contentList = FXCollections.observableArrayList();
String line;
while ((line = reader.readLine()) != null) {
contentList.add(line);
}
lstContentListView.setItems(contentList);
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
public void toggleWatchdog(ActionEvent actionEvent) {
if (wdtCheck.isSelected())
WatchdogTimer.enable();
else
WatchdogTimer.disable();
}
@FXML
private ToggleButtonGroup bgTRISA0;
@FXML
private ToggleButtonGroup bgTRISA1;
@FXML
private ToggleButtonGroup bgTRISA2;
@FXML
private ToggleButtonGroup bgTRISA3;
@FXML
private ToggleButtonGroup bgTRISA4;
@FXML
private ToggleButtonGroup bgTRISB0;
@FXML
private ToggleButtonGroup bgTRISB1;
@FXML
private ToggleButtonGroup bgTRISB2;
@FXML
private ToggleButtonGroup bgTRISB3;
@FXML
private ToggleButtonGroup bgTRISB4;
@FXML
private ToggleButtonGroup bgTRISB5;
@FXML
private ToggleButtonGroup bgTRISB6;
@FXML
private ToggleButtonGroup bgTRISB7;
@FXML
private ToggleButtonGroup bgPORTA0;
@FXML
private ToggleButtonGroup bgPORTA1;
@FXML
private ToggleButtonGroup bgPORTA2;
@FXML
private ToggleButtonGroup bgPORTA3;
@FXML
private ToggleButtonGroup bgPORTA4;
@FXML
private ToggleButtonGroup bgPORTB0;
@FXML
private ToggleButtonGroup bgPORTB1;
@FXML
private ToggleButtonGroup bgPORTB2;
@FXML
private ToggleButtonGroup bgPORTB3;
@FXML
private ToggleButtonGroup bgPORTB4;
@FXML
private ToggleButtonGroup bgPORTB5;
@FXML
private ToggleButtonGroup bgPORTB6;
@FXML
private ToggleButtonGroup bgPORTB7;
private static ToggleButtonGroup[] allTRISbuttons;
private static ToggleButtonGroup[] allPORTbuttons;
private static Circle[] allLEDsA;
private static Circle[] allLEDsB;
private static ToggleButtonGroup dummy = new ToggleButtonGroup(new ToggleButton(), new ToggleButton());
public void initialize() {
ToggleButtonGroup [] allTRISButtons = {bgTRISA0, bgTRISA1, bgTRISA2, bgTRISA3, bgTRISA4, dummy, dummy, dummy, bgTRISB0, bgTRISB1, bgTRISB2, bgTRISB3, bgTRISB4, bgTRISB5, bgTRISB6, bgTRISB7};
ToggleButtonGroup [] allPORTButtons = {bgPORTA0, bgPORTA1, bgPORTA2, bgPORTA3, bgPORTA4, dummy, dummy, dummy, bgPORTB0, bgPORTB1, bgPORTB2, bgPORTB3, bgPORTB4, bgPORTB5, bgPORTB6, bgPORTB7};
Circle[] allLEDsA = {ledA0, ledA1, ledA2, ledA3, ledA4};
Circle[] allLEDsB = {ledB0, ledB1, ledB2, ledB3, ledB4, ledB5, ledB6, ledB7};
for (int i = 0; i<allPORTButtons.length; i++) {
allTRISButtons[i].getToggles().get(0).setSelected(true);
allPORTButtons[i].getToggles().get(0).setSelected(true);
allTRISButtons[i].getToggles().get(1).setSelected(false);
allPORTButtons[i].getToggles().get(1).setSelected(false);
ToggleButtonGroupExt.get().addAlwaysOneSelectedSupport(allTRISButtons[i]);
ToggleButtonGroupExt.get().addAlwaysOneSelectedSupport(allPORTButtons[i]);
}
ledCheckA.setSelected(false);
ledCheckB.setSelected(false);
setTRISbuttons(allTRISButtons);
setPORTbuttons(allPORTButtons);
IOPorts.setLEDs(allLEDsA, allLEDsB);
lstContentListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
autoRunGUI.setOnAction(this::autoRunGUI);
stopButton.setOnAction(this::stopAutoRun);
executionTimeComboBox.setItems(FXCollections.observableArrayList("8 MHZ", "4 MHZ", "1 MHZ", "500 HZ", "100 HZ", "32 HZ"));
executionTimeComboBox.setValue("4 MHZ");
executionTimeComboBox.setOnAction(event -> updateExecutionTimeMultiplier());
lstContentListView.setCellFactory(createBreakpointCell());
}
private static void setTRISbuttons(ToggleButtonGroup[] allButtons) {
allTRISbuttons = allButtons;
}
public static ToggleButtonGroup [] getTRISbuttons() {
return allTRISbuttons;
}
private static void setPORTbuttons(ToggleButtonGroup[] allButtons) {
allPORTbuttons = allButtons;
}
public static ToggleButtonGroup [] getPORTbuttons() {
return allPORTbuttons;
}
public static Circle[] getLEDsA() {
return allLEDsA;
}
public static Circle[] getLEDsB() {
return allLEDsB;
}
@FXML
private CheckBox ledCheckA;
@FXML
private CheckBox ledCheckB;
@FXML
private Circle ledA0;
@FXML
private Circle ledA1;
@FXML
private Circle ledA2;
@FXML
private Circle ledA3;
@FXML
private Circle ledA4;
@FXML
private Circle ledB0;
@FXML
private Circle ledB1;
@FXML
private Circle ledB2;
@FXML
private Circle ledB3;
@FXML
private Circle ledB4;
@FXML
private Circle ledB5;
@FXML
private Circle ledB6;
@FXML
private Circle ledB7;
@FXML
public void toggleLEDs (ActionEvent actionEvent) {
IOPorts.setLEDs(new boolean[]{ledCheckA.isSelected(), ledCheckB.isSelected()});
}
}