Created source subclass, improved RetroArch exec

Steam RetroArch still not working on my machine.
This commit is contained in:
GeoffreyCoulaud
2023-08-13 18:13:17 +02:00
parent 0599a61057
commit c2c998adcd
4 changed files with 63 additions and 17 deletions

View File

@@ -26,7 +26,7 @@ from gi.repository import GLib, Gtk
from src import shared from src import shared
from src.game import Game from src.game import Game
from src.importer.sources.location import Location, LocationSubPath from src.importer.sources.location import Location, LocationSubPath
from src.importer.sources.source import Source, SourceIterable from src.importer.sources.source import ExecutableFormatSource, SourceIterable
class FlatpakSourceIterable(SourceIterable): class FlatpakSourceIterable(SourceIterable):
@@ -116,7 +116,7 @@ class FlatpakLocations(NamedTuple):
data: Location data: Location
class FlatpakSource(Source): class FlatpakSource(ExecutableFormatSource):
"""Generic Flatpak source""" """Generic Flatpak source"""
source_id = "flatpak" source_id = "flatpak"

View File

@@ -26,7 +26,11 @@ from typing import NamedTuple
from src import shared from src import shared
from src.game import Game from src.game import Game
from src.importer.sources.location import Location, LocationSubPath from src.importer.sources.location import Location, LocationSubPath
from src.importer.sources.source import Source, SourceIterationResult, SourceIterable from src.importer.sources.source import (
ExecutableFormatSource,
SourceIterationResult,
SourceIterable,
)
class LegendarySourceIterable(SourceIterable): class LegendarySourceIterable(SourceIterable):
@@ -93,7 +97,7 @@ class LegendaryLocations(NamedTuple):
config: Location config: Location
class LegendarySource(Source): class LegendarySource(ExecutableFormatSource):
source_id = "legendary" source_id = "legendary"
name = _("Legendary") name = _("Legendary")
executable_format = "legendary launch {app_name}" executable_format = "legendary launch {app_name}"

View File

@@ -26,6 +26,8 @@ from pathlib import Path
from time import time from time import time
from typing import NamedTuple from typing import NamedTuple
from urllib.parse import quote
from src import shared from src import shared
from src.errors.friendly_error import FriendlyError from src.errors.friendly_error import FriendlyError
from src.game import Game from src.game import Game
@@ -103,7 +105,7 @@ class RetroarchSourceIterable(SourceIterable):
"added": added_time, "added": added_time,
"name": item["label"], "name": item["label"],
"game_id": self.source.game_id_format.format(game_id=game_id), "game_id": self.source.game_id_format.format(game_id=game_id),
"executable": self.source.executable_format.format( "executable": self.source.make_executable(
rom_path=item["path"], rom_path=item["path"],
core_path=core_path, core_path=core_path,
), ),
@@ -168,14 +170,6 @@ class RetroarchSource(Source):
) )
) )
@property
def executable_format(self):
self.locations.config.resolve()
is_flatpak = self.locations.config.root.is_relative_to(shared.flatpak_dir)
base = "flatpak run org.libretro.RetroArch" if is_flatpak else "retroarch"
args = '-L "{core_path}" "{rom_path}"'
return f"{base} {args}"
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
try: try:
@@ -214,3 +208,36 @@ class RetroarchSource(Source):
return Path(f"{library_path}/steamapps/common/RetroArch") return Path(f"{library_path}/steamapps/common/RetroArch")
# Not found # Not found
raise ValueError("RetroArch not found in Steam library") raise ValueError("RetroArch not found in Steam library")
def make_executable(self, rom_path: Path, core_path: Path) -> str:
"""
Generate an executable command from the rom path and core path,
depending on the source's location.
The format depends on RetroArch's installation method,
detected from the source config location
:param Path rom_path: the game's rom path
:param Path core_path: the game's core path
:return str: an executable command
"""
self.locations.config.resolve()
args = f'-L "{core_path}" "{rom_path}"'
# Steam RetroArch
# (Must check before Flatpak, because Steam itself can be installed as one)
if self.locations.config.root.parent.parent.name == "steamapps":
uri = "steam://run/1118310//" + quote(args) + "/"
return f"xdg-open {uri}"
# Flatpak RetroArch
if self.locations.config.root.is_relative_to(shared.flatpak_dir):
return f"flatpak run org.libretro.RetroArch {args}"
# TODO executable override for non-sandboxed sources
# Linux native RetroArch
return f"retroarch {args}"
# TODO implement for windows (needs override)

View File

@@ -75,10 +75,12 @@ class Source(Iterable):
def is_available(self): def is_available(self):
return sys.platform in self.available_on return sys.platform in self.available_on
@property
@abstractmethod @abstractmethod
def executable_format(self) -> str: def make_executable(self, *args, **kwargs) -> str:
"""The executable format used to construct game executables""" """
Create a game executable command.
Should be implemented by child classes.
"""
def __iter__(self) -> Generator[SourceIterationResult, None, None]: def __iter__(self) -> Generator[SourceIterationResult, None, None]:
""" """
@@ -93,8 +95,21 @@ class Source(Iterable):
return iter(self.iterable_class(self)) return iter(self.iterable_class(self))
class ExecutableFormatSource(Source):
"""Source class that uses a simple executable format to start games"""
@property
@abstractmethod
def executable_format(self) -> str:
"""The executable format used to construct game executables"""
def make_executable(self, *args, **kwargs) -> str:
"""Use the executable format to"""
return self.executable_format.format(args, kwargs)
# pylint: disable=abstract-method # pylint: disable=abstract-method
class URLExecutableSource(Source): class URLExecutableSource(ExecutableFormatSource):
"""Source class that use custom URLs to start games""" """Source class that use custom URLs to start games"""
url_format: str url_format: str