1
0
Fork 0
mirror of synced 2024-06-30 12:11:19 +12:00

RareCore: Add RareGames to a data structure in RareCore

This merges a few of the internal features of RareCore such us
RareGame filtering and thus game grouping based on attributes.

This is required to properly connect a single signal from RareCore to
the downloads tab for game installation. This also includes filtering
games based on updates and other attributes.

Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
This commit is contained in:
loathingKernel 2023-01-04 22:38:05 +02:00
parent b0c4fb4212
commit ab596139af
6 changed files with 104 additions and 15 deletions

View file

@ -1,7 +1,7 @@
from PyQt5.QtCore import QSize, pyqtSignal, pyqtSlot from PyQt5.QtCore import QSize, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut, QMessageBox from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut, QMessageBox
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton from rare.shared import RareCore, LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
from rare.components.tabs.account import AccountWidget from rare.components.tabs.account import AccountWidget
from rare.components.tabs.downloads import DownloadsTab from rare.components.tabs.downloads import DownloadsTab
from rare.components.tabs.games import GamesTab from rare.components.tabs.games import GamesTab
@ -18,6 +18,7 @@ class TabWidget(QTabWidget):
def __init__(self, parent): def __init__(self, parent):
super(TabWidget, self).__init__(parent=parent) super(TabWidget, self).__init__(parent=parent)
self.rcore = RareCore.instance()
self.core = LegendaryCoreSingleton() self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton() self.signals = GlobalSignalsSingleton()
self.args = ArgumentsSingleton() self.args = ArgumentsSingleton()
@ -28,17 +29,13 @@ class TabWidget(QTabWidget):
self.games_tab = GamesTab(self) self.games_tab = GamesTab(self)
self.addTab(self.games_tab, self.tr("Games")) self.addTab(self.games_tab, self.tr("Games"))
# Downloads Tab after Games Tab to use populated RareCore games list
if not self.args.offline: if not self.args.offline:
# updates = self.games_tab.default_widget.game_list.updates self.downloads_tab = DownloadsTab(self)
self.downloads_tab = DownloadsTab(self.games_tab.game_updates, self) updates = list(self.rcore.updates)
self.addTab( self.addTab(
self.downloads_tab, self.downloads_tab,
"Downloads" self.tr("Downloads {}").format(f"({len(updates) if updates else 0})"),
+ (
" (" + str(len(self.games_tab.game_updates)) + ")"
if len(self.games_tab.game_updates) != 0
else ""
),
) )
self.store = Shop(self.core) self.store = Shop(self.core)
self.addTab(self.store, self.tr("Store (Beta)")) self.addTab(self.store, self.tr("Store (Beta)"))

View file

@ -20,7 +20,7 @@ from rare.components.tabs.downloads.download_thread import DownloadThread
from rare.lgndr.models.downloading import UIUpdate from rare.lgndr.models.downloading import UIUpdate
from rare.models.game import RareGame from rare.models.game import RareGame
from rare.models.install import InstallOptionsModel, InstallQueueItemModel from rare.models.install import InstallOptionsModel, InstallQueueItemModel
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.shared import RareCore, LegendaryCoreSingleton, GlobalSignalsSingleton
from rare.ui.components.tabs.downloads.downloads_tab import Ui_DownloadsTab from rare.ui.components.tabs.downloads.downloads_tab import Ui_DownloadsTab
from rare.utils.misc import get_size, create_desktop_link from rare.utils.misc import get_size, create_desktop_link
@ -32,9 +32,10 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
dl_queue: List[InstallQueueItemModel] = [] dl_queue: List[InstallQueueItemModel] = []
dl_status = pyqtSignal(int) dl_status = pyqtSignal(int)
def __init__(self, game_updates: Set[RareGame], parent=None): def __init__(self, parent=None):
super(DownloadsTab, self).__init__(parent=parent) super(DownloadsTab, self).__init__(parent=parent)
self.setupUi(self) self.setupUi(self)
self.rcore = RareCore.instance()
self.core = LegendaryCoreSingleton() self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton() self.signals = GlobalSignalsSingleton()
@ -56,9 +57,10 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
self.update_text = QLabel(self.tr("No updates available")) self.update_text = QLabel(self.tr("No updates available"))
self.update_layout.addWidget(self.update_text) self.update_layout.addWidget(self.update_text)
self.update_text.setVisible(len(game_updates) == 0)
for rgame in game_updates: has_updates = False
for rgame in self.rcore.updates:
has_updates = True
self.add_update(rgame) self.add_update(rgame)
self.queue_widget.item_removed.connect(self.queue_item_removed) self.queue_widget.item_removed.connect(self.queue_item_removed)

View file

