From d382181700162d5812034185c0b256075f1c5590 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Mon, 27 May 2024 19:15:04 +0300 Subject: [PATCH] Update architecture. Change mediator, add simple observer to track active 'transfers' --- .../Controllers/FilesDropHandle.java | 11 +- .../Controllers/FilesDropHandleTask.java | 8 +- .../Controllers/FontSettingsController.java | 6 +- .../Controllers/GamesController.java | 173 +++++++++--------- .../nsusbloader/Controllers/ISubscriber.java | 25 +++ .../Controllers/NSLMainController.java | 58 ++---- .../Controllers/NSTableViewController.java | 23 ++- .../Controllers/NxdtController.java | 29 ++- .../Controllers/PatchesController.java | 26 +-- .../java/nsusbloader/Controllers/Payload.java | 48 +++++ .../Controllers/RcmController.java | 45 ++--- .../SettingsBlockGenericController.java | 11 +- .../Controllers/SplitMergeController.java | 164 ++++++++--------- .../java/nsusbloader/MediatorControl.java | 77 ++++---- .../ModelControllers/LogPrinterGui.java | 10 +- .../ModelControllers/MessagesConsumer.java | 52 ++---- src/main/java/nsusbloader/NSLMain.java | 7 +- .../java/nsusbloader/TransfersPublisher.java | 47 +++++ .../nsusbloader/com/usb/GoldLeaf_010.java | 4 +- .../java/nsusbloader/com/usb/GoldLeaf_07.java | 4 +- .../java/nsusbloader/com/usb/GoldLeaf_08.java | 4 +- .../java/integration/EsIntegrationTest.java | 2 +- .../java/integration/FsIntegrationTest.java | 2 +- 23 files changed, 462 insertions(+), 374 deletions(-) create mode 100644 src/main/java/nsusbloader/Controllers/ISubscriber.java create mode 100644 src/main/java/nsusbloader/Controllers/Payload.java create mode 100644 src/main/java/nsusbloader/TransfersPublisher.java diff --git a/src/main/java/nsusbloader/Controllers/FilesDropHandle.java b/src/main/java/nsusbloader/Controllers/FilesDropHandle.java index 29f4482..d2042cc 100644 --- a/src/main/java/nsusbloader/Controllers/FilesDropHandle.java +++ b/src/main/java/nsusbloader/Controllers/FilesDropHandle.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -39,10 +39,13 @@ import java.util.ResourceBundle; public class FilesDropHandle { - public FilesDropHandle(List files, String filesRegex, String foldersRegex){ + public FilesDropHandle(List files, + String filesRegex, + String foldersRegex, + NSTableViewController tableController){ FilesDropHandleTask filesDropHandleTask = new FilesDropHandleTask(files, filesRegex, foldersRegex); - ResourceBundle resourceBundle = MediatorControl.getInstance().getResourceBundle(); + ResourceBundle resourceBundle = MediatorControl.INSTANCE.getResourceBundle(); Button cancelButton = new Button(resourceBundle.getString("btn_Cancel")); ProgressIndicator progressIndicator = new ProgressIndicator(); @@ -101,7 +104,7 @@ public class FilesDropHandle { List allFiles = filesDropHandleTask.getValue(); if (! allFiles.isEmpty()) { - MediatorControl.getInstance().getGamesController().tableFilesListController.setFiles(allFiles); + tableController.setFiles(allFiles); } stage.close(); }); diff --git a/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java b/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java index 93bc8ad..598bc41 100644 --- a/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java +++ b/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -32,7 +32,7 @@ public class FilesDropHandleTask extends Task> { private final List filesDropped; private final List allFiles; - private String messageTemplate; + private final String messageTemplate; private long filesScanned = 0; private long filesAdded = 0; @@ -43,12 +43,12 @@ public class FilesDropHandleTask extends Task> { this.filesRegex = filesRegex; this.foldersRegex = foldersRegex; this.allFiles = new ArrayList<>(); - this.messageTemplate = MediatorControl.getInstance().getResourceBundle().getString("windowBodyFilesScanned"); + this.messageTemplate = MediatorControl.INSTANCE.getResourceBundle().getString("windowBodyFilesScanned"); } @Override protected List call() { - if (filesDropped == null || filesDropped.size() == 0) + if (filesDropped == null || filesDropped.isEmpty()) return allFiles; for (File file : filesDropped){ diff --git a/src/main/java/nsusbloader/Controllers/FontSettingsController.java b/src/main/java/nsusbloader/Controllers/FontSettingsController.java index 0f7f14c..98c20a6 100644 --- a/src/main/java/nsusbloader/Controllers/FontSettingsController.java +++ b/src/main/java/nsusbloader/Controllers/FontSettingsController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2023 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -142,7 +142,9 @@ public class FontSettingsController implements Initializable { final double fontSize = fontSizeSpinner.getValue().intValue(); preferences.setFontStyle(fontFamily, fontSize); - MediatorControl.getInstance().updateApplicationFont(fontFamily, fontSize); + + MediatorControl.INSTANCE.getLogArea().getScene().getRoot().setStyle( + String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize)); closeWindow(); } diff --git a/src/main/java/nsusbloader/Controllers/GamesController.java b/src/main/java/nsusbloader/Controllers/GamesController.java index 3c78b99..364cb08 100644 --- a/src/main/java/nsusbloader/Controllers/GamesController.java +++ b/src/main/java/nsusbloader/Controllers/GamesController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko, wolfposd + Copyright 2019-2024 Dmitry Isaenko, wolfposd This file is part of NS-USBloader. @@ -31,6 +31,7 @@ import javafx.scene.layout.Region; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import nsusbloader.AppPreferences; +import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.com.net.NETCommunications; import nsusbloader.com.usb.UsbCommunications; import nsusbloader.FilesHelper; @@ -45,12 +46,14 @@ import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; -public class GamesController implements Initializable { +public class GamesController implements Initializable, ISubscriber { private static final String REGEX_ONLY_NSP = ".*\\.nsp$"; private static final String REGEX_ALLFILES_TINFOIL = ".*\\.(nsp$|xci$|nsz$|xcz$)"; private static final String REGEX_ALLFILES = ".*"; + private static final MediatorControl mediator = MediatorControl.INSTANCE; + @FXML private AnchorPane usbNetPane; @@ -63,7 +66,7 @@ public class GamesController implements Initializable { @FXML private Button switchThemeBtn; @FXML - public NSTableViewController tableFilesListController; // Accessible from Mediator (for drag-n-drop support) + private NSTableViewController tableFilesListController; @FXML private Button selectNspBtn, selectSplitBtn, uploadStopBtn; @@ -101,6 +104,7 @@ public class GamesController implements Initializable { disableUploadStopBtn(tableFilesListController.isFilesForUploadListEmpty()); }); // Add listener to notify tableView controller tableFilesListController.setNewProtocol(getSelectedProtocolByName()); // Notify tableView controller + tableFilesListController.setGamesController(this); ObservableList choiceNetUsbList = FXCollections.observableArrayList("USB", "NET"); choiceNetUsb.setItems(choiceNetUsbList); @@ -204,11 +208,11 @@ public class GamesController implements Initializable { } private boolean isAllFiletypesAllowedForGL() { - return ! MediatorControl.getInstance().getSettingsController().getGoldleafSettings().getNSPFileFilterForGL(); + return ! mediator.getSettingsController().getGoldleafSettings().getNSPFileFilterForGL(); } private boolean isXciNszXczSupport() { - return MediatorControl.getInstance().getSettingsController().getTinfoilSettings().isXciNszXczSupport(); + return mediator.getSettingsController().getTinfoilSettings().isXciNszXczSupport(); } /** @@ -216,7 +220,7 @@ public class GamesController implements Initializable { * tinfoil + xcinszxcz
* tinfoil + nsponly
* goldleaf
- * etc.. + * etc... */ private String getRegexForFiles() { if (isTinfoil() && isXciNszXczSupport()) @@ -368,56 +372,58 @@ public class GamesController implements Initializable { if (workThread != null && workThread.isAlive()) return; - // Collect files - List nspToUpload; - - TextArea logArea = MediatorControl.getInstance().getContoller().logArea; - if (isTinfoil() && tableFilesListController.getFilesForUpload() == null) { - logArea.setText(resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected")); + ServiceWindow.getInfoNotification("(o_o\")", resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected")); return; } - if ((nspToUpload = tableFilesListController.getFilesForUpload()) != null){ + // Collect files + List nspToUpload = tableFilesListController.getFilesForUpload(); + + if (nspToUpload == null) + nspToUpload = new ArrayList<>(); + //todo: add to make it visible + /* + else { + TextArea logArea = mediator.getLogArea(); logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n"); nspToUpload.forEach(item -> logArea.appendText(" "+item.getAbsolutePath()+"\n")); } - else { - logArea.clear(); - nspToUpload = new LinkedList<>(); - } + */ - SettingsController settings = MediatorControl.getInstance().getSettingsController(); + SettingsController settings = mediator.getSettingsController(); // If USB selected if (isGoldLeaf()){ final SettingsBlockGoldleafController goldleafSettings = settings.getGoldleafSettings(); usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + goldleafSettings.getGlVer(), goldleafSettings.getNSPFileFilterForGL()); } - else if (( isTinfoil() && getSelectedNetUsb().equals("USB") )){ - usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false); - } - else { // NET INSTALL OVER TINFOIL - final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; - final SettingsBlockTinfoilController tinfoilSettings = settings.getTinfoilSettings(); - - if (tinfoilSettings.isValidateNSHostName() && ! getNsIp().matches(ipValidationPattern)) { - if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"), resourceBundle.getString("windowBodyBadIp"))) - return; + else { + if (getSelectedNetUsb().equals("USB")){ + usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false); } + else { // NET INSTALL OVER TINFOIL + final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; + final SettingsBlockTinfoilController tinfoilSettings = settings.getTinfoilSettings(); - String nsIP = getNsIp(); + if (tinfoilSettings.isValidateNSHostName() && ! getNsIp().matches(ipValidationPattern)) { + if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"), resourceBundle.getString("windowBodyBadIp"))) + return; + } - if (! tinfoilSettings.isExpertModeSelected()) - usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", ""); - else { - usbNetCommunications = new NETCommunications( - nspToUpload, - nsIP, - tinfoilSettings.isNoRequestsServe(), - tinfoilSettings.isAutoDetectIp()?"":tinfoilSettings.getHostIp(), - tinfoilSettings.isRandomlySelectPort()?"":tinfoilSettings.getHostPort(), - tinfoilSettings.isNoRequestsServe()?tinfoilSettings.getHostExtra():"" - ); + String nsIP = getNsIp(); + + if (! tinfoilSettings.isExpertModeSelected()) + usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", ""); + else { + usbNetCommunications = new NETCommunications( + nspToUpload, + nsIP, + tinfoilSettings.isNoRequestsServe(), + tinfoilSettings.isAutoDetectIp()?"":tinfoilSettings.getHostIp(), + tinfoilSettings.isRandomlySelectPort()?"":tinfoilSettings.getHostPort(), + tinfoilSettings.isNoRequestsServe()?tinfoilSettings.getHostExtra():"" + ); + } } } workThread = new Thread(usbNetCommunications); @@ -446,7 +452,7 @@ public class GamesController implements Initializable { * */ @FXML private void handleDragOver(DragEvent event){ - if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive()) + if (event.getDragboard().hasFiles() && ! mediator.getTransferActive()) event.acceptTransferModes(TransferMode.ANY); event.consume(); } @@ -456,47 +462,15 @@ public class GamesController implements Initializable { @FXML private void handleDrop(DragEvent event) { List files = event.getDragboard().getFiles(); - new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders()); + new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders(), tableFilesListController); event.setDropCompleted(true); event.consume(); } - + /** - * This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission" - * Called from mediator - * TODO: remove shitcoding practices + * This function called from NSTableViewController * */ - public void notifyThreadStarted(boolean isActive, EModule type){ - if (! type.equals(EModule.USB_NET_TRANSFERS)){ - usbNetPane.setDisable(isActive); - return; - } - - selectNspBtn.setDisable(isActive); - selectSplitBtn.setDisable(isActive); - btnUpStopImage.getStyleClass().clear(); - - if (isActive) { - btnUpStopImage.getStyleClass().add("regionStop"); - - uploadStopBtn.setOnAction(e-> stopBtnAction()); - uploadStopBtn.setText(resourceBundle.getString("btn_Stop")); - uploadStopBtn.getStyleClass().remove("buttonUp"); - uploadStopBtn.getStyleClass().add("buttonStop"); - } - else { - btnUpStopImage.getStyleClass().add("regionUpload"); - - uploadStopBtn.setOnAction(e-> uploadBtnAction()); - uploadStopBtn.setText(resourceBundle.getString("btn_Upload")); - uploadStopBtn.getStyleClass().remove("buttonStop"); - uploadStopBtn.getStyleClass().add("buttonUp"); - } - } - /** - * Crunch. This function called from NSTableViewController - * */ - public void disableUploadStopBtn(boolean disable){ + void disableUploadStopBtn(boolean disable){ if (isTinfoil()) uploadStopBtn.setDisable(disable); else @@ -515,11 +489,8 @@ public class GamesController implements Initializable { }).start(); } - public void updateFilesSelectorButtonBehaviour(boolean isDirectoryChooser){ + void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){ btnSelectImage.getStyleClass().clear(); - setFilesSelectorButtonBehaviour(isDirectoryChooser); - } - private void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){ if (isDirectoryChooser){ selectNspBtn.setOnAction(e -> selectFoldersBtnAction()); btnSelectImage.getStyleClass().add("regionScanFolders"); @@ -535,7 +506,7 @@ public class GamesController implements Initializable { /** * Get 'Recent' path */ - public String getRecentPath(){ + private String getRecentPath(){ return previouslyOpenedPath; } @@ -547,4 +518,42 @@ public class GamesController implements Initializable { preferences.setNetUsb(getSelectedNetUsb()); preferences.setNsIp(getNsIp()); } + + /** + * This thing modifies UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission" + * */ + @Override + public void notify(EModule type, boolean isActive, Payload payload) { + if (! type.equals(EModule.USB_NET_TRANSFERS)){ + usbNetPane.setDisable(isActive); + return; + } + + selectNspBtn.setDisable(isActive); + selectSplitBtn.setDisable(isActive); + btnUpStopImage.getStyleClass().clear(); + + if (isActive) { + btnUpStopImage.getStyleClass().add("regionStop"); + + uploadStopBtn.setOnAction(e-> stopBtnAction()); + uploadStopBtn.setText(resourceBundle.getString("btn_Stop")); + uploadStopBtn.getStyleClass().remove("buttonUp"); + uploadStopBtn.getStyleClass().add("buttonStop"); + return; + } + btnUpStopImage.getStyleClass().add("regionUpload"); + + uploadStopBtn.setOnAction(e-> uploadBtnAction()); + uploadStopBtn.setText(resourceBundle.getString("btn_Upload")); + uploadStopBtn.getStyleClass().remove("buttonStop"); + uploadStopBtn.getStyleClass().add("buttonUp"); + + Map statusMap = payload.getStatusMap(); + + if (! statusMap.isEmpty()) { + for (String key : statusMap.keySet()) + tableFilesListController.setFileStatus(key, statusMap.get(key)); + } + } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/Controllers/ISubscriber.java b/src/main/java/nsusbloader/Controllers/ISubscriber.java new file mode 100644 index 0000000..1e1ba59 --- /dev/null +++ b/src/main/java/nsusbloader/Controllers/ISubscriber.java @@ -0,0 +1,25 @@ +/* + Copyright 2019-2024 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader.Controllers; + +import nsusbloader.NSLDataTypes.EModule; + +public interface ISubscriber { + void notify(EModule type, boolean status, Payload payload); +} diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java index 533c450..a159c9e 100644 --- a/src/main/java/nsusbloader/Controllers/NSLMainController.java +++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -18,7 +18,6 @@ */ package nsusbloader.Controllers; -import javafx.application.HostServices; import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -35,10 +34,10 @@ public class NSLMainController implements Initializable { private ResourceBundle resourceBundle; @FXML - public TextArea logArea; // Accessible from Mediator + private TextArea logArea; @FXML - public ProgressBar progressBar; // Accessible from Mediator + private ProgressBar progressBar; @FXML private TabPane mainTabPane; @@ -68,8 +67,6 @@ public class NSLMainController implements Initializable { logArea.appendText(rb.getString("tab3_Txt_GreetingsMessage2")+"\n"); - MediatorControl.getInstance().setController(this); - AppPreferences preferences = AppPreferences.getInstance(); if (preferences.getAutoCheckUpdates()) @@ -79,6 +76,22 @@ public class NSLMainController implements Initializable { mainTabPane.getTabs().remove(3); openLastOpenedTab(); + + TransfersPublisher transfersPublisher = new TransfersPublisher( + GamesTabController, + SplitMergeTabController, + RcmTabController, + NXDTabController, + PatchesTabController); + + MediatorControl.INSTANCE.configure( + resourceBundle, + SettingsTabController, + logArea, + progressBar, + GamesTabController, + transfersPublisher); + } private void checkForUpdates(){ Task> updTask = new UpdatesChecker(); @@ -101,40 +114,7 @@ public class NSLMainController implements Initializable { updates.setDaemon(true); updates.start(); } - /** - * Get resources - * TODO: Find better solution; used in UsbCommunications() -> GL -> SelectFile command - * @return ResourceBundle - */ - public ResourceBundle getResourceBundle() { - return resourceBundle; - } - /** - * Provide hostServices to Settings tab - * */ - public void setHostServices(HostServices hs ){ SettingsTabController.getGenericSettings().registerHostServices(hs);} - /** - * Get 'Settings' controller - * Used by FrontController - * */ - public SettingsController getSettingsCtrlr(){ - return SettingsTabController; - } - - public GamesController getGamesCtrlr(){ - return GamesTabController; - } - - public SplitMergeController getSmCtrlr(){ - return SplitMergeTabController; - } - - public RcmController getRcmCtrlr(){ return RcmTabController; } - - public NxdtController getNXDTabController(){ return NXDTabController; } - - public PatchesController getPatchesTabController(){ return PatchesTabController; } /** * Save preferences before exit * */ diff --git a/src/main/java/nsusbloader/Controllers/NSTableViewController.java b/src/main/java/nsusbloader/Controllers/NSTableViewController.java index 267da43..379ba79 100644 --- a/src/main/java/nsusbloader/Controllers/NSTableViewController.java +++ b/src/main/java/nsusbloader/Controllers/NSTableViewController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko, wolfposd + Copyright 2019-2024 Dmitry Isaenko, wolfposd This file is part of NS-USBloader. @@ -42,6 +42,8 @@ public class NSTableViewController implements Initializable { private TableView table; private ObservableList rowsObsLst; + private GamesController gamesController; + @Override public void initialize(URL url, ResourceBundle resourceBundle) { rowsObsLst = FXCollections.observableArrayList(); @@ -52,10 +54,10 @@ public class NSTableViewController implements Initializable { table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); table.setOnKeyPressed(keyEvent -> { if (!rowsObsLst.isEmpty()) { - if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.getInstance().getTransferActive()) { + if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.INSTANCE.getTransferActive()) { rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems()); if (rowsObsLst.isEmpty()) - MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better + gamesController.disableUploadStopBtn(true); table.refresh(); } else if (keyEvent.getCode() == KeyCode.SPACE) { for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) { @@ -173,13 +175,13 @@ public class NSTableViewController implements Initializable { deleteMenuItem.setOnAction(actionEvent -> { rowsObsLst.remove(row.getItem()); if (rowsObsLst.isEmpty()) - MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better + gamesController.disableUploadStopBtn(true); table.refresh(); }); MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll")); deleteAllMenuItem.setOnAction(actionEvent -> { rowsObsLst.clear(); - MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better + gamesController.disableUploadStopBtn(true); table.refresh(); }); contextMenu.getItems().addAll(deleteMenuItem, deleteAllMenuItem); @@ -189,7 +191,7 @@ public class NSTableViewController implements Initializable { Bindings.when( Bindings.isNotNull( row.itemProperty())) - .then(MediatorControl.getInstance().getTransferActive()?null:contextMenu) + .then(MediatorControl.INSTANCE.getTransferActive()?null:contextMenu) .otherwise((ContextMenu) null) ); // Just.. don't ask.. @@ -210,6 +212,11 @@ public class NSTableViewController implements Initializable { table.getColumns().add(fileSizeColumn); table.getColumns().add(uploadColumn); } + + public void setGamesController(GamesController gamesController) { + this.gamesController = gamesController; + } + /** * Add single file when user selected it (Split file usually) * */ @@ -224,7 +231,7 @@ public class NSTableViewController implements Initializable { } else { rowsObsLst.add(new NSLRowModel(file, true)); - MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better + gamesController.disableUploadStopBtn(false); } table.refresh(); } @@ -244,7 +251,7 @@ public class NSTableViewController implements Initializable { else { for (File file: newFiles) rowsObsLst.add(new NSLRowModel(file, true)); - MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better + gamesController.disableUploadStopBtn(false); } //rowsObsLst.get(0).setMarkForUpload(true); table.refresh(); diff --git a/src/main/java/nsusbloader/Controllers/NxdtController.java b/src/main/java/nsusbloader/Controllers/NxdtController.java index c824cc9..a6439c6 100644 --- a/src/main/java/nsusbloader/Controllers/NxdtController.java +++ b/src/main/java/nsusbloader/Controllers/NxdtController.java @@ -25,8 +25,6 @@ import javafx.scene.control.Label; import javafx.scene.layout.Region; import javafx.stage.DirectoryChooser; import nsusbloader.AppPreferences; -import nsusbloader.FilesHelper; -import nsusbloader.MediatorControl; import nsusbloader.ModelControllers.CancellableRunnable; import nsusbloader.NSLDataTypes.EModule; import nsusbloader.Utilities.nxdumptool.NxdtTask; @@ -35,7 +33,7 @@ import java.io.File; import java.net.URL; import java.util.ResourceBundle; -public class NxdtController implements Initializable { +public class NxdtController implements Initializable, ISubscriber { @FXML private Label saveToLocationLbl, statusLbl; @@ -79,7 +77,6 @@ public class NxdtController implements Initializable { * */ private void startDumpProcess(){ if ((workThread == null || ! workThread.isAlive())){ - MediatorControl.getInstance().getContoller().logArea.clear(); nxdtTask = new NxdtTask(saveToLocationLbl.getText()); workThread = new Thread(nxdtTask); @@ -97,12 +94,22 @@ public class NxdtController implements Initializable { } } - public void notifyThreadStarted(boolean isActive, EModule type){ + /** + * Save application settings on exit + * */ + public void updatePreferencesOnExit(){ + AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText()); + } + + @Override + public void notify(EModule type, boolean isActive, Payload payload) { if (! type.equals(EModule.NXDT)){ injectPldBtn.setDisable(isActive); return; } + statusLbl.setText(payload.getMessage()); + if (isActive) { btnDumpStopImage.getStyleClass().clear(); btnDumpStopImage.getStyleClass().add("regionStop"); @@ -121,16 +128,4 @@ public class NxdtController implements Initializable { injectPldBtn.getStyleClass().remove("buttonStop"); injectPldBtn.getStyleClass().add("buttonUp"); } - public void setOneLineStatus(boolean status){ - if (status) - statusLbl.setText(rb.getString("done_txt")); - else - statusLbl.setText(rb.getString("failure_txt")); - } - /** - * Save application settings on exit - * */ - public void updatePreferencesOnExit(){ - AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText()); - } } diff --git a/src/main/java/nsusbloader/Controllers/PatchesController.java b/src/main/java/nsusbloader/Controllers/PatchesController.java index 6afd267..a2f0b8c 100644 --- a/src/main/java/nsusbloader/Controllers/PatchesController.java +++ b/src/main/java/nsusbloader/Controllers/PatchesController.java @@ -1,5 +1,5 @@ /* - Copyright 2018-2022 Dmitry Isaenko + Copyright 2018-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -46,7 +46,7 @@ import nsusbloader.Utilities.patches.fs.FsPatchMaker; import nsusbloader.Utilities.patches.loader.LoaderPatchMaker; // TODO: CLI SUPPORT -public class PatchesController implements Initializable { +public class PatchesController implements Initializable, ISubscriber { @FXML private VBox patchesToolPane; @FXML @@ -237,9 +237,8 @@ public class PatchesController implements Initializable { if (workThread != null && workThread.isAlive()) return; - statusLbl.setText(""); - if (MediatorControl.getInstance().getTransferActive()) { + if (MediatorControl.INSTANCE.getTransferActive()) { ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); return; @@ -261,9 +260,8 @@ public class PatchesController implements Initializable { if (workThread != null && workThread.isAlive()) return; - statusLbl.setText(""); - if (MediatorControl.getInstance().getTransferActive()) { + if (MediatorControl.INSTANCE.getTransferActive()) { ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); return; @@ -285,9 +283,8 @@ public class PatchesController implements Initializable { if (workThread != null && workThread.isAlive()) return; - statusLbl.setText(""); - if (MediatorControl.getInstance().getTransferActive()) { + if (MediatorControl.INSTANCE.getTransferActive()) { ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); return; @@ -306,18 +303,20 @@ public class PatchesController implements Initializable { workThread.interrupt(); } - public void notifyThreadStarted(boolean isActive, EModule type) { + @Override + public void notify(EModule type, boolean isActive, Payload payload) { if (! type.equals(EModule.PATCHES)) { patchesToolPane.setDisable(isActive); return; } + statusLbl.setText(payload.getMessage()); + convertRegionEs.getStyleClass().clear(); makeFsBtn.setVisible(! isActive); makeLoaderBtn.setVisible(! isActive); if (isActive) { - MediatorControl.getInstance().getContoller().logArea.clear(); convertRegionEs.getStyleClass().add("regionStop"); makeEsBtn.setOnAction(e-> interruptProcessOfPatchMaking()); @@ -334,13 +333,6 @@ public class PatchesController implements Initializable { makeEsBtn.getStyleClass().add("buttonUp"); } - public void setOneLineStatus(boolean statusSuccess){ - if (statusSuccess) - statusLbl.setText(resourceBundle.getString("done_txt")); - else - statusLbl.setText(resourceBundle.getString("failure_txt")); - } - void updatePreferencesOnExit(){ AppPreferences.getInstance().setPatchesSaveToLocation(saveToLbl.getText()); if (locationKeysLbl.getText().isEmpty()) diff --git a/src/main/java/nsusbloader/Controllers/Payload.java b/src/main/java/nsusbloader/Controllers/Payload.java new file mode 100644 index 0000000..3b37fc1 --- /dev/null +++ b/src/main/java/nsusbloader/Controllers/Payload.java @@ -0,0 +1,48 @@ +/* + Copyright 2019-2024 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader.Controllers; + +import nsusbloader.NSLDataTypes.EFileStatus; + +import java.util.Collections; +import java.util.Map; + +public class Payload { + private final String message; + private final Map statusMap; + + public Payload(){ + this(""); + } + public Payload(String message){ + this(message, Collections.emptyMap()); + } + public Payload(String message, Map statusMap){ + this.message = message; + this.statusMap = statusMap; + } + + public String getMessage() { + return message; + } + + public Map getStatusMap() { + return statusMap; + } +} diff --git a/src/main/java/nsusbloader/Controllers/RcmController.java b/src/main/java/nsusbloader/Controllers/RcmController.java index 3fc6b5e..de29650 100644 --- a/src/main/java/nsusbloader/Controllers/RcmController.java +++ b/src/main/java/nsusbloader/Controllers/RcmController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -41,7 +41,7 @@ import java.io.File; import java.net.URL; import java.util.ResourceBundle; -public class RcmController implements Initializable { +public class RcmController implements Initializable, ISubscriber { @FXML private ToggleGroup rcmToggleGrp; @@ -68,12 +68,14 @@ public class RcmController implements Initializable { @FXML private Label statusLbl; + private AppPreferences preferences; private ResourceBundle rb; private String myRegexp; + @Override public void initialize(URL url, ResourceBundle resourceBundle) { this.rb = resourceBundle; - final AppPreferences preferences = AppPreferences.getInstance(); + this.preferences = AppPreferences.getInstance(); rcmToggleGrp.selectToggle(pldrRadio1); pldrRadio1.setOnAction(e -> statusLbl.setText("")); @@ -193,8 +195,7 @@ public class RcmController implements Initializable { } private void smash(){ - statusLbl.setText(""); - if (MediatorControl.getInstance().getTransferActive()) { + if (MediatorControl.INSTANCE.getTransferActive()) { ServiceWindow.getErrorNotification(rb.getString("windowTitleError"), rb.getString("windowBodyPleaseStopOtherProcessFirst")); return; @@ -273,31 +274,28 @@ public class RcmController implements Initializable { private void bntResetPayloader(ActionEvent event){ final Node btn = (Node)event.getSource(); + statusLbl.setText(""); + switch (btn.getId()){ case "resPldBtn1": payloadFNameLbl1.setText(""); payloadFPathLbl1.setText(""); - statusLbl.setText(""); break; case "resPldBtn2": payloadFNameLbl2.setText(""); payloadFPathLbl2.setText(""); - statusLbl.setText(""); break; case "resPldBtn3": payloadFNameLbl3.setText(""); payloadFPathLbl3.setText(""); - statusLbl.setText(""); break; case "resPldBtn4": payloadFNameLbl4.setText(""); payloadFPathLbl4.setText(""); - statusLbl.setText(""); break; case "resPldBtn5": payloadFNameLbl5.setText(""); payloadFPathLbl5.setText(""); - statusLbl.setText(""); } } @@ -324,27 +322,20 @@ public class RcmController implements Initializable { } } - public void setOneLineStatus(boolean statusSuccess){ - if (statusSuccess) - statusLbl.setText(rb.getString("done_txt")); - else - statusLbl.setText(rb.getString("failure_txt")); - } - - public void notifyThreadStarted(boolean isStart, EModule type){ - rcmToolPane.setDisable(isStart); - if (type.equals(EModule.RCM) && isStart){ - MediatorControl.getInstance().getContoller().logArea.clear(); - } + @Override + public void notify(EModule type, boolean isActive, Payload payload) { + rcmToolPane.setDisable(isActive); + if (type.equals(EModule.RCM)) + statusLbl.setText(payload.getMessage()); } /** * Save application settings on exit * */ public void updatePreferencesOnExit(){ - AppPreferences.getInstance().setRecentRcm(1, payloadFPathLbl1.getText()); - AppPreferences.getInstance().setRecentRcm(2, payloadFPathLbl2.getText()); - AppPreferences.getInstance().setRecentRcm(3, payloadFPathLbl3.getText()); - AppPreferences.getInstance().setRecentRcm(4, payloadFPathLbl4.getText()); - AppPreferences.getInstance().setRecentRcm(5, payloadFPathLbl5.getText()); + preferences.setRecentRcm(1, payloadFPathLbl1.getText()); + preferences.setRecentRcm(2, payloadFPathLbl2.getText()); + preferences.setRecentRcm(3, payloadFPathLbl3.getText()); + preferences.setRecentRcm(4, payloadFPathLbl4.getText()); + preferences.setRecentRcm(5, payloadFPathLbl5.getText()); } } diff --git a/src/main/java/nsusbloader/Controllers/SettingsBlockGenericController.java b/src/main/java/nsusbloader/Controllers/SettingsBlockGenericController.java index c90f049..fc4b584 100644 --- a/src/main/java/nsusbloader/Controllers/SettingsBlockGenericController.java +++ b/src/main/java/nsusbloader/Controllers/SettingsBlockGenericController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -55,9 +55,7 @@ public class SettingsBlockGenericController implements Initializable { direcroriesChooserForRomsCB; @FXML private Hyperlink newVersionHyperlink; - private ResourceBundle resourceBundle; - private HostServices hostServices; @Override @@ -68,8 +66,8 @@ public class SettingsBlockGenericController implements Initializable { autoCheckForUpdatesCB.setSelected(preferences.getAutoCheckUpdates()); direcroriesChooserForRomsCB.setSelected(preferences.getDirectoriesChooserForRoms()); direcroriesChooserForRomsCB.setOnAction(actionEvent -> - MediatorControl.getInstance().getGamesController().updateFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected()) - ); + MediatorControl.INSTANCE.getGamesController().setFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected()) + ); Region btnSwitchImage = new Region(); btnSwitchImage.getStyleClass().add("regionUpdatesCheck"); @@ -81,6 +79,7 @@ public class SettingsBlockGenericController implements Initializable { languagesChB.setItems(settingsLanguagesSetup.getLanguages()); languagesChB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage()); + hostServices = MediatorControl.INSTANCE.getHostServices(); newVersionHyperlink.setOnAction(e-> hostServices.showDocument(newVersionHyperlink.getText())); checkForUpdBtn.setOnAction(e->checkForUpdatesAction()); submitLanguageBtn.setOnAction(e->languageButtonAction()); @@ -149,8 +148,6 @@ public class SettingsBlockGenericController implements Initializable { return direcroriesChooserForRomsCB.isSelected(); } - protected void registerHostServices(HostServices hostServices){ this.hostServices = hostServices;} - void setNewVersionLink(String newVer){ newVersionHyperlink.setVisible(true); newVersionHyperlink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer); diff --git a/src/main/java/nsusbloader/Controllers/SplitMergeController.java b/src/main/java/nsusbloader/Controllers/SplitMergeController.java index 57de95d..10e1de3 100644 --- a/src/main/java/nsusbloader/Controllers/SplitMergeController.java +++ b/src/main/java/nsusbloader/Controllers/SplitMergeController.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -31,7 +31,6 @@ import javafx.stage.FileChooser; import nsusbloader.AppPreferences; import nsusbloader.FilesHelper; import nsusbloader.MediatorControl; -import nsusbloader.ModelControllers.CancellableRunnable; import nsusbloader.NSLDataTypes.EModule; import nsusbloader.ServiceWindow; import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor; @@ -41,7 +40,7 @@ import java.net.URL; import java.util.List; import java.util.ResourceBundle; -public class SplitMergeController implements Initializable { +public class SplitMergeController implements Initializable, ISubscriber { @FXML private ToggleGroup splitMergeTogGrp; @FXML @@ -147,13 +146,87 @@ public class SplitMergeController implements Initializable { convertBtn.setOnAction(actionEvent -> setConvertBtnAction()); } - public void notifyThreadStarted(boolean isStart, EModule type){ // todo: refactor: remove everything, place to separate container and just disable. - if (! type.equals(EModule.SPLIT_MERGE_TOOL)){ - smToolPane.setDisable(isStart); + /** + * It's button listener when convert-process in progress + * */ + private void stopBtnAction(){ + if (smThread != null && smThread.isAlive()) { + smThread.interrupt(); + } + } + /** + * It's button listener when convert-process NOT in progress + * */ + private void setConvertBtnAction(){ + if (MediatorControl.INSTANCE.getTransferActive()) { + ServiceWindow.getErrorNotification( + resourceBundle.getString("windowTitleError"), + resourceBundle.getString("windowBodyPleaseFinishTransfersFirst") + ); return; } - if (isStart){ - MediatorControl.getInstance().getContoller().logArea.clear(); + + if (splitRad.isSelected()) + smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText()); + else + smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText()); + smThread = new Thread(smTask); + smThread.setDaemon(true); + smThread.start(); + } + /** + * Drag-n-drop support (dragOver consumer) + * */ + @FXML + private void handleDragOver(DragEvent event){ + if (event.getDragboard().hasFiles() && ! MediatorControl.INSTANCE.getTransferActive()) + event.acceptTransferModes(TransferMode.ANY); + event.consume(); + } + /** + * Drag-n-drop support (drop consumer) + * */ + @FXML + private void handleDrop(DragEvent event) { + List files = event.getDragboard().getFiles(); + File firstFile = files.get(0); + + if (firstFile.isDirectory()) + mergeRad.fire(); + else + splitRad.fire(); + + this.BlockListViewController.addAll(files); + + event.setDropCompleted(true); + event.consume(); + } + + + /** + * Save application settings on exit + * */ + public void updatePreferencesOnExit(){ + if (splitRad.isSelected()) + AppPreferences.getInstance().setSplitMergeType(0); + else + AppPreferences.getInstance().setSplitMergeType(1); + + AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText()); + } + + @Override + public void notify(EModule type, boolean isActive, Payload payload) { + // todo: refactor: remove everything, place to separate container and just disable. + + if (! type.equals(EModule.SPLIT_MERGE_TOOL)){ + smToolPane.setDisable(isActive); + return; + } + + statusLbl.setText(payload.getMessage()); + + if (isActive){ splitRad.setDisable(true); mergeRad.setDisable(true); selectFileFolderBtn.setDisable(true); @@ -182,79 +255,4 @@ public class SplitMergeController implements Initializable { else convertRegion.getStyleClass().add("regionOneToSplit"); } - - /** - * It's button listener when convert-process in progress - * */ - private void stopBtnAction(){ - if (smThread != null && smThread.isAlive()) { - smThread.interrupt(); - } - } - /** - * It's button listener when convert-process NOT in progress - * */ - private void setConvertBtnAction(){ - statusLbl.setText(""); - if (MediatorControl.getInstance().getTransferActive()) { - ServiceWindow.getErrorNotification( - resourceBundle.getString("windowTitleError"), - resourceBundle.getString("windowBodyPleaseFinishTransfersFirst") - ); - return; - } - - if (splitRad.isSelected()) - smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText()); - else - smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText()); - smThread = new Thread(smTask); - smThread.setDaemon(true); - smThread.start(); - } - /** - * Drag-n-drop support (dragOver consumer) - * */ - @FXML - private void handleDragOver(DragEvent event){ - if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive()) - event.acceptTransferModes(TransferMode.ANY); - event.consume(); - } - /** - * Drag-n-drop support (drop consumer) - * */ - @FXML - private void handleDrop(DragEvent event) { - List files = event.getDragboard().getFiles(); - File firstFile = files.get(0); - - if (firstFile.isDirectory()) - mergeRad.fire(); - else - splitRad.fire(); - - this.BlockListViewController.addAll(files); - - event.setDropCompleted(true); - event.consume(); - } - - public void setOneLineStatus(boolean status){ - if (status) - statusLbl.setText(resourceBundle.getString("done_txt")); - else - statusLbl.setText(resourceBundle.getString("failure_txt")); - } - /** - * Save application settings on exit - * */ - public void updatePreferencesOnExit(){ - if (splitRad.isSelected()) - AppPreferences.getInstance().setSplitMergeType(0); - else - AppPreferences.getInstance().setSplitMergeType(1); - - AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText()); - } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/MediatorControl.java b/src/main/java/nsusbloader/MediatorControl.java index a73b239..af2cb27 100644 --- a/src/main/java/nsusbloader/MediatorControl.java +++ b/src/main/java/nsusbloader/MediatorControl.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -18,50 +18,57 @@ */ package nsusbloader; +import javafx.application.HostServices; +import javafx.scene.control.ProgressBar; +import javafx.scene.control.TextArea; import nsusbloader.Controllers.*; import nsusbloader.NSLDataTypes.EModule; import java.util.ResourceBundle; -import java.util.concurrent.atomic.AtomicBoolean; public class MediatorControl { - private final AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure - private NSLMainController mainController; + public static final MediatorControl INSTANCE = new MediatorControl(); - public static MediatorControl getInstance(){ - return MediatorControlHold.INSTANCE; + private ResourceBundle resourceBundle; + private TransfersPublisher transfersPublisher; + private HostServices hostServices; + private GamesController gamesController; + private SettingsController settingsController; + + private TextArea logArea; + private ProgressBar progressBar; + + private MediatorControl(){} + + public void configure(ResourceBundle resourceBundle, + SettingsController settingsController, + TextArea logArea, + ProgressBar progressBar, + GamesController gamesController, + TransfersPublisher transfersPublisher) { + this.resourceBundle = resourceBundle; + this.settingsController = settingsController; + this.gamesController = gamesController; + this.logArea = logArea; + this.progressBar = progressBar; + this.transfersPublisher = transfersPublisher; + } + public void setHostServices(HostServices hostServices) { + this.hostServices = hostServices; } - private static class MediatorControlHold { - private static final MediatorControl INSTANCE = new MediatorControl(); - } - public void setController(NSLMainController controller){ - this.mainController = controller; + public HostServices getHostServices() { return hostServices; } + public ResourceBundle getResourceBundle(){ return resourceBundle; } + public SettingsController getSettingsController() { return settingsController; } + public GamesController getGamesController() { return gamesController; } + public TextArea getLogArea() { return logArea; } + public ProgressBar getProgressBar() { return progressBar; } + + public synchronized void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) { + transfersPublisher.setTransferActive(appModuleType, isActive, payload); } - public NSLMainController getContoller(){ return mainController; } - public GamesController getGamesController(){ return mainController.getGamesCtrlr(); } - public SettingsController getSettingsController(){ return mainController.getSettingsCtrlr(); } - public SplitMergeController getSplitMergeController(){ return mainController.getSmCtrlr(); } - public RcmController getRcmController(){ return mainController.getRcmCtrlr(); } - public NxdtController getNxdtController(){ return mainController.getNXDTabController(); } - public PatchesController getPatchesController(){ return mainController.getPatchesTabController(); } - - public ResourceBundle getResourceBundle(){ - return mainController.getResourceBundle(); - } - - public synchronized void setBgThreadActive(boolean isActive, EModule appModuleType) { - isTransferActive.set(isActive); - getGamesController().notifyThreadStarted(isActive, appModuleType); - getSplitMergeController().notifyThreadStarted(isActive, appModuleType); - getRcmController().notifyThreadStarted(isActive, appModuleType); - getNxdtController().notifyThreadStarted(isActive, appModuleType); - getPatchesController().notifyThreadStarted(isActive, appModuleType); - } - public synchronized boolean getTransferActive() { return this.isTransferActive.get(); } - public void updateApplicationFont(String fontFamily, double fontSize){ - mainController.logArea.getScene().getRoot().setStyle( - String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize)); + public synchronized boolean getTransferActive() { + return transfersPublisher.getTransferActive(); } } diff --git a/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java b/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java index d557964..606771d 100644 --- a/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java +++ b/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -40,9 +40,13 @@ public class LogPrinterGui implements ILogPrinter { LogPrinterGui(EModule whoIsAsking){ this.msgQueue = new LinkedBlockingQueue<>(); this.progressQueue = new LinkedBlockingQueue<>(); - this.statusMap = new HashMap<>(); + this.statusMap = new HashMap<>(); this.oneLinerStatus = new AtomicBoolean(); - this.msgConsumer = new MessagesConsumer(whoIsAsking, this.msgQueue, this.progressQueue, this.statusMap, this.oneLinerStatus); + this.msgConsumer = new MessagesConsumer(whoIsAsking, + this.msgQueue, + this.progressQueue, + this.statusMap, + this.oneLinerStatus); this.msgConsumer.start(); } /** diff --git a/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java b/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java index 08add56..491d5ad 100644 --- a/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java +++ b/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -22,24 +22,26 @@ import javafx.animation.AnimationTimer; import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.TextArea; -import nsusbloader.Controllers.NSTableViewController; +import nsusbloader.Controllers.Payload; import nsusbloader.MediatorControl; import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EModule; import java.util.ArrayList; import java.util.HashMap; +import java.util.ResourceBundle; import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; public class MessagesConsumer extends AnimationTimer { - private final BlockingQueue msgQueue; - private final TextArea logsArea; + private static final MediatorControl mediator = MediatorControl.INSTANCE; + private static final TextArea logsArea = mediator.getLogArea(); + private static final ProgressBar progressBar = mediator.getProgressBar();; + private static final ResourceBundle resourceBundle = mediator.getResourceBundle(); + private final BlockingQueue msgQueue; private final BlockingQueue progressQueue; - private final ProgressBar progressBar; private final HashMap statusMap; - private final NSTableViewController tableViewController; private final EModule appModuleType; private final AtomicBoolean oneLinerStatus; @@ -53,22 +55,16 @@ public class MessagesConsumer extends AnimationTimer { AtomicBoolean oneLinerStatus){ this.appModuleType = appModuleType; this.isInterrupted = false; - this.msgQueue = msgQueue; - this.logsArea = MediatorControl.getInstance().getContoller().logArea; - this.progressQueue = progressQueue; - this.progressBar = MediatorControl.getInstance().getContoller().progressBar; - this.statusMap = statusMap; - this.tableViewController = MediatorControl.getInstance().getGamesController().tableFilesListController; - this.oneLinerStatus = oneLinerStatus; progressBar.setProgress(0.0); - progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS); - MediatorControl.getInstance().setBgThreadActive(true, appModuleType); + + logsArea.clear(); + mediator.setTransferActive(appModuleType, true, new Payload()); } @Override @@ -89,32 +85,18 @@ public class MessagesConsumer extends AnimationTimer { }); } - if (isInterrupted) // It's safe 'cuz it's could't be interrupted while HashMap populating + if (isInterrupted) // safe, could not be interrupted while HashMap populating updateElementsAndStop(); } private void updateElementsAndStop(){ - MediatorControl.getInstance().setBgThreadActive(false, appModuleType); + Payload payload = new Payload( + resourceBundle.getString(oneLinerStatus.get() ? "done_txt" : "failure_txt"), + statusMap); + + mediator.setTransferActive(appModuleType, false, payload); progressBar.setProgress(0.0); - if (statusMap.size() > 0){ - for (String key : statusMap.keySet()) - tableViewController.setFileStatus(key, statusMap.get(key)); - } - - switch (appModuleType){ - case RCM: - MediatorControl.getInstance().getRcmController().setOneLineStatus(oneLinerStatus.get()); - break; - case NXDT: - MediatorControl.getInstance().getNxdtController().setOneLineStatus(oneLinerStatus.get()); - break; - case SPLIT_MERGE_TOOL: - MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get()); - break; - case PATCHES: - MediatorControl.getInstance().getPatchesController().setOneLineStatus(oneLinerStatus.get()); - } this.stop(); } diff --git a/src/main/java/nsusbloader/NSLMain.java b/src/main/java/nsusbloader/NSLMain.java index fa40c9a..ce98308 100644 --- a/src/main/java/nsusbloader/NSLMain.java +++ b/src/main/java/nsusbloader/NSLMain.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -68,14 +68,15 @@ public class NSLMain extends Application { primaryStage.show(); primaryStage.setOnCloseRequest(e->{ - if (MediatorControl.getInstance().getTransferActive()) + if (MediatorControl.INSTANCE.getTransferActive()) if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"), rb.getString("windowBodyConfirmExit"))) e.consume(); }); NSLMainController controller = loader.getController(); - controller.setHostServices(getHostServices()); + MediatorControl.INSTANCE.setHostServices(getHostServices()); + primaryStage.setOnHidden(e-> { AppPreferences.getInstance().setSceneHeight(mainScene.getHeight()); AppPreferences.getInstance().setSceneWidth(mainScene.getWidth()); diff --git a/src/main/java/nsusbloader/TransfersPublisher.java b/src/main/java/nsusbloader/TransfersPublisher.java new file mode 100644 index 0000000..246cbb8 --- /dev/null +++ b/src/main/java/nsusbloader/TransfersPublisher.java @@ -0,0 +1,47 @@ +/* + Copyright 2019-2024 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader; + +import nsusbloader.Controllers.ISubscriber; +import nsusbloader.Controllers.Payload; +import nsusbloader.NSLDataTypes.EModule; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TransfersPublisher { + private final AtomicBoolean isTransferActive = new AtomicBoolean(false); + + private final List subscribers = new ArrayList<>(); + + public TransfersPublisher(ISubscriber... subscriber){ + subscribers.addAll(Arrays.asList(subscriber)); + } + + public void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) { + isTransferActive.set(isActive); + subscribers.forEach(s->s.notify(appModuleType, isActive, payload)); + } + + public boolean getTransferActive() { + return isTransferActive.get(); + } +} diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_010.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_010.java index a5669d2..3f420a0 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_010.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_010.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2022 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -933,7 +933,7 @@ class GoldLeaf_010 extends TransferModule { private boolean selectFile(){ File selectedFile = CompletableFuture.supplyAsync(() -> { FileChooser fChooser = new FileChooser(); - fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION + fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a priority. fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); return fChooser.showOpenDialog(null); // Leave as is for now. diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java index 38adb7e..640032b 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -918,7 +918,7 @@ class GoldLeaf_07 extends TransferModule { private boolean selectFile(){ File selectedFile = CompletableFuture.supplyAsync(() -> { FileChooser fChooser = new FileChooser(); - fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION + fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio. fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); return fChooser.showOpenDialog(null); // Leave as is for now. diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java index f8bf657..c367fd8 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java @@ -1,5 +1,5 @@ /* - Copyright 2019-2020 Dmitry Isaenko + Copyright 2019-2024 Dmitry Isaenko This file is part of NS-USBloader. @@ -941,7 +941,7 @@ class GoldLeaf_08 extends TransferModule { private boolean selectFile(){ File selectedFile = CompletableFuture.supplyAsync(() -> { FileChooser fChooser = new FileChooser(); - fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION + fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a prio. fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); return fChooser.showOpenDialog(null); // Leave as is for now. diff --git a/src/test/java/integration/EsIntegrationTest.java b/src/test/java/integration/EsIntegrationTest.java index c8ec24e..8fb868c 100644 --- a/src/test/java/integration/EsIntegrationTest.java +++ b/src/test/java/integration/EsIntegrationTest.java @@ -22,7 +22,7 @@ public class EsIntegrationTest { pathToKeysFile = environment.getProdkeysLocation(); saveTo = environment.getSaveToLocation() + File.separator + "ES_LPR"; pathToFirmwares = environment.getFirmwaresLocation(); - pathToFirmware = pathToFirmware + File.separator + "Firmware 14.1.0"; + pathToFirmware = environment.getFirmwaresLocation() + File.separator + "Firmware 17.0.0"; } @DisplayName("ES Integration validation - everything") diff --git a/src/test/java/integration/FsIntegrationTest.java b/src/test/java/integration/FsIntegrationTest.java index 5a85acc..f56544c 100644 --- a/src/test/java/integration/FsIntegrationTest.java +++ b/src/test/java/integration/FsIntegrationTest.java @@ -25,7 +25,7 @@ public class FsIntegrationTest { pathToKeysFile = environment.getProdkeysLocation(); saveTo = environment.getSaveToLocation() + File.separator + "FS_LPR"; pathToFirmwares = environment.getFirmwaresLocation(); - pathToFirmware = pathToFirmware + File.separator + "Firmware 13.0.0"; + pathToFirmware = environment.getFirmwaresLocation() + File.separator + "Firmware 17.0.0"; } @DisplayName("FS Integration validation - everything")