Various changes
- Removed useless format manager - Moved pipeline to its own file - Fixed steam source next not returning game - Changed pipeline order
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
from src.game import Game
|
||||
from src.store.managers.format_update_manager import FormatUpdateManager
|
||||
from src.store.managers.manager import Manager
|
||||
from src.store.managers.sgdb_manager import SGDBManager
|
||||
from src.store.managers.steam_api_manager import SteamAPIManager
|
||||
|
||||
|
||||
class FileManager(Manager):
|
||||
"""Manager in charge of saving a game to a file"""
|
||||
|
||||
run_after = set((SteamAPIManager, SGDBManager, FormatUpdateManager))
|
||||
run_after = set((SteamAPIManager,))
|
||||
|
||||
def run(self, game: Game) -> None:
|
||||
game.save()
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
from src.store.managers.manager import Manager
|
||||
from src.game import Game
|
||||
|
||||
|
||||
class FormatUpdateManager(Manager):
|
||||
"""Class in charge of migrating a game from an older format"""
|
||||
|
||||
def v1_5_to_v2_0(self, game: Game) -> None:
|
||||
"""Convert a game from v1.5 format to v2.0 format"""
|
||||
if game.blacklisted is None:
|
||||
game.blacklisted = False
|
||||
if game.removed is None:
|
||||
game.removed = False
|
||||
game.version = 2.0
|
||||
|
||||
def run(self, game: Game) -> None:
|
||||
if game.version is None:
|
||||
self.v1_5_to_v2_0(game)
|
||||
game.save()
|
||||
@@ -3,11 +3,14 @@ from requests import HTTPError
|
||||
from src.game import Game
|
||||
from src.store.managers.manager import Manager
|
||||
from src.utils.steamgriddb import SGDBAuthError, SGDBError, SGDBHelper
|
||||
from src.store.managers.steam_api_manager import SteamAPIManager
|
||||
|
||||
|
||||
class SGDBManager(Manager):
|
||||
"""Manager in charge of downloading a game's cover from steamgriddb"""
|
||||
|
||||
run_after = set((SteamAPIManager,))
|
||||
|
||||
def run(self, game: Game) -> None:
|
||||
try:
|
||||
sgdb = SGDBHelper()
|
||||
|
||||
80
src/store/pipeline.py
Normal file
80
src/store/pipeline.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from typing import Iterable
|
||||
|
||||
from gi.repository import GObject
|
||||
|
||||
from src.game import Game
|
||||
from src.store.managers.manager import Manager
|
||||
from src.utils.task import Task
|
||||
|
||||
|
||||
class Pipeline(GObject.Object):
|
||||
"""Class representing a set of managers for a game"""
|
||||
|
||||
game: Game
|
||||
|
||||
waiting: set[Manager]
|
||||
running: set[Manager]
|
||||
done: set[Manager]
|
||||
|
||||
def __init__(self, game: Game, managers: Iterable[Manager]) -> None:
|
||||
super().__init__()
|
||||
self.game = game
|
||||
self.waiting = set(managers)
|
||||
self.running = set()
|
||||
self.done = set()
|
||||
|
||||
@property
|
||||
def not_done(self) -> set[Manager]:
|
||||
"""Get the managers that are not done yet"""
|
||||
return self.waiting | self.running
|
||||
|
||||
@property
|
||||
def blocked(self) -> set[Manager]:
|
||||
"""Get the managers that cannot run because their dependencies aren't done"""
|
||||
blocked = set()
|
||||
for manager_a in self.waiting:
|
||||
for manager_b in self.not_done:
|
||||
if manager_a == manager_b:
|
||||
continue
|
||||
if type(manager_b) in manager_a.run_after:
|
||||
blocked.add(manager_a)
|
||||
return blocked
|
||||
|
||||
@property
|
||||
def ready(self) -> set[Manager]:
|
||||
"""Get the managers that can be run"""
|
||||
return self.waiting - self.blocked
|
||||
|
||||
def advance(self):
|
||||
"""Spawn tasks for managers that are able to run for a game"""
|
||||
for manager in self.ready:
|
||||
self.waiting.remove(manager)
|
||||
self.running.add(manager)
|
||||
data = (manager,)
|
||||
task = Task.new(self, manager.cancellable, self.manager_task_callback, data)
|
||||
task.set_task_data(data)
|
||||
task.run_in_thread(self.manager_task_thread_func)
|
||||
|
||||
@GObject.Signal(name="manager-started", arg_types=(object,))
|
||||
def manager_started(self, manager: Manager) -> None:
|
||||
"""Signal emitted when a manager is started"""
|
||||
pass
|
||||
|
||||
def manager_task_thread_func(self, _task, _source_object, data, cancellable):
|
||||
"""Thread function for manager tasks"""
|
||||
manager, *_rest = data
|
||||
self.emit("manager-started", manager)
|
||||
manager.run(self.game)
|
||||
|
||||
@GObject.Signal(name="manager-done", arg_types=(object,))
|
||||
def manager_done(self, manager: Manager) -> None:
|
||||
"""Signal emitted when a manager is done"""
|
||||
pass
|
||||
|
||||
def manager_task_callback(self, _source_object, _result, data):
|
||||
"""Callback function for manager tasks"""
|
||||
manager, *_rest = data
|
||||
self.running.remove(manager)
|
||||
self.done.add(manager)
|
||||
self.emit("manager-done", manager)
|
||||
self.advance()
|
||||
@@ -1,84 +1,7 @@
|
||||
from typing import Iterable
|
||||
|
||||
from gi.repository import GObject
|
||||
|
||||
from src import shared
|
||||
from src.game import Game
|
||||
from src.store.managers.manager import Manager
|
||||
from src.utils.task import Task
|
||||
|
||||
|
||||
class Pipeline(GObject.Object):
|
||||
"""Class representing a set of managers for a game"""
|
||||
|
||||
game: Game
|
||||
|
||||
waiting: set[Manager]
|
||||
running: set[Manager]
|
||||
done: set[Manager]
|
||||
|
||||
def __init__(self, game: Game, managers: Iterable[Manager]) -> None:
|
||||
super().__init__()
|
||||
self.game = game
|
||||
self.waiting = set(managers)
|
||||
self.running = set()
|
||||
self.done = set()
|
||||
|
||||
@property
|
||||
def not_done(self) -> set[Manager]:
|
||||
"""Get the managers that are not done yet"""
|
||||
return self.waiting | self.running
|
||||
|
||||
@property
|
||||
def blocked(self) -> set[Manager]:
|
||||
"""Get the managers that cannot run because their dependencies aren't done"""
|
||||
blocked = set()
|
||||
for manager_a in self.waiting:
|
||||
for manager_b in self.not_done:
|
||||
if manager_a == manager_b:
|
||||
continue
|
||||
if type(manager_b) in manager_a.run_after:
|
||||
blocked.add(manager_a)
|
||||
return blocked
|
||||
|
||||
@property
|
||||
def ready(self) -> set[Manager]:
|
||||
"""Get the managers that can be run"""
|
||||
return self.waiting - self.blocked
|
||||
|
||||
def advance(self):
|
||||
"""Spawn tasks for managers that are able to run for a game"""
|
||||
for manager in self.ready:
|
||||
self.waiting.remove(manager)
|
||||
self.running.add(manager)
|
||||
data = (manager,)
|
||||
task = Task.new(self, manager.cancellable, self.manager_task_callback, data)
|
||||
task.set_task_data(data)
|
||||
task.run_in_thread(self.manager_task_thread_func)
|
||||
|
||||
@GObject.Signal(name="manager-started", arg_types=(object,))
|
||||
def manager_started(self, manager: Manager) -> None:
|
||||
"""Signal emitted when a manager is started"""
|
||||
pass
|
||||
|
||||
def manager_task_thread_func(self, _task, _source_object, data, cancellable):
|
||||
"""Thread function for manager tasks"""
|
||||
manager, *_rest = data
|
||||
self.emit("manager-started", manager)
|
||||
manager.run(self.game)
|
||||
|
||||
@GObject.Signal(name="manager-done", arg_types=(object,))
|
||||
def manager_done(self, manager: Manager) -> None:
|
||||
"""Signal emitted when a manager is done"""
|
||||
pass
|
||||
|
||||
def manager_task_callback(self, _source_object, _result, data):
|
||||
"""Callback function for manager tasks"""
|
||||
manager, *_rest = data
|
||||
self.running.remove(manager)
|
||||
self.done.add(manager)
|
||||
self.emit("manager-done", manager)
|
||||
self.advance()
|
||||
from src.store.pipeline import Pipeline
|
||||
|
||||
|
||||
class Store:
|
||||
|
||||
Reference in New Issue
Block a user