RareCore: Replace individual fetch workers with a single one.
The workers where co-dependent anyways as the non-asset worker was started after the games worker had sent back its results. By combining them we can move any data manipulations to the worker and simplify the handling in RareCore.
This commit is contained in:
parent
497bdc08cc
commit
5307932656
|
@ -4,7 +4,7 @@ import time
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable
|
from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable, Tuple
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal, QSettings, pyqtSlot, QThreadPool, QRunnable, QTimer
|
from PyQt5.QtCore import QObject, pyqtSignal, QSettings, pyqtSlot, QThreadPool, QRunnable, QTimer
|
||||||
from legendary.lfs.eos import EOSOverlayApp
|
from legendary.lfs.eos import EOSOverlayApp
|
||||||
|
@ -21,8 +21,6 @@ from .workers import (
|
||||||
VerifyWorker,
|
VerifyWorker,
|
||||||
MoveWorker,
|
MoveWorker,
|
||||||
FetchWorker,
|
FetchWorker,
|
||||||
GamesWorker,
|
|
||||||
NonAssetWorker,
|
|
||||||
OriginWineWorker,
|
OriginWineWorker,
|
||||||
)
|
)
|
||||||
from .workers.uninstall import uninstall_game
|
from .workers.uninstall import uninstall_game
|
||||||
|
@ -52,11 +50,6 @@ class RareCore(QObject):
|
||||||
self.__image_manager: Optional[ImageManager] = None
|
self.__image_manager: Optional[ImageManager] = None
|
||||||
|
|
||||||
self.__start_time = time.time()
|
self.__start_time = time.time()
|
||||||
self.__fetched_games: List = []
|
|
||||||
self.__fetched_dlcs: Dict = {}
|
|
||||||
|
|
||||||
self.__games_fetched: bool = False
|
|
||||||
self.__non_asset_fetched: bool = False
|
|
||||||
|
|
||||||
self.args(args)
|
self.args(args)
|
||||||
self.signals(init=True)
|
self.signals(init=True)
|
||||||
|
@ -270,54 +263,21 @@ class RareCore(QObject):
|
||||||
self.progress.emit(int(idx/length * 80) + 20, self.tr("Loaded <b>{}</b>").format(rgame.app_title))
|
self.progress.emit(int(idx/length * 80) + 20, self.tr("Loaded <b>{}</b>").format(rgame.app_title))
|
||||||
|
|
||||||
@pyqtSlot(object, int)
|
@pyqtSlot(object, int)
|
||||||
def handle_result(self, result: object, res_type: int):
|
def __on_fetch_result(self, result: Tuple[List, Dict], res_type: int):
|
||||||
status = ""
|
|
||||||
if res_type == FetchWorker.Result.GAMES:
|
|
||||||
games, dlc_dict = result
|
|
||||||
self.__fetched_games += games
|
|
||||||
self.__fetched_dlcs.update(dlc_dict)
|
|
||||||
self.fetch_non_asset()
|
|
||||||
self.__games_fetched = True
|
|
||||||
status = self.tr("Prepared games")
|
|
||||||
if res_type == FetchWorker.Result.NON_ASSET:
|
|
||||||
games, dlc_dict = result
|
|
||||||
self.__fetched_games += games
|
|
||||||
for catalog_id, dlcs in dlc_dict.items():
|
|
||||||
if catalog_id in self.__fetched_dlcs.keys():
|
|
||||||
self.__fetched_dlcs[catalog_id] += dlcs
|
|
||||||
else:
|
|
||||||
self.__fetched_dlcs[catalog_id] = dlcs
|
|
||||||
self.__non_asset_fetched = True
|
|
||||||
status = self.tr("Prepared games without assets")
|
|
||||||
logger.info(f"Got API results for {FetchWorker.Result(res_type).name}")
|
logger.info(f"Got API results for {FetchWorker.Result(res_type).name}")
|
||||||
|
self.progress.emit(15, self.tr("Preparing library"))
|
||||||
fetched = [
|
self.__add_games_and_dlcs(*result)
|
||||||
self.__games_fetched,
|
self.progress.emit(100, self.tr("Launching Rare"))
|
||||||
self.__non_asset_fetched,
|
logger.debug(f"Fetch time {time.time() - self.__start_time} seconds")
|
||||||
]
|
QTimer.singleShot(100, self.__post_init)
|
||||||
|
self.completed.emit()
|
||||||
self.progress.emit(sum(fetched) * 10, status)
|
|
||||||
|
|
||||||
if all(fetched):
|
|
||||||
self.__add_games_and_dlcs(self.__fetched_games, self.__fetched_dlcs)
|
|
||||||
self.progress.emit(100, self.tr("Launching Rare"))
|
|
||||||
logger.debug(f"Fetch time {time.time() - self.__start_time} seconds")
|
|
||||||
QTimer.singleShot(100, self.__post_init)
|
|
||||||
self.completed.emit()
|
|
||||||
|
|
||||||
def fetch(self):
|
def fetch(self):
|
||||||
self.__games_fetched: bool = False
|
|
||||||
self.__non_asset_fetched: bool = False
|
|
||||||
self.__start_time = time.time()
|
self.__start_time = time.time()
|
||||||
|
fetch_worker = FetchWorker(self.__core, self.__args)
|
||||||
games_worker = GamesWorker(self.__core, self.__args)
|
fetch_worker.signals.progress.connect(self.progress)
|
||||||
games_worker.signals.result.connect(self.handle_result)
|
fetch_worker.signals.result.connect(self.__on_fetch_result)
|
||||||
QThreadPool.globalInstance().start(games_worker)
|
QThreadPool.globalInstance().start(fetch_worker)
|
||||||
|
|
||||||
def fetch_non_asset(self):
|
|
||||||
non_asset_worker = NonAssetWorker(self.__core, self.__args)
|
|
||||||
non_asset_worker.signals.result.connect(self.handle_result)
|
|
||||||
QThreadPool.globalInstance().start(non_asset_worker)
|
|
||||||
|
|
||||||
def fetch_saves(self):
|
def fetch_saves(self):
|
||||||
def __fetch() -> None:
|
def __fetch() -> None:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .fetch import FetchWorker, GamesWorker, NonAssetWorker
|
from .fetch import FetchWorker
|
||||||
from .install_info import InstallInfoWorker
|
from .install_info import InstallInfoWorker
|
||||||
from .move import MoveWorker
|
from .move import MoveWorker
|
||||||
from .uninstall import UninstallWorker
|
from .uninstall import UninstallWorker
|
||||||
|
|
|
@ -16,8 +16,10 @@ class FetchWorker(Worker):
|
||||||
class Result(IntEnum):
|
class Result(IntEnum):
|
||||||
GAMES = 1
|
GAMES = 1
|
||||||
NON_ASSET = 2
|
NON_ASSET = 2
|
||||||
|
COMBINED = 3
|
||||||
|
|
||||||
class Signals(QObject):
|
class Signals(QObject):
|
||||||
|
progress = pyqtSignal(int, str)
|
||||||
result = pyqtSignal(object, int)
|
result = pyqtSignal(object, int)
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, args: Namespace):
|
def __init__(self, core: LegendaryCore, args: Namespace):
|
||||||
|
@ -26,33 +28,43 @@ class FetchWorker(Worker):
|
||||||
self.core = core
|
self.core = core
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
|
|
||||||
class GamesWorker(FetchWorker):
|
|
||||||
def run_real(self):
|
def run_real(self):
|
||||||
|
# Fetch regular EGL games with assets
|
||||||
|
self.signals.progress.emit(0, self.signals.tr("Updating game metadata"))
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
result = self.core.get_game_and_dlc_list(update_assets=not self.args.offline, platform="Windows", skip_ue=False)
|
games, dlc_dict = self.core.get_game_and_dlc_list(
|
||||||
self.signals.result.emit(result, FetchWorker.Result.GAMES)
|
update_assets=not self.args.offline, platform="Windows", skip_ue=False
|
||||||
logger.debug(f"Games: {len(result[0])}, DLCs {len(result[1])}")
|
)
|
||||||
logger.debug(f"Request Games: {time.time() - start_time} seconds")
|
logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}")
|
||||||
|
logger.debug(f"Request games: {time.time() - start_time} seconds")
|
||||||
|
|
||||||
|
# Fetch non-asset games
|
||||||
class NonAssetWorker(FetchWorker):
|
self.signals.progress.emit(10, self.signals.tr("Updating non-asset metadata"))
|
||||||
def run_real(self):
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
try:
|
try:
|
||||||
result = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)
|
na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)
|
||||||
except (HTTPError, ConnectionError) as e:
|
except (HTTPError, ConnectionError) as e:
|
||||||
logger.warning(f"Exception while fetching non asset games from EGS: {e}")
|
logger.warning(f"Exception while fetching non asset games from EGS: {e}")
|
||||||
result = ([], {})
|
na_games, na_dlc_dict = ([], {})
|
||||||
# FIXME:
|
# FIXME:
|
||||||
# This is here because of broken appIds from Epic:
|
# This is here because of broken appIds from Epic:
|
||||||
# https://discord.com/channels/826881530310819914/884510635642216499/1111321692703305729
|
# https://discord.com/channels/826881530310819914/884510635642216499/1111321692703305729
|
||||||
# There is a tab character in the appId of Fallout New Vegas: Honest Hearts DLC, this breaks metadata storage
|
# There is a tab character in the appId of Fallout New Vegas: Honest Hearts DLC, this breaks metadata storage
|
||||||
# on Windows as they can't handle tabs at the end of the filename (?)
|
# on Windows as they can't handle tabs at the end of the filename (?)
|
||||||
# Legendary and Heroic are also affected, but it completed breaks Rare, so dodge it for now pending a fix.
|
# Legendary and Heroic are also affected, but it completely breaks Rare, so dodge it for now pending a fix.
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Exception while fetching non asset games from EGS: {e}")
|
logger.error(f"Exception while fetching non asset games from EGS: {e}")
|
||||||
result = ([], {})
|
na_games, na_dlc_dict = ([], {})
|
||||||
self.signals.result.emit(result, FetchWorker.Result.NON_ASSET)
|
logger.debug(f"Non-asset {len(na_games)}, games with non-asset DLCs {len(na_dlc_dict)}")
|
||||||
logger.debug(f"Non asset: {len(result[0])}, DLCs {len(result[1])}")
|
logger.debug(f"Request non-asset: {time.time() - start_time} seconds")
|
||||||
logger.debug(f"Request Non Asset: {time.time() - start_time} seconds")
|
|
||||||
|
# Combine the two games lists and the two dlc dictionaries between regular and non-asset results
|
||||||
|
games += na_games
|
||||||
|
for catalog_id, dlcs in na_dlc_dict.items():
|
||||||
|
if catalog_id in dlc_dict.keys():
|
||||||
|
dlc_dict[catalog_id] += dlcs
|
||||||
|
else:
|
||||||
|
dlc_dict[catalog_id] = dlcs
|
||||||
|
logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}")
|
||||||
|
|
||||||
|
self.signals.result.emit((games, dlc_dict), FetchWorker.Result.COMBINED)
|
||||||
|
|
Loading…
Reference in a new issue