From 4e1248a18a8ae064b9b624f370ebbd0b4b80f36e Mon Sep 17 00:00:00 2001 From: loathingKernel <142770+loathingKernel@users.noreply.github.com> Date: Sun, 12 Mar 2023 01:09:51 +0200 Subject: [PATCH] RareCore: Move OriginWineWorker execution in `load_pixamps()` We don't need to know if Origin is installed before launching the window, so we can save on startup time by executing the worker after the window has become visible. --- rare/models/game.py | 1 + rare/shared/image_manager.py | 2 +- rare/shared/rare_core.py | 28 ++++++++-------------------- rare/shared/workers/fetch.py | 1 - rare/shared/workers/wine_resolver.py | 24 ++++++++++-------------- rare/shared/workers/worker.py | 8 ++++++-- 6 files changed, 26 insertions(+), 38 deletions(-) diff --git a/rare/models/game.py b/rare/models/game.py index a3cd8978..9ecba0ea 100644 --- a/rare/models/game.py +++ b/rare/models/game.py @@ -483,6 +483,7 @@ class RareGame(RareGameSlim): self.signals.game.installed.emit(self.app_name) else: self.signals.game.uninstalled.emit(self.app_name) + self.set_pixmap() def repair(self, repair_and_update): self.signals.game.install.emit( diff --git a/rare/shared/image_manager.py b/rare/shared/image_manager.py index 37e6bb64..a82a8dbc 100644 --- a/rare/shared/image_manager.py +++ b/rare/shared/image_manager.py @@ -214,7 +214,7 @@ class ImageManager(QObject): ): updates = [image for image in game.metadata["keyImages"] if image["type"] in self.__img_types] else: - updates = list() + updates = [] for image in game.metadata["keyImages"]: if image["type"] in self.__img_types: if image["type"] not in json_data.keys() or json_data[image["type"]] != image["md5"]: diff --git a/rare/shared/rare_core.py b/rare/shared/rare_core.py index a717d7c5..eb15da1a 100644 --- a/rare/shared/rare_core.py +++ b/rare/shared/rare_core.py @@ -50,7 +50,6 @@ class RareCore(QObject): self.__games_fetched: bool = False self.__non_asset_fetched: bool = False - self.__origin_resolved: bool = False self.__saves_fetched: bool = False self.__entitlements_fetched: bool = False @@ -279,15 +278,8 @@ class RareCore(QObject): games, dlc_dict = result self.__add_games_and_dlcs(games, dlc_dict) self.fetch_saves() - self.resolve_origin() self.__non_asset_fetched = True status = "Loaded games without assets" - if res_type == FetchWorker.Result.ORIGIN: - attrs, _ = result - for app_name, (install_dir, install_size) in attrs.items(): - self.__games[app_name].set_origin_attributes(install_dir, install_size) - self.__origin_resolved = True - status = "Resolved Origin installation status" if res_type == FetchWorker.Result.SAVES: saves, _ = result for app_name, saves in saves.items(): @@ -303,12 +295,11 @@ class RareCore(QObject): fetched = [ self.__games_fetched, self.__non_asset_fetched, - self.__origin_resolved, self.__saves_fetched, self.__entitlements_fetched, ] - self.progress.emit(sum(fetched) * 10, status) + self.progress.emit(sum(fetched) * 20, status) if all(fetched): self.progress.emit(75, self.tr("Validating game installations")) @@ -320,7 +311,6 @@ class RareCore(QObject): def fetch(self): self.__games_fetched: bool = False self.__non_asset_fetched: bool = False - self.__origin_resolved: bool = False self.__saves_fetched: bool = False self.__entitlements_fetched: bool = False @@ -338,11 +328,6 @@ class RareCore(QObject): else: self.__saves_fetched = True - def resolve_origin(self): - origin_worker = OriginWineWorker(self.__core, self.__args, self.origin_games) - origin_worker.signals.result.connect(self.handle_result) - QThreadPool.globalInstance().start(origin_worker) - def fetch_extra(self): non_asset_worker = NonAssetWorker(self.__core, self.__args) non_asset_worker.signals.result.connect(self.handle_result) @@ -369,16 +354,19 @@ class RareCore(QObject): @return: None """ + origin_worker = OriginWineWorker(self.__core, list(self.origin_games)) + QThreadPool.globalInstance().start(origin_worker) + def __load_pixmaps() -> None: # time.sleep(0.1) for rgame in self.__games.values(): # self.__image_manager.download_image(rgame.game, rgame.set_pixmap, 0, False) rgame.load_pixmap() - # lk: perception delay - time.sleep(0.001) + # lk: activity perception delay + time.sleep(0.0003) - worker = QRunnable.create(__load_pixmaps) - QThreadPool.globalInstance().start(worker) + pixmap_worker = QRunnable.create(__load_pixmaps) + QThreadPool.globalInstance().start(pixmap_worker) @property def games_and_dlcs(self) -> Iterator[RareGame]: diff --git a/rare/shared/workers/fetch.py b/rare/shared/workers/fetch.py index f842e5e7..8d4e49cd 100644 --- a/rare/shared/workers/fetch.py +++ b/rare/shared/workers/fetch.py @@ -18,7 +18,6 @@ class FetchWorker(Worker): class Result(IntEnum): GAMES = 1 NON_ASSET = 2 - ORIGIN = 3 SAVES = 5 ENTITLEMENTS = 6 diff --git a/rare/shared/workers/wine_resolver.py b/rare/shared/workers/wine_resolver.py index 535e1273..b0bce42d 100644 --- a/rare/shared/workers/wine_resolver.py +++ b/rare/shared/workers/wine_resolver.py @@ -1,19 +1,17 @@ import os import platform import time -from argparse import Namespace from configparser import ConfigParser from logging import getLogger -from typing import Union, Iterator, Dict, Tuple +from typing import Union, Iterator -from PyQt5.QtCore import pyqtSignal, QObject +from PyQt5.QtCore import pyqtSignal, QObject, QRunnable import rare.utils.wine as wine from rare.lgndr.core import LegendaryCore from rare.models.game import RareGame from rare.models.pathspec import PathSpec from rare.utils.misc import path_size, format_size -from .fetch import FetchWorker from .worker import Worker if platform.system() == "Windows": @@ -52,21 +50,19 @@ class WineResolver(Worker): return -class OriginWineWorker(FetchWorker): - def __init__(self, core: LegendaryCore, args: Namespace, games: Union[Iterator[RareGame], RareGame]): - super(OriginWineWorker, self).__init__(core, args) +class OriginWineWorker(QRunnable): + def __init__(self, core: LegendaryCore, games: Union[Iterator[RareGame], RareGame]): + super(OriginWineWorker, self).__init__() self.__cache: dict[str, ConfigParser] = {} + self.core = core if isinstance(games, RareGame): games = [games] self.games = games - def run_real(self) -> None: + def run(self) -> None: t = time.time() - result: Dict[str, Tuple[str, int]] = {} for rgame in self.games: - if not rgame.is_origin: - continue reg_path: str = rgame.game.metadata \ .get("customAttributes", {}) \ @@ -77,6 +73,8 @@ class OriginWineWorker(FetchWorker): reg_key: str = rgame.game.metadata \ .get("customAttributes", {}) \ .get("RegistryKey", {}).get("value", None) + if not reg_key: + continue if platform.system() == "Windows": install_dir = windows_helpers.query_registry_value(winreg.HKEY_LOCAL_MACHINE, reg_path, reg_key) @@ -104,10 +102,8 @@ class OriginWineWorker(FetchWorker): if install_dir: if os.path.isdir(install_dir): install_size = path_size(install_dir) - result.update({rgame.app_name: (install_dir, install_size)}) + rgame.set_origin_attributes(install_dir, install_size) logger.debug(f"Found Origin game {rgame.title} ({install_dir}, {format_size(install_size)})") else: logger.warning(f"Found Origin game {rgame.title} ({install_dir} does not exist)") - - self.signals.result.emit((result, None), FetchWorker.Result.ORIGIN) logger.info(f"Origin registry worker finished in {time.time() - t}s") diff --git a/rare/shared/workers/worker.py b/rare/shared/workers/worker.py index 40335a14..86d35f4c 100644 --- a/rare/shared/workers/worker.py +++ b/rare/shared/workers/worker.py @@ -25,7 +25,7 @@ class Worker(QRunnable): @property def signals(self) -> QObject: if self.__signals is None: - raise NotImplementedError + raise RuntimeError(f"Subclasses must implement '{type(self).__name__}.signals' QObject attribute") return self.__signals @signals.setter @@ -39,7 +39,7 @@ class Worker(QRunnable): @pyqtSlot() def run(self): self.run_real() - self.__signals.deleteLater() + self.signals.deleteLater() class QueueWorkerState(IntEnum): @@ -76,6 +76,7 @@ class QueueWorker(Worker): super(QueueWorker, self).__init__() self.feedback = QueueWorker.Signals() self.state = QueueWorkerState.QUEUED + self._kill = False @pyqtSlot() def run(self): @@ -89,4 +90,7 @@ class QueueWorker(Worker): def worker_info(self) -> QueueWorkerInfo: pass + def kill(self): + raise NotImplementedError + self._kill = True