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:
parent
c05209578c
commit
c063f5f5b9
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue