Source code for simvx.graphics.platform

"""Windowing abstraction — auto-detects available backend."""


from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from ._base import WindowBackend

__all__ = ["AVAILABLE_BACKENDS", "get_backend", "resolve_backend"]

_BACKENDS: list[tuple[str, str, str]] = [
    ("glfw", "._glfw", "GlfwBackend"),
    ("sdl3", "._sdl3", "Sdl3Backend"),
    ("qt", "._qt", "QtBackend"),
]

AVAILABLE_BACKENDS: tuple[str, ...] = tuple(name for name, _, _ in _BACKENDS)


[docs] def resolve_backend(name: str | None = None) -> tuple[WindowBackend, str]: """Return a ``(backend, resolved_name)`` pair. If *name* is ``None``, tries each backend in order and returns the first one whose import succeeds along with its name. """ if name is not None: for bname, module, cls in _BACKENDS: if bname == name: import importlib mod = importlib.import_module(module, __package__) return getattr(mod, cls)(), bname raise ValueError(f"Unknown backend: {name!r}. Allowed: {list(AVAILABLE_BACKENDS)}") for bname, module, cls in _BACKENDS: try: import importlib mod = importlib.import_module(module, __package__) backend_cls = getattr(mod, cls) return backend_cls(), bname except (ImportError, ModuleNotFoundError): continue raise RuntimeError("No windowing backend available. Install glfw, PySDL3, or PySide6.")
[docs] def get_backend(name: str | None = None) -> WindowBackend: """Return a windowing backend instance. See :func:`resolve_backend`.""" return resolve_backend(name)[0]