Source code for baremote._appmode

# Released under the MIT License. See LICENSE for details.
#
"""Provides the Remote app-mode."""

from __future__ import annotations  # Docs-generation hack.

from typing import TYPE_CHECKING, override

import _baremote
import babase
from babase import AppMode, AppIntentDefault

# The touch controls' art comes from the classic package for now (see
# _make_base_asset_set).
from bauiv1 import _classicassets

from baremote._client import RemoteClient

if TYPE_CHECKING:
    from babase import AppIntent, AppModeConfig


# ba_meta export babase.AppMode
[docs] class RemoteAppMode(AppMode): """The app-mode for using a device as a game controller. This turns a phone or tablet into a controller for a game on the same network; it is the future home of the BombSquad Remote app (in development for 1.9). Currently a placeholder with no ui of its own: it connects to the first game it finds, and while connected the device's touchscreen controls (or a keyboard or gamepad) drive a player in that game. Progress is reported as screen-messages and ``ba.net`` log lines. It is not in the project's default app-modes, so the app never selects it on its own; it can be switched to manually via the dev-console's AppModes tab. """ #: Testing hook -- if set, the client queries only these (address, #: port) pairs instead of broadcasting, so a test run can't latch #: onto some other game on the network. Takes effect on the next #: activation. test_scan_targets: list[tuple[str, int]] | None = None #: Testing hook -- send random presses instead of real input (for #: headless runs, which have no input devices). Takes effect on the #: next activation. test_random_input: bool = False def __init__(self) -> None: super().__init__() self._client: RemoteClient | None = None
[docs] @override @classmethod def can_handle_intent(cls, intent: AppIntent) -> bool: return isinstance(intent, AppIntentDefault)
[docs] @override def handle_intent(self, intent: AppIntent) -> None: assert isinstance(intent, AppIntentDefault)
[docs] @override def on_activate(self, config: AppModeConfig) -> None: del config # Unused. babase.set_base_asset_set(_make_base_asset_set()) _baremote.remote_app_mode_activate() assert self._client is None self._client = RemoteClient( scan_targets=self.test_scan_targets, random_input=self.test_random_input, ) self._client.start()
[docs] @override def on_deactivate(self) -> None: if self._client is not None: self._client.stop() self._client = None _baremote.remote_app_mode_deactivate()
def _make_base_asset_set() -> babase.BaseAssetSet: """Build the art we supply for base's draws: the touch controls. Everything else stays at its engine placeholder (we draw no scenes). This borrows classic's touch-control art; a lean remote app would want it in a small package of its own. """ tex = _classicassets.textures msh = _classicassets.meshes assets = babase.BaseAssetSet() assets.action_buttons = tex.action_buttons assets.touch_arrows = tex.touch_arrows assets.touch_arrows_actions = tex.touch_arrows_actions assets.arrow = tex.arrow assets.action_button_bottom = msh.action_button_bottom assets.action_button_left = msh.action_button_left assets.action_button_right = msh.action_button_right assets.action_button_top = msh.action_button_top assets.arrow_back = msh.arrow_back assets.arrow_front = msh.arrow_front return assets # Docs-generation hack; import some stuff that we likely only forward-declared # in our actual source code so that docs tools can find it. from typing import (Coroutine, Any, Literal, Callable, Generator, Awaitable, Sequence, Self, TypeIs) import asyncio from concurrent.futures import Future from pathlib import Path from enum import Enum