Use signals for updating and saving games

This commit is contained in:
kramo
2023-06-15 17:37:54 +02:00
parent e6afed6678
commit 39bc64c136
7 changed files with 107 additions and 78 deletions

View File

@@ -1,16 +1,55 @@
from src import shared # pylint: disable=no-name-in-module
from src.game import Game
from src.game_cover import GameCover
from src.store.managers.manager import Manager
from src.store.managers.sgdb_manager import SGDBManager
from src.store.managers.steam_api_manager import SteamAPIManager
from src.store.managers.manager import Manager
class DisplayManager(Manager):
"""Manager in charge of adding a game to the UI"""
run_after = (SteamAPIManager, SGDBManager)
signals = {"update-ready"}
def manager_logic(self, game: Game, _additional_data: dict) -> None:
# TODO decouple a game from its widget
shared.win.games[game.game_id] = game
game.update()
if game.get_parent():
game.get_parent().get_parent().remove(game)
if game.get_parent():
game.get_parent().set_child()
game.menu_button.set_menu_model(
game.hidden_game_options if game.hidden else game.game_options
)
game.title.set_label(game.name)
game.menu_button.get_popover().connect(
"notify::visible", game.toggle_play, None
)
game.menu_button.get_popover().connect(
"notify::visible", game.win.set_active_game, game
)
if game.game_id in game.win.game_covers:
game.game_cover = game.win.game_covers[game.game_id]
game.game_cover.add_picture(game.cover)
else:
game.game_cover = GameCover({game.cover}, game.get_cover_path())
game.win.game_covers[game.game_id] = game.game_cover
if (
game.win.stack.get_visible_child() == game.win.details_view
and game.win.active_game == game
):
game.win.show_details_view(game)
if not game.removed and not game.blacklisted:
if game.hidden:
game.win.hidden_library.append(game)
else:
game.win.library.append(game)
game.get_parent().set_focusable(False)
game.win.set_library_child()

View File

@@ -1,3 +1,6 @@
import json
from src import shared # pylint: disable=no-name-in-module
from src.game import Game
from src.store.managers.async_manager import AsyncManager
from src.store.managers.steam_api_manager import SteamAPIManager
@@ -7,6 +10,31 @@ class FileManager(AsyncManager):
"""Manager in charge of saving a game to a file"""
run_after = (SteamAPIManager,)
signals = {"save-ready"}
def manager_logic(self, game: Game, _additional_data: dict) -> None:
game.save()
def manager_logic(self, game: Game, additional_data: dict) -> None:
if additional_data.get("skip_save"): # Skip saving when loading games from disk
return
shared.games_dir.mkdir(parents=True, exist_ok=True)
attrs = (
"added",
"executable",
"game_id",
"source",
"hidden",
"last_played",
"name",
"developer",
"removed",
"blacklisted",
"version",
)
json.dump(
{attr: getattr(game, attr) for attr in attrs if attr},
(shared.games_dir / f"{game.game_id}.json").open("w"),
indent=4,
sort_keys=True,
)

View File

@@ -21,6 +21,7 @@ class Manager:
retryable_on: Container[type[Exception]] = tuple()
continue_on: Container[type[Exception]] = tuple()
signals: Container[type[str]] = set()
retry_delay: int = 3
max_tries: int = 3
@@ -110,6 +111,5 @@ class Manager:
self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any]
) -> None:
"""Pass the game through the manager"""
# TODO: connect to signals here
self.execute_resilient_manager_logic(game, additional_data)
callback(self)

View File

@@ -16,9 +16,12 @@ class Store:
self.games = {}
self.pipelines = {}
def add_manager(self, manager: Manager):
def add_manager(self, manager: Manager, in_pipeline=True):
"""Add a manager that will run when games are added"""
self.managers[type(manager)] = manager
self.managers[type(manager)] = [manager, in_pipeline]
def manager_to_pipeline(self, manager_type: type[Manager]):
self.managers[manager_type][1] = True
def add_game(
self, game: Game, additional_data: dict, replace=False
@@ -50,8 +53,17 @@ class Store:
path.unlink(missing_ok=True)
return None
# Connect signals
for manager, _in_pipeline in self.managers.values():
for signal in manager.signals:
game.connect(signal, manager.execute_resilient_manager_logic)
# Run the pipeline for the game
pipeline = Pipeline(game, additional_data, self.managers.values())
pipeline = Pipeline(
game,
additional_data,
(manager[0] for manager in self.managers.values() if manager[1]),
)
self.games[game.game_id] = game
self.pipelines[game.game_id] = pipeline
pipeline.advance()