1
0
Fork 0
mirror of synced 2024-06-02 02:34:40 +12:00

Library: Move image loading from RareCore to the GameWidget

Instead of loading images in the showEvent of the MainWindow,
load them in the showEvent of each widget. It seems to reduce
the startup stuttering this way. With some more work
we can only load the images for the widgets that are currently
visible and reduce the stutter even more.

At the same time, reduce the number of concurrent downloads
in the image manager and add a timeout so we won't halt.
The exception from the timeout is just logged at this point,
and the download is not requeued.
This commit is contained in:
loathingKernel 2023-09-14 21:47:47 +03:00
parent c05209578c
commit c063f5f5b9
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
4 changed files with 15 additions and 39 deletions

View file

@ -143,15 +143,6 @@ class MainWindow(QMainWindow):
self.resize(window_size)
self.move(screen_rect.center() - self.rect().adjusted(0, 0, decor_width, decor_height).center())
# lk: For the gritty details see `RareCore.load_pixmaps()` method
# Just before the window is shown, fire a timer to load game icons
# This is by nature a little iffy because we don't really know if the
# has been shown, and it might make the window delay as widgets being are updated.
# Still better than showing a hanged window frame for a few seconds.
def showEvent(self, a0: QShowEvent) -> None:
if not self._window_launched:
QTimer.singleShot(100, self.rcore.load_pixmaps)
@pyqtSlot()
def show(self) -> None:
super(MainWindow, self).show()

View file

@ -1,8 +1,9 @@
import platform
import random
from logging import getLogger
from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot, QObject, QEvent
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot, QObject, QEvent, QTimer
from PyQt5.QtGui import QMouseEvent, QShowEvent
from PyQt5.QtWidgets import QMessageBox, QAction
from rare.models.game import RareGame
@ -105,6 +106,11 @@ class GameWidget(LibraryWidget):
# lk: attributes as `GameWidgetUi` class
__slots__ = "ui"
def showEvent(self, a0: QShowEvent) -> None:
if self.rgame.pixmap.isNull():
QTimer.singleShot(random.randrange(42, 361, 7), self.rgame.load_pixmap)
super().showEvent(a0)
@pyqtSlot()
def update_state(self):
if self.rgame.is_idle:

View file

@ -82,7 +82,7 @@ class ImageManager(QObject):
self.device = ImageSize.Preset(1, QApplication.instance().devicePixelRatio())
self.threadpool = QThreadPool()
self.threadpool.setMaxThreadCount(8)
self.threadpool.setMaxThreadCount(6)
def __img_dir(self, app_name: str) -> Path:
return self.image_dir.joinpath(app_name)
@ -182,8 +182,12 @@ class ImageManager(QObject):
logger.info(f"Downloading {image['type']} for {game.app_name} ({game.app_title})")
json_data[image["type"]] = image["md5"]
payload = {"resize": 1, "w": ImageSize.Image.size.width(), "h": ImageSize.Image.size.height()}
# cache_data[image["type"]] = requests.get(image["url"], params=payload, timeout=2).content
cache_data[image["type"]] = requests.get(image["url"], params=payload).content
try:
# cache_data[image["type"]] = requests.get(image["url"], params=payload).content
cache_data[image["type"]] = requests.get(image["url"], params=payload, timeout=10).content
except Exception as e:
logger.error(e)
return False
self.__convert(game, cache_data)
# lk: don't keep the cache if there is no logo (kept for me)

View file

@ -330,31 +330,6 @@ class RareCore(QObject):
self.fetch_entitlements()
self.resolve_origin()
def load_pixmaps(self) -> None:
"""
Load pixmaps for all games
This exists here solely to fight signal and possibly threading issues.
The initial image loading at startup should not be done in the RareGame class
for two reasons. It will delay startup due to widget updates and the image
might become availabe before the UI is brought up. In case of the second, we
will get both a long queue of signals to be serviced and some of them might
be not connected yet so the widget won't be updated. So do the loading here
by calling this after the MainWindow has finished initializing.
@return: None
"""
def __load_pixmaps() -> None:
# time.sleep(0.1)
for rgame in self.__library.values():
# self.__image_manager.download_image(rgame.game, rgame.set_pixmap, 0, False)
rgame.load_pixmap()
# lk: activity perception delay
time.sleep(0.0005)
pixmap_worker = QRunnable.create(__load_pixmaps)
QThreadPool.globalInstance().start(pixmap_worker)
@property
def games_and_dlcs(self) -> Iterator[RareGame]:
for app_name in self.__library: