mirror of
https://github.com/lutris/lutris
synced 2024-09-05 07:23:32 +00:00
Group delegate classes in the delegates module
This commit is contained in:
parent
27a3d71697
commit
41c300fefd
|
@ -18,7 +18,7 @@ from lutris.config import LutrisConfig
|
|||
from lutris.database import categories as categories_db
|
||||
from lutris.database import games as games_db
|
||||
from lutris.database import sql
|
||||
from lutris.exceptions import GameConfigError, UnavailableRunnerError, watch_game_errors
|
||||
from lutris.exceptions import GameConfigError, watch_game_errors
|
||||
from lutris.runner_interpreter import export_bash_script, get_launch_parameters
|
||||
from lutris.runners import InvalidRunner, import_runner
|
||||
from lutris.util import audio, discord, extract, jobs, linux, strings, system, xdgshortcuts
|
||||
|
@ -67,38 +67,6 @@ class Game(GObject.Object):
|
|||
"game-installed": (GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||
}
|
||||
|
||||
class LaunchUIDelegate:
|
||||
"""These objects provide UI for the game while it is being launched;
|
||||
one provided to the launch() method.
|
||||
|
||||
The default implementation provides no UI and makes default choices for
|
||||
the user, but DialogLaunchUIDelegate implements this to show dialogs and ask the
|
||||
user questions. Windows then inherit from DialogLaunchUIDelegate.
|
||||
|
||||
If these methods throw any errors are reported via tha game-error signal;
|
||||
that is not part of this delegate because errors can be report outside of
|
||||
the launch() method, where no delegate is available.
|
||||
"""
|
||||
|
||||
def check_game_launchable(self, game):
|
||||
"""See if the game can be launched. If there are adverse conditions,
|
||||
this can warn the user and ask whether to launch. If this returs
|
||||
False, the launch is cancelled. The default is to return True with no
|
||||
actual checks.
|
||||
"""
|
||||
if not game.runner.is_installed():
|
||||
raise UnavailableRunnerError("The required runner '%s' is not installed." % game.runner.name)
|
||||
return True
|
||||
|
||||
def select_game_launch_config(self, game):
|
||||
"""Prompt the user for which launch config to use. Returns None
|
||||
if the user cancelled, an empty dict for the primary game configuration
|
||||
and the launch_config as a dict if one is selected.
|
||||
|
||||
The default is the select the primary game.
|
||||
"""
|
||||
return {} # primary game
|
||||
|
||||
def __init__(self, game_id=None):
|
||||
super().__init__()
|
||||
self._id = game_id # pylint: disable=invalid-name
|
||||
|
@ -126,6 +94,7 @@ class Game(GObject.Object):
|
|||
self.service = game_data.get("service")
|
||||
self.appid = game_data.get("service_id")
|
||||
self.playtime = float(game_data.get("playtime") or 0.0)
|
||||
self.discord_id = game_data.get('discord_id') # Discord App ID for RPC
|
||||
|
||||
self._config = None
|
||||
self._runner = None
|
||||
|
@ -146,9 +115,6 @@ class Game(GObject.Object):
|
|||
self.timer = Timer()
|
||||
self.screen_saver_inhibitor_cookie = None
|
||||
|
||||
# Adding Discord App ID for RPC
|
||||
self.discord_id = game_data.get('discord_id')
|
||||
|
||||
@staticmethod
|
||||
def create_empty_service_game(db_game, service):
|
||||
"""Creates a Game from the database data from ServiceGameCollection, which is
|
||||
|
|
|
@ -41,6 +41,7 @@ from lutris.game import Game, export_game, import_game
|
|||
from lutris.installer import get_installers
|
||||
from lutris.gui.dialogs import ErrorDialog, InstallOrPlayDialog, NoticeDialog, LutrisInitDialog
|
||||
from lutris.gui.dialogs.issue import IssueReportWindow
|
||||
from lutris.gui.dialogs.delegates import LaunchUIDelegate, InstallUIDelegate, CommandLineUIDelegate
|
||||
from lutris.gui.installerwindow import InstallerWindow, InstallationKind
|
||||
from lutris.gui.widgets.status_icon import LutrisStatusIcon
|
||||
from lutris.migrations import migrate
|
||||
|
@ -53,7 +54,6 @@ from lutris.util.steam.appmanifest import AppManifest, get_appmanifests
|
|||
from lutris.util.steam.config import get_steamapps_paths
|
||||
from lutris.services import get_enabled_services
|
||||
from lutris.database.services import ServiceGameCollection
|
||||
from lutris.runners.runner import Runner
|
||||
|
||||
from .lutriswindow import LutrisWindow
|
||||
|
||||
|
@ -78,8 +78,8 @@ class Application(Gtk.Application):
|
|||
self.force_updates = False
|
||||
self.css_provider = Gtk.CssProvider.new()
|
||||
self.window = None
|
||||
self.launch_ui_delegate = Game.LaunchUIDelegate()
|
||||
self.install_ui_delegate = Runner.InstallUIDelegate()
|
||||
self.launch_ui_delegate = LaunchUIDelegate()
|
||||
self.install_ui_delegate = InstallUIDelegate()
|
||||
|
||||
self.running_games = Gio.ListStore.new(Game)
|
||||
self.app_windows = {}
|
||||
|
@ -974,23 +974,3 @@ Also, check that the version specified is in the correct format.
|
|||
|
||||
def has_tray_icon(self):
|
||||
return self.tray and self.tray.is_visible()
|
||||
|
||||
|
||||
class CommandLineUIDelegate(Game.LaunchUIDelegate):
|
||||
"""This delegate can provide user selections that were provided on the command line."""
|
||||
|
||||
def __init__(self, launch_config_name):
|
||||
self.launch_config_name = launch_config_name
|
||||
|
||||
def select_game_launch_config(self, game):
|
||||
if not self.launch_config_name:
|
||||
return {}
|
||||
|
||||
game_config = game.config.game_level.get("game", {})
|
||||
configs = game_config.get("launch_configs")
|
||||
|
||||
for config in configs:
|
||||
if config.get("name") == self.launch_config_name:
|
||||
return config
|
||||
|
||||
raise RuntimeError("The launch configuration '%s' could not be found." % self.launch_config_name)
|
||||
|
|
|
@ -2,15 +2,109 @@ from gettext import gettext as _
|
|||
|
||||
from gi.repository import Gdk, Gtk
|
||||
|
||||
from lutris.exceptions import UnavailableRunnerError
|
||||
from lutris.game import Game
|
||||
from lutris.gui import dialogs
|
||||
from lutris.gui.dialogs.download import DownloadDialog
|
||||
from lutris.runners import wine
|
||||
from lutris.runners.runner import Runner
|
||||
from lutris.util.downloader import Downloader
|
||||
|
||||
|
||||
class DialogInstallUIDelegate(Runner.InstallUIDelegate):
|
||||
class LaunchUIDelegate:
|
||||
"""These objects provide UI for the game while it is being launched;
|
||||
one provided to the launch() method.
|
||||
|
||||
The default implementation provides no UI and makes default choices for
|
||||
the user, but DialogLaunchUIDelegate implements this to show dialogs and ask the
|
||||
user questions. Windows then inherit from DialogLaunchUIDelegate.
|
||||
|
||||
If these methods throw any errors are reported via tha game-error signal;
|
||||
that is not part of this delegate because errors can be report outside of
|
||||
the launch() method, where no delegate is available.
|
||||
"""
|
||||
|
||||
def check_game_launchable(self, game):
|
||||
"""See if the game can be launched. If there are adverse conditions,
|
||||
this can warn the user and ask whether to launch. If this returs
|
||||
False, the launch is cancelled. The default is to return True with no
|
||||
actual checks.
|
||||
"""
|
||||
if not game.runner.is_installed():
|
||||
raise UnavailableRunnerError("The required runner '%s' is not installed." % game.runner.name)
|
||||
return True
|
||||
|
||||
def select_game_launch_config(self, game):
|
||||
"""Prompt the user for which launch config to use. Returns None
|
||||
if the user cancelled, an empty dict for the primary game configuration
|
||||
and the launch_config as a dict if one is selected.
|
||||
|
||||
The default is the select the primary game.
|
||||
"""
|
||||
return {} # primary game
|
||||
|
||||
|
||||
class InstallUIDelegate:
|
||||
"""These objects provide UI for a runner as it is installing itself.
|
||||
One of these must be provided to the install() method.
|
||||
|
||||
The default implementation provides no UI and makes default choices for
|
||||
the user, but DialogInstallUIDelegate implements this to show dialogs and
|
||||
ask the user questions. Windows then inherit from DialogLaunchUIDelegate.
|
||||
"""
|
||||
|
||||
def show_install_yesno_inquiry(self, question, title):
|
||||
"""Called to ask the user a yes/no question.
|
||||
|
||||
The default is 'yes'."""
|
||||
return True
|
||||
|
||||
def show_install_file_inquiry(self, question, title, message):
|
||||
"""Called to ask the user for a file.
|
||||
|
||||
Lutris first asks the user the question given (showing the title);
|
||||
if the user answers 'Yes', it asks for the file using the message.
|
||||
|
||||
Returns None if the user answers 'No' or cancels out. Returns the
|
||||
file path if the user selected one.
|
||||
|
||||
The default is to return None always.
|
||||
"""
|
||||
return None
|
||||
|
||||
def download_install_file(self, url, destination):
|
||||
"""Downloads a file from a URL to a destination, overwriting any
|
||||
file at that path.
|
||||
|
||||
Returns True if sucessful, and False if the user cancels.
|
||||
|
||||
The default is to download with no UI, and no option to cancel.
|
||||
"""
|
||||
downloader = Downloader(url, destination, overwrite=True)
|
||||
downloader.start()
|
||||
return downloader.join()
|
||||
|
||||
|
||||
class CommandLineUIDelegate(LaunchUIDelegate):
|
||||
"""This delegate can provide user selections that were provided on the command line."""
|
||||
|
||||
def __init__(self, launch_config_name):
|
||||
self.launch_config_name = launch_config_name
|
||||
|
||||
def select_game_launch_config(self, game):
|
||||
if not self.launch_config_name:
|
||||
return {}
|
||||
|
||||
game_config = game.config.game_level.get("game", {})
|
||||
configs = game_config.get("launch_configs")
|
||||
|
||||
for config in configs:
|
||||
if config.get("name") == self.launch_config_name:
|
||||
return config
|
||||
|
||||
raise RuntimeError("The launch configuration '%s' could not be found." % self.launch_config_name)
|
||||
|
||||
|
||||
class DialogInstallUIDelegate(InstallUIDelegate):
|
||||
"""This provides UI for runner installation via dialogs."""
|
||||
|
||||
def show_install_yesno_inquiry(self, question, title):
|
||||
|
@ -37,7 +131,7 @@ class DialogInstallUIDelegate(Runner.InstallUIDelegate):
|
|||
return dialog.downloader.state == Downloader.COMPLETED
|
||||
|
||||
|
||||
class DialogLaunchUIDelegate(Game.LaunchUIDelegate):
|
||||
class DialogLaunchUIDelegate(LaunchUIDelegate):
|
||||
"""This provides UI for game launch via dialogs."""
|
||||
|
||||
def check_game_launchable(self, game):
|
||||
|
|
|
@ -10,7 +10,6 @@ from lutris.database.games import get_game_by_field
|
|||
from lutris.exceptions import GameConfigError, UnavailableLibrariesError
|
||||
from lutris.runners import RunnerInstallationError
|
||||
from lutris.util import flatpak, strings, system
|
||||
from lutris.util.downloader import Downloader
|
||||
from lutris.util.extract import ExtractFailure, extract_archive
|
||||
from lutris.util.http import HTTPError, Request
|
||||
from lutris.util.linux import LINUX_SYSTEM
|
||||
|
@ -35,46 +34,6 @@ class Runner: # pylint: disable=too-many-public-methods
|
|||
arch = None # If the runner is only available for an architecture that isn't x86_64
|
||||
flatpak_id = None
|
||||
|
||||
class InstallUIDelegate:
|
||||
"""These objects provide UI for a runner as it is installing itself.
|
||||
One of these must be provided to the install() method.
|
||||
|
||||
The default implementation provides no UI and makes default choices for
|
||||
the user, but DialogInstallUIDelegate implements this to show dialogs and
|
||||
ask the user questions. Windows then inherit from DialogLaunchUIDelegate.
|
||||
"""
|
||||
|
||||
def show_install_yesno_inquiry(self, question, title):
|
||||
"""Called to ask the user a yes/no question.
|
||||
|
||||
The default is 'yes'."""
|
||||
return True
|
||||
|
||||
def show_install_file_inquiry(self, question, title, message):
|
||||
"""Called to ask the user for a file.
|
||||
|
||||
Lutris first asks the user the question given (showing the title);
|
||||
if the user answers 'Yes', it asks for the file using the message.
|
||||
|
||||
Returns None if the user answers 'No' or cancels out. Returns the
|
||||
file path if the user selected one.
|
||||
|
||||
The default is to return None always.
|
||||
"""
|
||||
return None
|
||||
|
||||
def download_install_file(self, url, destination):
|
||||
"""Downloads a file from a URL to a destination, overwriting any
|
||||
file at that path.
|
||||
|
||||
Returns True if sucessful, and False if the user cancels.
|
||||
|
||||
The default is to download with no UI, and no option to cancel.
|
||||
"""
|
||||
downloader = Downloader(url, destination, overwrite=True)
|
||||
downloader.start()
|
||||
return downloader.join()
|
||||
|
||||
def __init__(self, config=None):
|
||||
"""Initialize runner."""
|
||||
if config:
|
||||
|
@ -222,6 +181,7 @@ class Runner: # pylint: disable=too-many-public-methods
|
|||
return [exe]
|
||||
if flatpak.is_app_installed(self.flatpak_id):
|
||||
return flatpak.get_run_command(self.flatpak_id)
|
||||
return []
|
||||
|
||||
def get_env(self, os_env=False, disable_runtime=False):
|
||||
"""Return environment variables used for a game."""
|
||||
|
|
|
@ -50,7 +50,7 @@ class TestPCSX2Runner(unittest.TestCase):
|
|||
mock_config.game_config = {'main_file': main_file}
|
||||
mock_config.runner_config = {'nogui': True}
|
||||
self.runner.config = mock_config
|
||||
expected = {'command': [self.runner.get_executable(), '-nogui', main_file]}
|
||||
expected = {'command': self.runner.get_command() + ['-nogui', main_file]}
|
||||
self.assertEqual(self.runner.play(), expected)
|
||||
|
||||
@patch('lutris.util.system.path_exists')
|
||||
|
|
Loading…
Reference in a new issue