mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-04-17 06:12:33 -05:00
feat: add target_cores filter to resolve_platform_cores
Optional target_cores parameter intersects the resolved core set, enabling per-target filtering without changing existing call sites. Includes 2 E2E tests covering intersection and None pass-through.
This commit is contained in:
@@ -582,29 +582,28 @@ def group_identical_platforms(
|
|||||||
|
|
||||||
def resolve_platform_cores(
|
def resolve_platform_cores(
|
||||||
config: dict, profiles: dict[str, dict],
|
config: dict, profiles: dict[str, dict],
|
||||||
|
target_cores: set[str] | None = None,
|
||||||
) -> set[str]:
|
) -> set[str]:
|
||||||
"""Resolve which emulator profiles are relevant for a platform.
|
"""Resolve which emulator profiles are relevant for a platform.
|
||||||
|
|
||||||
Resolution strategies (by priority):
|
Resolution strategies (by priority):
|
||||||
1. cores: "all_libretro" — all profiles with libretro in type
|
1. cores: "all_libretro" -- all profiles with libretro in type
|
||||||
2. cores: [list] — profiles whose dict key matches a core name
|
2. cores: [list] -- profiles whose dict key matches a core name
|
||||||
3. cores: absent — fallback to systems intersection
|
3. cores: absent -- fallback to systems intersection
|
||||||
|
|
||||||
Alias profiles are always excluded (they point to another profile).
|
Alias profiles are always excluded (they point to another profile).
|
||||||
|
If target_cores is provided, result is intersected with it.
|
||||||
"""
|
"""
|
||||||
cores_config = config.get("cores")
|
cores_config = config.get("cores")
|
||||||
|
|
||||||
if cores_config == "all_libretro":
|
if cores_config == "all_libretro":
|
||||||
return {
|
result = {
|
||||||
name for name, p in profiles.items()
|
name for name, p in profiles.items()
|
||||||
if "libretro" in p.get("type", "")
|
if "libretro" in p.get("type", "")
|
||||||
and p.get("type") != "alias"
|
and p.get("type") != "alias"
|
||||||
}
|
}
|
||||||
|
elif isinstance(cores_config, list):
|
||||||
if isinstance(cores_config, list):
|
|
||||||
core_set = {str(c) for c in cores_config}
|
core_set = {str(c) for c in cores_config}
|
||||||
# Build reverse index: platform core name -> profile name
|
|
||||||
# Uses profile filename (dict key) + all names in cores: field
|
|
||||||
core_to_profile: dict[str, str] = {}
|
core_to_profile: dict[str, str] = {}
|
||||||
for name, p in profiles.items():
|
for name, p in profiles.items():
|
||||||
if p.get("type") == "alias":
|
if p.get("type") == "alias":
|
||||||
@@ -612,19 +611,22 @@ def resolve_platform_cores(
|
|||||||
core_to_profile[name] = name
|
core_to_profile[name] = name
|
||||||
for core_name in p.get("cores", []):
|
for core_name in p.get("cores", []):
|
||||||
core_to_profile[str(core_name)] = name
|
core_to_profile[str(core_name)] = name
|
||||||
return {
|
result = {
|
||||||
core_to_profile[c]
|
core_to_profile[c]
|
||||||
for c in core_set
|
for c in core_set
|
||||||
if c in core_to_profile
|
if c in core_to_profile
|
||||||
}
|
}
|
||||||
|
else:
|
||||||
|
platform_systems = set(config.get("systems", {}).keys())
|
||||||
|
result = {
|
||||||
|
name for name, p in profiles.items()
|
||||||
|
if set(p.get("systems", [])) & platform_systems
|
||||||
|
and p.get("type") != "alias"
|
||||||
|
}
|
||||||
|
|
||||||
# Fallback: system ID intersection
|
if target_cores is not None:
|
||||||
platform_systems = set(config.get("systems", {}).keys())
|
result = result & target_cores
|
||||||
return {
|
return result
|
||||||
name for name, p in profiles.items()
|
|
||||||
if set(p.get("systems", [])) & platform_systems
|
|
||||||
and p.get("type") != "alias"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_validation(validation: list | dict | None) -> list[str]:
|
def _parse_validation(validation: list | dict | None) -> list[str]:
|
||||||
|
|||||||
@@ -1291,6 +1291,33 @@ class TestE2E(unittest.TestCase):
|
|||||||
child,
|
child,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Target filtering in resolve_platform_cores (Task 2)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_target_core_intersection(self):
|
||||||
|
self._write_target_fixtures()
|
||||||
|
profiles = {
|
||||||
|
"core_a": {"type": "libretro", "systems": ["sys1"]},
|
||||||
|
"core_b": {"type": "libretro", "systems": ["sys1"]},
|
||||||
|
"core_c": {"type": "libretro", "systems": ["sys2"]},
|
||||||
|
"core_d": {"type": "libretro", "systems": ["sys2"]},
|
||||||
|
}
|
||||||
|
config = {"cores": "all_libretro"}
|
||||||
|
result = resolve_platform_cores(config, profiles)
|
||||||
|
self.assertEqual(result, {"core_a", "core_b", "core_c", "core_d"})
|
||||||
|
result = resolve_platform_cores(config, profiles, target_cores={"core_a", "core_b"})
|
||||||
|
self.assertEqual(result, {"core_a", "core_b"})
|
||||||
|
|
||||||
|
def test_target_none_no_filter(self):
|
||||||
|
profiles = {
|
||||||
|
"core_a": {"type": "libretro", "systems": ["sys1"]},
|
||||||
|
"core_b": {"type": "libretro", "systems": ["sys1"]},
|
||||||
|
}
|
||||||
|
config = {"cores": "all_libretro"}
|
||||||
|
result = resolve_platform_cores(config, profiles, target_cores=None)
|
||||||
|
self.assertEqual(result, {"core_a", "core_b"})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user