Store improvements
- Store games by source - Added convenience dunder methods (contains, iter, len, getitem) - Added store.get - Changed `enable_in_pipeline` for `toggle_in_pipeline`
This commit is contained in:
@@ -155,9 +155,10 @@ class DetailsWindow(Adw.Window):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Increment the number after the game id (eg. imported_1, imported_2)
|
# Increment the number after the game id (eg. imported_1, imported_2)
|
||||||
|
source_id = "imported"
|
||||||
numbers = [0]
|
numbers = [0]
|
||||||
game_id: str
|
game_id: str
|
||||||
for game_id in shared.store.games:
|
for game_id in shared.source_games[source_id]:
|
||||||
prefix = "imported_"
|
prefix = "imported_"
|
||||||
if not game_id.startswith(prefix):
|
if not game_id.startswith(prefix):
|
||||||
continue
|
continue
|
||||||
@@ -168,7 +169,7 @@ class DetailsWindow(Adw.Window):
|
|||||||
{
|
{
|
||||||
"game_id": f"imported_{game_number}",
|
"game_id": f"imported_{game_number}",
|
||||||
"hidden": False,
|
"hidden": False,
|
||||||
"source": "imported",
|
"source": source_id,
|
||||||
"added": int(time()),
|
"added": int(time()),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class CartridgesApplication(Adw.Application):
|
|||||||
shared.store.add_manager(SteamAPIManager())
|
shared.store.add_manager(SteamAPIManager())
|
||||||
shared.store.add_manager(OnlineCoverManager())
|
shared.store.add_manager(OnlineCoverManager())
|
||||||
shared.store.add_manager(SGDBManager())
|
shared.store.add_manager(SGDBManager())
|
||||||
shared.store.enable_manager_in_pipelines(FileManager)
|
shared.store.toggle_manager_in_pipelines(FileManager, True)
|
||||||
|
|
||||||
# Create actions
|
# Create actions
|
||||||
self.create_actions(
|
self.create_actions(
|
||||||
|
|||||||
@@ -214,10 +214,9 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
self.toast.dismiss()
|
self.toast.dismiss()
|
||||||
|
|
||||||
def remove_all_games(self, *_args):
|
def remove_all_games(self, *_args):
|
||||||
for game in shared.store.games.values():
|
for game in shared.store:
|
||||||
if not game.removed:
|
if not game.removed:
|
||||||
self.removed_games.add(game)
|
self.removed_games.add(game)
|
||||||
|
|
||||||
game.removed = True
|
game.removed = True
|
||||||
game.save()
|
game.save()
|
||||||
game.update()
|
game.update()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from typing import MutableMapping, Generator, Any
|
||||||
|
|
||||||
from src import shared
|
from src import shared
|
||||||
from src.game import Game
|
from src.game import Game
|
||||||
@@ -31,24 +32,59 @@ class Store:
|
|||||||
managers: dict[type[Manager], Manager]
|
managers: dict[type[Manager], Manager]
|
||||||
pipeline_managers: set[Manager]
|
pipeline_managers: set[Manager]
|
||||||
pipelines: dict[str, Pipeline]
|
pipelines: dict[str, Pipeline]
|
||||||
games: dict[str, Game]
|
source_games: MutableMapping[str, MutableMapping[str, Game]]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.managers = {}
|
self.managers = {}
|
||||||
self.pipeline_managers = set()
|
self.pipeline_managers = set()
|
||||||
self.pipelines = {}
|
self.pipelines = {}
|
||||||
self.games = {}
|
self.source_games = {}
|
||||||
|
|
||||||
|
def __contains__(self, obj: object) -> bool:
|
||||||
|
"""Check if the game is present in the store with the `in` keyword"""
|
||||||
|
if not isinstance(obj, Game):
|
||||||
|
return False
|
||||||
|
if not (source_mapping := self.source_games.get(obj.source)):
|
||||||
|
return False
|
||||||
|
return obj.game_id in source_mapping
|
||||||
|
|
||||||
|
def __iter__(self) -> Generator[Game, None, None]:
|
||||||
|
"""Iterate through the games in the store with `for ... in`"""
|
||||||
|
for _source_id, games_mapping in self.source_games.items():
|
||||||
|
for _game_id, game in games_mapping.items():
|
||||||
|
yield game
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
"""Get the number of games in the store with the `len` builtin"""
|
||||||
|
return sum(len(source_mapping) for source_mapping in self.source_games)
|
||||||
|
|
||||||
|
def __getitem__(self, game_id: str) -> Game:
|
||||||
|
"""Get a game by its id with `store["game_id_goes_here"]`"""
|
||||||
|
for game in iter(self):
|
||||||
|
if game.game_id == game_id:
|
||||||
|
return game
|
||||||
|
raise KeyError("Game not found in store")
|
||||||
|
|
||||||
|
def get(self, game_id: str, default: Any = None) -> Game | Any:
|
||||||
|
"""Get a game by its ID, with a fallback if not found"""
|
||||||
|
try:
|
||||||
|
game = self[game_id]
|
||||||
|
return game
|
||||||
|
except KeyError:
|
||||||
|
return default
|
||||||
|
|
||||||
def add_manager(self, manager: Manager, in_pipeline=True):
|
def add_manager(self, manager: Manager, in_pipeline=True):
|
||||||
"""Add a manager to the store"""
|
"""Add a manager to the store"""
|
||||||
manager_type = type(manager)
|
manager_type = type(manager)
|
||||||
self.managers[manager_type] = manager
|
self.managers[manager_type] = manager
|
||||||
if in_pipeline:
|
self.toggle_manager_in_pipelines(manager_type, in_pipeline)
|
||||||
self.enable_manager_in_pipelines(manager_type)
|
|
||||||
|
|
||||||
def enable_manager_in_pipelines(self, manager_type: type[Manager]):
|
def toggle_manager_in_pipelines(self, manager_type: type[Manager], enable: bool):
|
||||||
"""Make a manager run in new pipelines"""
|
"""Change if a manager should run in new pipelines"""
|
||||||
self.pipeline_managers.add(self.managers[manager_type])
|
if enable:
|
||||||
|
self.pipeline_managers.add(self.managers[manager_type])
|
||||||
|
else:
|
||||||
|
self.pipeline_managers.discard(self.managers[manager_type])
|
||||||
|
|
||||||
def cleanup_game(self, game: Game) -> None:
|
def cleanup_game(self, game: Game) -> None:
|
||||||
"""Remove a game's files"""
|
"""Remove a game's files"""
|
||||||
@@ -74,7 +110,7 @@ class Store:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Handle game duplicates
|
# Handle game duplicates
|
||||||
stored_game = self.games.get(game.game_id)
|
stored_game = self.get(game.game_id)
|
||||||
if not stored_game:
|
if not stored_game:
|
||||||
# New game, do as normal
|
# New game, do as normal
|
||||||
logging.debug("New store game %s (%s)", game.name, game.game_id)
|
logging.debug("New store game %s (%s)", game.name, game.game_id)
|
||||||
@@ -96,11 +132,15 @@ class Store:
|
|||||||
for signal in manager.signals:
|
for signal in manager.signals:
|
||||||
game.connect(signal, manager.execute_resilient_manager_logic)
|
game.connect(signal, manager.execute_resilient_manager_logic)
|
||||||
|
|
||||||
|
# Add the game to the store
|
||||||
|
if not game.source in self.source_games:
|
||||||
|
self.source_games[game.source] = {}
|
||||||
|
self.source_games[game.source][game.game_id] = game
|
||||||
|
|
||||||
# Run the pipeline for the game
|
# Run the pipeline for the game
|
||||||
if not run_pipeline:
|
if not run_pipeline:
|
||||||
return None
|
return None
|
||||||
pipeline = Pipeline(game, additional_data, self.pipeline_managers)
|
pipeline = Pipeline(game, additional_data, self.pipeline_managers)
|
||||||
self.games[game.game_id] = game
|
|
||||||
self.pipelines[game.game_id] = pipeline
|
self.pipelines[game.game_id] = pipeline
|
||||||
pipeline.advance()
|
pipeline.advance()
|
||||||
return pipeline
|
return pipeline
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
|
|||||||
def set_library_child(self):
|
def set_library_child(self):
|
||||||
child, hidden_child = self.notice_empty, self.hidden_notice_empty
|
child, hidden_child = self.notice_empty, self.hidden_notice_empty
|
||||||
|
|
||||||
for game in shared.store.games.values():
|
for game in shared.store:
|
||||||
if game.removed or game.blacklisted:
|
if game.removed or game.blacklisted:
|
||||||
continue
|
continue
|
||||||
if game.hidden:
|
if game.hidden:
|
||||||
|
|||||||
Reference in New Issue
Block a user