diff --git a/app/gui.py b/app/gui.py index 7e5c249..8b8e095 100644 --- a/app/gui.py +++ b/app/gui.py @@ -3616,6 +3616,33 @@ class SaveSyncPlanWorker(QObject): self.finished.emit() +class SaveScanWorker(QObject): + """Scan the three SAVEDATA locations off the GUI thread.""" + result = Signal(int, dict) # gen, {location: {save_id: meta}} + finished = Signal() + + def __init__(self, gen, locations): + super().__init__() + self.gen = gen + self.locations = locations + self._cancel = threading.Event() + + def cancel(self): + self._cancel.set() + + def run(self): + data = {} + for name, root in self.locations.items(): + if self._cancel.is_set(): + break + try: + data[name] = {s["id"]: s for s in saves.list_saves(root)} + except Exception: # noqa: BLE001 + data[name] = {} + self.result.emit(self.gen, data) + self.finished.emit() + + class SavesPage(QWidget): """PSP save-data sync between PSP, PPSSPP, and a cloud folder.""" @@ -3628,6 +3655,8 @@ class SavesPage(QWidget): self._cloud_dir = "" self._syncing = False self._closing = False + self._gen = 0 + self._scan_worker = None self._threads = [] self._workers = [] @@ -3783,9 +3812,32 @@ class SavesPage(QWidget): QMessageBox.information(self, "Export save", f"Exported to:\n{Path(dest) / sid}") def refresh(self): - locs = self._locations() - data = {name: {s["id"]: s for s in saves.list_saves(root)} for name, root in locs.items()} + if self._closing: + return + self._gen += 1 + gen = self._gen + if self._scan_worker is not None: + self._scan_worker.cancel() + self.status.setText("Reading saves…") + thread = QThread(self) + worker = SaveScanWorker(gen, self._locations()) + worker.moveToThread(thread) + thread.started.connect(worker.run) + worker.result.connect(self._on_saves_scanned) + worker.finished.connect(thread.quit) + self._scan_worker = worker + self._threads.append(thread) + self._workers.append(worker) + thread.start() + + def _on_saves_scanned(self, gen, data): + if gen != self._gen or self._closing: + return + self._scan_worker = None self._data = data + self._populate(data) + + def _populate(self, data): all_ids = set() for d in data.values(): all_ids.update(d) @@ -3835,7 +3887,7 @@ class SavesPage(QWidget): self._populating = False self.table.setSortingEnabled(True) self.table.sortByColumn(sort_col, sort_order) - self.status.setText(f"{len(all_ids)} save(s) across {sum(1 for r in locs.values() if r)} location(s)") + self.status.setText(f"{len(all_ids)} save(s) across {sum(1 for r in self._locations().values() if r)} location(s)") self._update_delete_enabled() def sync_now(self, switch_tab=False):