mirror of
https://github.com/lutris/lutris
synced 2024-10-02 22:14:23 +00:00
Replace game filter with more efficient version.
This will just leave the list alone if 'Installed games only' is off and the filter text is empty. Also, it no longer strips the filter text over and over again, but just once at the start. It still has to strip each game name, but it's half the strippings now. Also, fix some ruff issues.
This commit is contained in:
parent
7689a74660
commit
44c2419ac1
|
@ -408,19 +408,30 @@ class LutrisWindow(Gtk.ApplicationWindow, DialogLaunchUIDelegate, DialogInstallU
|
|||
def get_recent_games(self):
|
||||
"""Return a list of currently running games"""
|
||||
games = games_db.get_games(filters={"installed": "1"})
|
||||
games = [game for game in games if self.game_matches(game)]
|
||||
games = self.filter_games(games)
|
||||
return sorted(games, key=lambda game: max(game["installed_at"] or 0, game["lastplayed"] or 0), reverse=True)
|
||||
|
||||
def game_matches(self, game):
|
||||
if self.filters.get("installed"):
|
||||
if "appid" in game and game["appid"] not in games_db.get_service_games(self.service.id):
|
||||
return False
|
||||
def filter_games(self, games):
|
||||
"""Filters a list of games according to the 'installed' and 'text' filters, if those are
|
||||
set. But if not, can just return games unchanged."""
|
||||
installed = bool(self.filters.get("installed"))
|
||||
text = self.filters.get("text")
|
||||
if not text:
|
||||
return True
|
||||
text = strip_accents(text).casefold()
|
||||
name = strip_accents(game["name"]).casefold()
|
||||
return text in name
|
||||
if text:
|
||||
text = strip_accents(text).casefold()
|
||||
|
||||
def game_matches(game):
|
||||
if installed:
|
||||
if "appid" in game and game["appid"] not in games_db.get_service_games(self.service.id):
|
||||
return False
|
||||
if not text:
|
||||
return True
|
||||
name = strip_accents(game["name"]).casefold()
|
||||
return text in name
|
||||
|
||||
if installed or text:
|
||||
return [game for game in games if game_matches(game)]
|
||||
|
||||
return games
|
||||
|
||||
def set_service(self, service_name):
|
||||
if self.service and self.service.id == service_name:
|
||||
|
@ -451,11 +462,12 @@ class LutrisWindow(Gtk.ApplicationWindow, DialogLaunchUIDelegate, DialogInstallU
|
|||
else:
|
||||
lutris_games = {g["service_id"]: g for g in games_db.get_games(filters={"service": self.service.id})}
|
||||
|
||||
return [
|
||||
self.combine_games(game, lutris_games.get(game["appid"]))
|
||||
for game in self.apply_view_sort(service_games, lambda game: lutris_games.get(game["appid"]) or game)
|
||||
if self.game_matches(game)
|
||||
]
|
||||
return self.filter_games(
|
||||
[
|
||||
self.combine_games(game, lutris_games.get(game["appid"]))
|
||||
for game in self.apply_view_sort(service_games, lambda game: lutris_games.get(game["appid"]) or game)
|
||||
]
|
||||
)
|
||||
|
||||
def get_games_from_filters(self):
|
||||
service_id = self.filters.get("service")
|
||||
|
@ -474,7 +486,7 @@ class LutrisWindow(Gtk.ApplicationWindow, DialogLaunchUIDelegate, DialogInstallU
|
|||
|
||||
filters = self.get_sql_filters()
|
||||
games = games_db.get_games(filters=filters)
|
||||
games = [game for game in games if game["id"] in category_game_ids and self.game_matches(game)]
|
||||
games = self.filter_games([game for game in games if game["id"] in category_game_ids])
|
||||
return self.apply_view_sort(games)
|
||||
|
||||
def get_sql_filters(self):
|
||||
|
@ -488,7 +500,7 @@ class LutrisWindow(Gtk.ApplicationWindow, DialogLaunchUIDelegate, DialogInstallU
|
|||
sql_filters["installed"] = "1"
|
||||
|
||||
# We omit the "text" search here because SQLite does a fairly literal
|
||||
# search, which is accent sensitive. We'll do better with self.game_matches()
|
||||
# search, which is accent sensitive. We'll do better with self.filter_games()
|
||||
return sql_filters
|
||||
|
||||
def get_service_media(self, icon_type):
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
from lutris.exceptions import MissingGameExecutableError
|
||||
from lutris.runners.runner import Runner
|
||||
from lutris.util import system
|
||||
from lutris.util.log import logger
|
||||
|
||||
|
||||
class MissingVitaTitleIDError(MissingGameExecutableError):
|
||||
"""Raise when the Title ID field has not be supplied to the Vita runner game options"""
|
||||
|
@ -30,7 +28,10 @@ class vita3k(Runner):
|
|||
"type": "string",
|
||||
"label": _("Title ID of Installed Application"),
|
||||
"argument": "-r",
|
||||
"help": _("Title ID of installed application. Eg.\"PCSG00042\". User installed apps are located in ux0:/app/<title-id>."),
|
||||
"help": _(
|
||||
'Title ID of installed application. Eg."PCSG00042". User installed apps are located in '
|
||||
"ux0:/app/<title-id>."
|
||||
),
|
||||
}
|
||||
]
|
||||
runner_options = [
|
||||
|
@ -47,14 +48,17 @@ class vita3k(Runner):
|
|||
"type": "file",
|
||||
"label": _("Config location"),
|
||||
"argument": "-c",
|
||||
"help": _("Get a configuration file from a given location. If a filename is given, it must end with \".yml\", otherwise it will be assumed to be a directory."),
|
||||
"help": _(
|
||||
'Get a configuration file from a given location. If a filename is given, it must end with ".yml", '
|
||||
"otherwise it will be assumed to be a directory."
|
||||
),
|
||||
},
|
||||
{
|
||||
"option": "load-config",
|
||||
"label": _("Load configuration file"),
|
||||
"type": "bool",
|
||||
"argument": "-f",
|
||||
"help": _("If trues, informs the emualtor to load the config file from the \"Config location\" option.")
|
||||
"help": _('If trues, informs the emualtor to load the config file from the "Config location" option.'),
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -72,15 +76,15 @@ class vita3k(Runner):
|
|||
continue
|
||||
if option["type"] == "bool":
|
||||
if self.runner_config.get(option["option"]):
|
||||
if 'argument' in option:
|
||||
if "argument" in option:
|
||||
arguments.append(option["argument"])
|
||||
elif option["type"] == "choice":
|
||||
if self.runner_config.get(option["option"]) != "off":
|
||||
if 'argument' in option:
|
||||
if "argument" in option:
|
||||
arguments.append(option["argument"])
|
||||
arguments.append(config.get(option["option"]))
|
||||
elif option["type"] in ("string", "file"):
|
||||
if 'argument' in option:
|
||||
if "argument" in option:
|
||||
arguments.append(option["argument"])
|
||||
arguments.append(config.get(option["option"]))
|
||||
else:
|
||||
|
@ -98,4 +102,4 @@ class vita3k(Runner):
|
|||
|
||||
@property
|
||||
def game_path(self):
|
||||
return self.game_config.get(self.entry_point_option, '')
|
||||
return self.game_config.get(self.entry_point_option, "")
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import unittest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from lutris.runners.vita3k import MissingVitaTitleIDError
|
||||
from lutris.runners.vita3k import vita3k
|
||||
from lutris.runners.vita3k import MissingVitaTitleIDError, vita3k
|
||||
|
||||
|
||||
class TestVita3kRunner(unittest.TestCase):
|
||||
|
@ -19,7 +18,7 @@ class TestVita3kRunner(unittest.TestCase):
|
|||
mock_config.game_config = {"main_file": main_file}
|
||||
mock_config.runner_config = MagicMock()
|
||||
self.runner.config = mock_config
|
||||
with self.assertRaises(MissingVitaTitleIDError) as cm:
|
||||
with self.assertRaises(MissingVitaTitleIDError):
|
||||
self.runner.play()
|
||||
|
||||
@patch("lutris.util.system.path_exists")
|
||||
|
@ -43,9 +42,7 @@ class TestVita3kRunner(unittest.TestCase):
|
|||
mock_isfile.return_value = True
|
||||
mock_config = MagicMock()
|
||||
mock_config.game_config = {"main_file": main_file}
|
||||
mock_config.runner_config = {
|
||||
"fullscreen": False
|
||||
}
|
||||
mock_config.runner_config = {"fullscreen": False}
|
||||
self.runner.config = mock_config
|
||||
expected = {"command": [self.runner.get_executable(), "-r", main_file]}
|
||||
self.assertEqual(self.runner.play(), expected)
|
||||
|
|
Loading…
Reference in a new issue