@ -14,6 +14,7 @@ from rare.shared import (
ApiResultsSingleton, ApiResultsSingleton,
ImageManagerSingleton, ImageManagerSingleton,
) )
from rare.shared import RareCore
from rare.shared.game_utils import GameUtils from rare.shared.game_utils import GameUtils
from rare.widgets.library_layout import LibraryLayout from rare.widgets.library_layout import LibraryLayout
from rare.widgets.sliding_stack import SlidingStackedWidget from rare.widgets.sliding_stack import SlidingStackedWidget
@ -30,6 +31,7 @@ logger = getLogger("GamesTab")
class GamesTab(QStackedWidget): class GamesTab(QStackedWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super(GamesTab, self).__init__(parent=parent) super(GamesTab, self).__init__(parent=parent)
self.rcore = RareCore.instance()
self.core = LegendaryCoreSingleton() self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton() self.signals = GlobalSignalsSingleton()
self.args = ArgumentsSingleton() self.args = ArgumentsSingleton()
@ -195,6 +197,7 @@ class GamesTab(QStackedWidget):
self.update_count_games_label() self.update_count_games_label()
for game in self.game_list + self.no_assets: for game in self.game_list + self.no_assets:
rgame = self.__create_game_with_dlcs(game) rgame = self.__create_game_with_dlcs(game)
self.rcore.add_game(rgame)
icon_widget, list_widget = self.add_library_widget(rgame) icon_widget, list_widget = self.add_library_widget(rgame)
if not icon_widget or not list_widget: if not icon_widget or not list_widget:
logger.warning(f"Excluding {rgame.app_name} from the game list") logger.warning(f"Excluding {rgame.app_name} from the game list")

View file

@ -116,7 +116,7 @@ class GameInfo(QWidget):
if self.rgame.is_origin: if self.rgame.is_origin:
self.game_utils.launch_game(self.rgame.app_name) self.game_utils.launch_game(self.rgame.app_name)
else: else:
self.signals.game.install.emit(InstallOptionsModel(app_name=self.rgame.app_name)) self.rgame.install()
@pyqtSlot() @pyqtSlot()
def uninstall(self): def uninstall(self):

View file

@ -346,6 +346,11 @@ class RareGame(QObject):
""" """
return not self.game.asset_infos return not self.game.asset_infos
def install(self):
self.signals.game.install.emit(
InstallOptionsModel(app_name=self.game.app_name)
)
@property @property
def is_origin(self) -> bool: def is_origin(self) -> bool:
return self.game.metadata.get("customAttributes", {}).get("ThirdPartyManagedApp", {}).get("value") == "Origin" return self.game.metadata.get("customAttributes", {}).get("ThirdPartyManagedApp", {}).get("value") == "Origin"

View file

@ -1,13 +1,16 @@
import configparser import configparser
import os import os
from argparse import Namespace from argparse import Namespace
from itertools import chain
from logging import getLogger from logging import getLogger
from typing import Optional from typing import Optional, Dict, Iterator, Callable
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
from legendary.models.game import Game, SaveGameFile
from rare.lgndr.core import LegendaryCore from rare.lgndr.core import LegendaryCore
from rare.models.apiresults import ApiResults from rare.models.apiresults import ApiResults
from rare.models.game import RareGame
from rare.models.signals import GlobalSignals from rare.models.signals import GlobalSignals
from .image_manager import ImageManager from .image_manager import ImageManager
@ -32,6 +35,8 @@ class RareCore(QObject):
self.core(init=True) self.core(init=True)
self.image_manager(init=True) self.image_manager(init=True)
self.__games: Dict[str, RareGame] = {}
RareCore._instance = self RareCore._instance = self
@staticmethod @staticmethod
@ -131,3 +136,80 @@ class RareCore(QObject):
super(RareCore, self).deleteLater() super(RareCore, self).deleteLater()
def get_game(self, app_name: str) -> RareGame:
return self.__games[app_name]
def add_game(self, rgame: RareGame) -> None:
rgame.signals.game.install.connect(self._signals.game.install)
self.__games[rgame.app_name] = rgame
def __filter_games(self, condition: Callable[[RareGame], bool]) -> Iterator[RareGame]:
return filter(condition, self.__games.values())
@property
def games_and_dlcs(self) -> Iterator[RareGame]:
for app_name in self.__games:
yield self.__games[app_name]
@property
def games(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: not game.is_dlc)
@property
def installed_games(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.is_installed and not game.is_dlc)
@property
def game_list(self) -> Iterator[Game]:
for game in self.games:
yield game.game
@property
def dlcs(self) -> Dict[str, Game]:
"""!
RareGames that ARE DLCs themselves
"""
return {game.game.catalog_item_id: game.owned_dlcs for game in self.has_dlcs}
# return self.__filter_games(lambda game: game.is_dlc)
@property
def has_dlcs(self) -> Iterator[RareGame]:
"""!
RareGames that HAVE DLCs associated with them
"""
return self.__filter_games(lambda game: bool(game.owned_dlcs))
@property
def bit32_games(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.is_win32)
@property
def mac_games(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.is_mac)
@property
def no_asset_games(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.is_non_asset)
@property
def unreal_engine(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.is_unreal)
@property
def updates(self) -> Iterator[RareGame]:
return self.__filter_games(lambda game: game.has_update)
@property
def saves(self) -> Iterator[SaveGameFile]:
"""!
SaveGameFiles across games
"""
return chain.from_iterable([game.saves for game in self.has_saves])
@property
def has_saves(self) -> Iterator[RareGame]:
"""!
RareGames that have SaveGameFiles associated with them
"""
return self.__filter_games(lambda game: bool(game.saves))