Refine QueueWorker and implement worker_info
for VerifyWorker
and MoveWorker
This commit is contained in:
parent
38710a0af1
commit
6b3a841378
|
@ -61,10 +61,6 @@ class GameInfo(QWidget):
|
|||
if platform.system() == "Windows":
|
||||
self.ui.lbl_grade.setVisible(False)
|
||||
self.ui.grade.setVisible(False)
|
||||
else:
|
||||
self.steam_worker: SteamWorker = SteamWorker(self.core)
|
||||
self.steam_worker.signals.rating.connect(self.ui.grade.setText)
|
||||
self.steam_worker.setAutoDelete(False)
|
||||
|
||||
self.ui.game_actions_stack.setCurrentWidget(self.ui.installed_page)
|
||||
|
||||
|
@ -151,18 +147,18 @@ class GameInfo(QWidget):
|
|||
self.verify_game(self.rgame)
|
||||
|
||||
def verify_game(self, rgame: RareGame):
|
||||
worker = VerifyWorker(self.core, self.args, rgame)
|
||||
worker.signals.progress.connect(self.__on_verify_progress)
|
||||
worker.signals.result.connect(self.__on_verify_result)
|
||||
worker.signals.error.connect(self.__on_verify_error)
|
||||
self.ui.verify_stack.setCurrentWidget(self.ui.verify_progress_page)
|
||||
verify_worker = VerifyWorker(self.core, self.args, rgame)
|
||||
verify_worker.signals.progress.connect(self.__on_verify_progress)
|
||||
verify_worker.signals.result.connect(self.__on_verify_result)
|
||||
verify_worker.signals.error.connect(self.__on_verify_error)
|
||||
self.ui.verify_progress.setValue(0)
|
||||
self.rgame.__worker = verify_worker
|
||||
self.verify_pool.start(verify_worker)
|
||||
self.ui.move_button.setEnabled(False)
|
||||
self.rcore.enqueue_worker(rgame, worker)
|
||||
|
||||
def verify_cleanup(self, rgame: RareGame):
|
||||
rgame.__worker = None
|
||||
if rgame is not self.rgame:
|
||||
return
|
||||
self.ui.verify_stack.setCurrentWidget(self.ui.verify_button_page)
|
||||
self.ui.move_button.setEnabled(True)
|
||||
self.ui.verify_button.setEnabled(True)
|
||||
|
@ -257,7 +253,7 @@ class GameInfo(QWidget):
|
|||
self.ui.move_progress.setValue(progress_int)
|
||||
|
||||
def start_copy_diff_drive(self):
|
||||
copy_worker = MoveWorker(
|
||||
worker = MoveWorker(
|
||||
self.core,
|
||||
install_path=self.rgame.igame.install_path,
|
||||
dest_path=self.dest_path_with_suffix,
|
||||
|
@ -265,10 +261,10 @@ class GameInfo(QWidget):
|
|||
igame=self.rgame.igame,
|
||||
)
|
||||
|
||||
copy_worker.signals.progress.connect(self.__on_move_progress)
|
||||
copy_worker.signals.result.connect(self.set_new_game)
|
||||
copy_worker.signals.error.connect(self.warn_no_space_left)
|
||||
QThreadPool.globalInstance().start(copy_worker)
|
||||
worker.signals.progress.connect(self.__on_move_progress)
|
||||
worker.signals.result.connect(self.set_new_game)
|
||||
worker.signals.error.connect(self.warn_no_space_left)
|
||||
self.rcore.enqueue_worker(self.rgame, worker)
|
||||
|
||||
def move_helper_clean_up(self):
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_button_page)
|
||||
|
@ -310,67 +306,69 @@ class GameInfo(QWidget):
|
|||
rgame = self.rcore.get_game(rgame)
|
||||
|
||||
if self.rgame is not None:
|
||||
if (worker := self.rgame.worker) is not None:
|
||||
if (worker := self.rgame.worker()) is not None:
|
||||
if isinstance(worker, VerifyWorker):
|
||||
try:
|
||||
worker.signals.progress.disconnect(self.__on_verify_progress)
|
||||
self.ui.verify_stack.setCurrentWidget(self.ui.verify_button_page)
|
||||
except TypeError as e:
|
||||
logger.warning(f"{self.rgame.app_name} verify worker: {e}")
|
||||
if isinstance(worker, MoveWorker):
|
||||
try:
|
||||
worker.signals.progress.disconnect(self.__on_move_progress)
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_button_page)
|
||||
except TypeError as e:
|
||||
logger.warning(f"{self.rgame.app_name} move worker: {e}")
|
||||
self.rgame.signals.widget.update.disconnect(self.__update_ui)
|
||||
self.rgame.signals.game.installed.disconnect(self.update_game)
|
||||
self.rgame.signals.game.uninstalled.disconnect(self.update_game)
|
||||
|
||||
self.rgame = rgame
|
||||
self.rgame = None
|
||||
|
||||
self.rgame.signals.widget.update.disconnect(self.__update_ui)
|
||||
self.rgame.signals.game.installed.connect(self.update_game)
|
||||
self.rgame.signals.game.uninstalled.connect(self.update_game)
|
||||
if (worker := self.rgame.worker) is not None:
|
||||
rgame.signals.widget.update.connect(self.__update_ui)
|
||||
rgame.signals.game.installed.connect(self.update_game)
|
||||
rgame.signals.game.uninstalled.connect(self.update_game)
|
||||
if (worker := rgame.worker()) is not None:
|
||||
if isinstance(worker, VerifyWorker):
|
||||
self.ui.verify_stack.setCurrentWidget(self.ui.verify_progress_page)
|
||||
self.ui.verify_progress.setValue(self.rgame.progress)
|
||||
self.ui.verify_progress.setValue(rgame.progress)
|
||||
worker.signals.progress.connect(self.__on_verify_progress)
|
||||
else:
|
||||
self.ui.verify_stack.setCurrentWidget(self.ui.verify_button_page)
|
||||
if isinstance(worker, MoveWorker):
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_progress_page)
|
||||
self.ui.move_progress.setValue(self.rgame.progress)
|
||||
self.ui.move_progress.setValue(rgame.progress)
|
||||
worker.signals.progress.connect(self.__on_move_progress)
|
||||
else:
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_button_page)
|
||||
|
||||
self.title.setTitle(self.rgame.app_title)
|
||||
self.title.setTitle(rgame.app_title)
|
||||
self.image.setPixmap(rgame.pixmap)
|
||||
self.ui.app_name.setText(self.rgame.app_name)
|
||||
self.ui.version.setText(self.rgame.version)
|
||||
self.ui.dev.setText(self.rgame.developer)
|
||||
self.ui.app_name.setText(rgame.app_name)
|
||||
self.ui.version.setText(rgame.version)
|
||||
self.ui.dev.setText(rgame.developer)
|
||||
|
||||
if self.rgame.igame:
|
||||
self.ui.install_size.setText(get_size(self.rgame.igame.install_size))
|
||||
self.ui.install_path.setText(self.rgame.igame.install_path)
|
||||
self.ui.platform.setText(self.rgame.igame.platform)
|
||||
if rgame.igame:
|
||||
self.ui.install_size.setText(get_size(rgame.igame.install_size))
|
||||
self.ui.install_path.setText(rgame.igame.install_path)
|
||||
self.ui.platform.setText(rgame.igame.platform)
|
||||
else:
|
||||
self.ui.install_size.setText("N/A")
|
||||
self.ui.install_path.setText("N/A")
|
||||
self.ui.platform.setText("Windows")
|
||||
|
||||
self.ui.install_size.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.lbl_install_size.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.install_path.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.lbl_install_path.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.install_size.setEnabled(bool(rgame.igame))
|
||||
self.ui.lbl_install_size.setEnabled(bool(rgame.igame))
|
||||
self.ui.install_path.setEnabled(bool(rgame.igame))
|
||||
self.ui.lbl_install_path.setEnabled(bool(rgame.igame))
|
||||
|
||||
self.ui.uninstall_button.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.verify_button.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.repair_button.setEnabled(bool(self.rgame.igame))
|
||||
self.ui.uninstall_button.setEnabled(bool(rgame.igame))
|
||||
self.ui.verify_button.setEnabled(bool(rgame.igame))
|
||||
self.ui.repair_button.setEnabled(bool(rgame.igame))
|
||||
|
||||
if not self.rgame.is_installed or self.rgame.is_origin:
|
||||
if not rgame.is_installed or rgame.is_origin:
|
||||
self.ui.game_actions_stack.setCurrentWidget(self.ui.uninstalled_page)
|
||||
if self.rgame.is_origin:
|
||||
if rgame.is_origin:
|
||||
self.ui.version.setText("N/A")
|
||||
self.ui.version.setEnabled(False)
|
||||
self.ui.install_button.setText(self.tr("Link to Origin/Launch"))
|
||||
|
@ -379,34 +377,26 @@ class GameInfo(QWidget):
|
|||
else:
|
||||
if not self.args.offline:
|
||||
self.ui.repair_button.setDisabled(
|
||||
not os.path.exists(os.path.join(self.core.lgd.get_tmp_path(), f"{self.rgame.app_name}.repair"))
|
||||
not os.path.exists(os.path.join(self.core.lgd.get_tmp_path(), f"{rgame.app_name}.repair"))
|
||||
)
|
||||
self.ui.game_actions_stack.setCurrentWidget(self.ui.installed_page)
|
||||
|
||||
grade_visible = not self.rgame.is_unreal and platform.system() != "Windows"
|
||||
grade_visible = not rgame.is_unreal and platform.system() != "Windows"
|
||||
self.ui.grade.setVisible(grade_visible)
|
||||
self.ui.lbl_grade.setVisible(grade_visible)
|
||||
|
||||
if platform.system() != "Windows" and not self.rgame.is_unreal:
|
||||
if platform.system() != "Windows" and not rgame.is_unreal:
|
||||
self.ui.grade.setText(self.tr("Loading"))
|
||||
self.steam_worker.set_app_name(self.rgame.app_name)
|
||||
QThreadPool.globalInstance().start(self.steam_worker)
|
||||
# TODO: Handle result emitted after quickly changing between game information
|
||||
steam_worker: SteamWorker = SteamWorker(self.core, rgame.app_name)
|
||||
steam_worker.signals.rating.connect(self.ui.grade.setText)
|
||||
QThreadPool.globalInstance().start(steam_worker)
|
||||
|
||||
# If the game that is currently moving matches with the current app_name, we show the progressbar.
|
||||
# Otherwhise, we show the move tool button.
|
||||
if self.rgame.igame is not None:
|
||||
if self.game_moving == self.rgame.app_name:
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_progress_page)
|
||||
else:
|
||||
self.ui.move_stack.setCurrentWidget(self.ui.move_button_page)
|
||||
|
||||
# If a game is verifying or moving, disable both verify and moving buttons.
|
||||
if rgame.worker is not None:
|
||||
self.ui.verify_button.setEnabled(False)
|
||||
self.ui.move_button.setEnabled(False)
|
||||
if self.is_moving:
|
||||
self.ui.move_button.setEnabled(False)
|
||||
self.ui.verify_button.setEnabled(False)
|
||||
self.ui.verify_button.setEnabled(rgame.is_idle)
|
||||
self.ui.move_button.setEnabled(rgame.is_idle)
|
||||
|
||||
self.move_game_pop_up.update_game(rgame.app_name)
|
||||
|
||||
self.rgame = rgame
|
||||
|
||||
|
||||
|
|
|
@ -132,13 +132,13 @@ class RareGame(QObject):
|
|||
def __on_progress_update(self, progress: int):
|
||||
self.progress = progress
|
||||
|
||||
@property
|
||||
def worker(self) -> Optional[QRunnable]:
|
||||
return self.__worker
|
||||
|
||||
@worker.setter
|
||||
def worker(self, worker: Optional[QRunnable]):
|
||||
def set_worker(self, worker: Optional[QRunnable]):
|
||||
self.__worker = worker
|
||||
if worker is None:
|
||||
self.state = RareGame.State.IDLE
|
||||
|
||||
@property
|
||||
def state(self) -> 'RareGame.State':
|
||||
|
|
|
@ -15,6 +15,7 @@ from rare.models.game import RareGame, RareEosOverlay
|
|||
from rare.models.signals import GlobalSignals
|
||||
from .workers import QueueWorker, VerifyWorker, MoveWorker
|
||||
from .image_manager import ImageManager
|
||||
from .workers.worker import QueueWorkerInfo
|
||||
|
||||
logger = getLogger("RareCore")
|
||||
|
||||
|
@ -52,13 +53,16 @@ class RareCore(QObject):
|
|||
rgame.state = RareGame.State.VERIFYING
|
||||
if isinstance(worker, MoveWorker):
|
||||
rgame.state = RareGame.State.MOVING
|
||||
rgame.worker = worker
|
||||
worker.feedback.started.connect(self.__signals.application.update_statubar)
|
||||
rgame.set_worker(worker)
|
||||
worker.feedback.started.connect(self.__signals.application.update_statusbar)
|
||||
worker.feedback.finished.connect(lambda: rgame.set_worker(None))
|
||||
worker.feedback.finished.connect(lambda: self.queue_workers.remove(worker))
|
||||
worker.feedback.finished.connect(self.__signals.application.update_statusbar)
|
||||
self.queue_workers.append(worker)
|
||||
self.queue_threadpool.start(worker, 0)
|
||||
self.queue_threadpool.start(worker, priority=0)
|
||||
self.__signals.application.update_statusbar.emit()
|
||||
|
||||
def queue_info(self) -> List:
|
||||
def queue_info(self) -> List[QueueWorkerInfo]:
|
||||
return [w.worker_info() for w in self.queue_workers]
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -7,7 +7,7 @@ from legendary.lfs.utils import validate_files
|
|||
from legendary.models.game import VerifyResult, InstalledGame
|
||||
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
from .worker import QueueWorker
|
||||
from .worker import QueueWorker, QueueWorkerInfo
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
|
@ -37,8 +37,10 @@ class MoveWorker(QueueWorker):
|
|||
self.file_list = None
|
||||
self.total: int = 0
|
||||
|
||||
def worker_info(self):
|
||||
return None
|
||||
def worker_info(self) -> QueueWorkerInfo:
|
||||
return QueueWorkerInfo(
|
||||
app_name=self.rgame.app_name, app_title=self.rgame.app_title, worker_type="Move", state=self.state
|
||||
)
|
||||
|
||||
def run_real(self):
|
||||
root_directory = Path(self.install_path)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import sys
|
||||
import time
|
||||
from argparse import Namespace
|
||||
from logging import getLogger
|
||||
|
||||
|
@ -10,7 +11,7 @@ from rare.lgndr.core import LegendaryCore
|
|||
from rare.lgndr.glue.arguments import LgndrVerifyGameArgs
|
||||
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
||||
from rare.models.game import RareGame
|
||||
from .worker import QueueWorker
|
||||
from .worker import QueueWorker, QueueWorkerInfo
|
||||
|
||||
logger = getLogger("VerifyWorker")
|
||||
|
||||
|
@ -21,8 +22,8 @@ class VerifyWorker(QueueWorker):
|
|||
result = pyqtSignal(RareGame, bool, int, int)
|
||||
error = pyqtSignal(RareGame, str)
|
||||
|
||||
num: int = 0
|
||||
total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
|
||||
# num: int = 0
|
||||
# total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
|
||||
|
||||
def __init__(self, core: LegendaryCore, args: Namespace, rgame: RareGame):
|
||||
super(VerifyWorker, self).__init__()
|
||||
|
@ -35,8 +36,10 @@ class VerifyWorker(QueueWorker):
|
|||
self.rgame.signals.progress.update.emit(num * 100 // total)
|
||||
self.signals.progress.emit(self.rgame, num, total, percentage, speed)
|
||||
|
||||
def worker_info(self):
|
||||
return None
|
||||
def worker_info(self) -> QueueWorkerInfo:
|
||||
return QueueWorkerInfo(
|
||||
app_name=self.rgame.app_name, app_title=self.rgame.app_title, worker_type="Verify", state=self.state
|
||||
)
|
||||
|
||||
def run_real(self):
|
||||
self.rgame.signals.progress.start.emit()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import sys
|
||||
from abc import abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from enum import IntEnum
|
||||
from typing import Optional
|
||||
|
||||
|
@ -42,6 +43,21 @@ class Worker(QRunnable):
|
|||
self.signals.deleteLater()
|
||||
|
||||
|
||||
class QueueWorkerState(IntEnum):
|
||||
UNDEFINED = 0
|
||||
QUEUED = 1
|
||||
ACTIVE = 2
|
||||
|
||||
|
||||
@dataclass
|
||||
class QueueWorkerInfo:
|
||||
app_name: str
|
||||
app_title: str
|
||||
worker_type: str
|
||||
state: QueueWorkerState
|
||||
progress: int = 0
|
||||
|
||||
|
||||
class QueueWorker(Worker):
|
||||
"""
|
||||
Base queueable worker class
|
||||
|
@ -53,11 +69,6 @@ class QueueWorker(Worker):
|
|||
to the `QueueWorker.signals` attribute, implement `QueueWorker.run_real()` and `QueueWorker.worker_info()`
|
||||
"""
|
||||
|
||||
class State(IntEnum):
|
||||
UNDEFINED = 0
|
||||
QUEUED = 1
|
||||
ACTIVE = 2
|
||||
|
||||
class Signals(QObject):
|
||||
started = pyqtSignal()
|
||||
finished = pyqtSignal()
|
||||
|
@ -65,16 +76,18 @@ class QueueWorker(Worker):
|
|||
def __init__(self):
|
||||
super(QueueWorker, self).__init__()
|
||||
self.feedback = QueueWorker.Signals()
|
||||
self.state = QueueWorker.State.QUEUED
|
||||
self.state = QueueWorkerState.QUEUED
|
||||
|
||||
@pyqtSlot()
|
||||
def run(self):
|
||||
self.state = QueueWorker.State.ACTIVE
|
||||
self.state = QueueWorkerState.ACTIVE
|
||||
self.feedback.started.emit()
|
||||
super(QueueWorker, self).run()
|
||||
self.feedback.finished.emit()
|
||||
self.feedback.deleteLater()
|
||||
|
||||
@abstractmethod
|
||||
def worker_info(self):
|
||||
pass
|
||||
def worker_info(self) -> QueueWorkerInfo:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -8,22 +8,22 @@ from PyQt5.QtCore import pyqtSignal, QRunnable, QObject, QCoreApplication
|
|||
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
|
||||
from rare.shared.workers import Worker
|
||||
from rare.utils.paths import data_dir, cache_dir
|
||||
|
||||
replace_chars = ",;.:-_ "
|
||||
url = "https://api.steampowered.com/ISteamApps/GetAppList/v2/"
|
||||
|
||||
|
||||
class SteamWorker(QRunnable):
|
||||
class SteamWorker(Worker):
|
||||
class Signals(QObject):
|
||||
rating = pyqtSignal(str)
|
||||
|
||||
app_name: str = ""
|
||||
|
||||
def __init__(self, core: LegendaryCore):
|
||||
def __init__(self, core: LegendaryCore, app_name: str):
|
||||
super(SteamWorker, self).__init__()
|
||||
self.signals = SteamWorker.Signals()
|
||||
self.core = core
|
||||
self.app_name = app_name
|
||||
_tr = QCoreApplication.translate
|
||||
self.ratings = {
|
||||
"platinum": _tr("SteamWorker", "Platinum"),
|
||||
|
@ -35,10 +35,7 @@ class SteamWorker(QRunnable):
|
|||
"pending": _tr("SteamWorker", "Could not get grade"),
|
||||
}
|
||||
|
||||
def set_app_name(self, app_name: str):
|
||||
self.app_name = app_name
|
||||
|
||||
def run(self) -> None:
|
||||
def run_real(self) -> None:
|
||||
self.signals.rating.emit(
|
||||
self.ratings.get(get_rating(self.app_name), self.ratings["fail"])
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue