bauiv1lib.connectivity

UI functionality related to master-server connectivity.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI functionality related to master-server connectivity."""
  4
  5from __future__ import annotations
  6
  7import time
  8from typing import TYPE_CHECKING
  9
 10import bauiv1 as bui
 11
 12if TYPE_CHECKING:
 13    from typing import Callable, Any
 14
 15
 16def wait_for_connectivity(
 17    on_connected: Callable[[], Any],
 18    on_cancel: Callable[[], Any] | None = None,
 19) -> None:
 20    """Wait for the engine to establish a master-server connection.
 21
 22    If need be, shows a window to keep the user informed of connectivity
 23    state and allows the user to cancel the operation. Note that canceling
 24    does not prevent the engine from continuing its attempt to establish
 25    connectivity; it simply cancels the operation that depends on it.
 26    """
 27    plus = bui.app.plus
 28    assert plus is not None
 29
 30    # Quick-out: if we're already connected, don't bother with the UI.
 31    if plus.cloud.connected:
 32        on_connected()
 33        return
 34
 35    WaitForConnectivityWindow(on_connected=on_connected, on_cancel=on_cancel)
 36
 37
 38class WaitForConnectivityWindow(bui.Window):
 39    """Window informing the user that the game is establishing connectivity."""
 40
 41    def __init__(
 42        self,
 43        on_connected: Callable[[], Any],
 44        on_cancel: Callable[[], Any] | None,
 45    ) -> None:
 46        self._on_connected = on_connected
 47        self._on_cancel = on_cancel
 48        self._width = 650
 49        self._height = 300
 50        self._infos: list[str | bui.Lstr] = [
 51            'This can take a few moments, especially on first launch.',
 52            'Make sure your internet connection is working.',
 53        ]
 54        self._last_info_switch_time = time.monotonic()
 55        self._info_index = 0
 56        super().__init__(
 57            root_widget=bui.containerwidget(
 58                size=(self._width, self._height),
 59                transition='in_scale',
 60                parent=bui.get_special_widget('overlay_stack'),
 61            )
 62        )
 63        bui.textwidget(
 64            parent=self._root_widget,
 65            position=(self._width * 0.5, self._height * 0.65),
 66            size=(0, 0),
 67            scale=1.2,
 68            h_align='center',
 69            v_align='center',
 70            text='Locating nearest regional servers...',
 71            maxwidth=self._width * 0.9,
 72        )
 73        self._info_text = bui.textwidget(
 74            parent=self._root_widget,
 75            position=(self._width * 0.5, self._height * 0.45),
 76            size=(0, 0),
 77            color=(0.7, 0.6, 0.7),
 78            flatness=1.0,
 79            scale=0.8,
 80            h_align='center',
 81            v_align='center',
 82            text=self._infos[0],
 83            maxwidth=self._width * 0.9,
 84        )
 85        cancel_button = bui.buttonwidget(
 86            parent=self._root_widget,
 87            autoselect=True,
 88            position=(50, 30),
 89            size=(150, 50),
 90            label=bui.Lstr(resource='cancelText'),
 91            on_activate_call=self._cancel,
 92        )
 93        bui.containerwidget(edit=self._root_widget, cancel_button=cancel_button)
 94        self._update_timer = bui.AppTimer(
 95            0.113, bui.WeakCall(self._update), repeat=True
 96        )
 97
 98    def _update(self) -> None:
 99        now = time.monotonic()
100
101        plus = bui.app.plus
102        assert plus is not None
103
104        if plus.cloud.connected:
105            self._connected()
106            return
107
108        if now - self._last_info_switch_time > 5.0:
109            self._info_index = (self._info_index + 1) % len(self._infos)
110            bui.textwidget(
111                edit=self._info_text, text=self._infos[self._info_index]
112            )
113            self._last_info_switch_time = now
114
115    def _connected(self) -> None:
116        if not self._root_widget or self._root_widget.transitioning_out:
117            return
118        bui.containerwidget(
119            edit=self._root_widget,
120            transition=('out_scale'),
121        )
122        bui.pushcall(self._on_connected)
123
124    def _cancel(self) -> None:
125        if not self._root_widget or self._root_widget.transitioning_out:
126            return
127        bui.containerwidget(
128            edit=self._root_widget,
129            transition=('out_scale'),
130        )
131        if self._on_cancel is not None:
132            bui.pushcall(self._on_cancel)
def wait_for_connectivity( on_connected: Callable[[], Any], on_cancel: Optional[Callable[[], Any]] = None) -> None:
17def wait_for_connectivity(
18    on_connected: Callable[[], Any],
19    on_cancel: Callable[[], Any] | None = None,
20) -> None:
21    """Wait for the engine to establish a master-server connection.
22
23    If need be, shows a window to keep the user informed of connectivity
24    state and allows the user to cancel the operation. Note that canceling
25    does not prevent the engine from continuing its attempt to establish
26    connectivity; it simply cancels the operation that depends on it.
27    """
28    plus = bui.app.plus
29    assert plus is not None
30
31    # Quick-out: if we're already connected, don't bother with the UI.
32    if plus.cloud.connected:
33        on_connected()
34        return
35
36    WaitForConnectivityWindow(on_connected=on_connected, on_cancel=on_cancel)

Wait for the engine to establish a master-server connection.

If need be, shows a window to keep the user informed of connectivity state and allows the user to cancel the operation. Note that canceling does not prevent the engine from continuing its attempt to establish connectivity; it simply cancels the operation that depends on it.

class WaitForConnectivityWindow(bauiv1._uitypes.Window):
 39class WaitForConnectivityWindow(bui.Window):
 40    """Window informing the user that the game is establishing connectivity."""
 41
 42    def __init__(
 43        self,
 44        on_connected: Callable[[], Any],
 45        on_cancel: Callable[[], Any] | None,
 46    ) -> None:
 47        self._on_connected = on_connected
 48        self._on_cancel = on_cancel
 49        self._width = 650
 50        self._height = 300
 51        self._infos: list[str | bui.Lstr] = [
 52            'This can take a few moments, especially on first launch.',
 53            'Make sure your internet connection is working.',
 54        ]
 55        self._last_info_switch_time = time.monotonic()
 56        self._info_index = 0
 57        super().__init__(
 58            root_widget=bui.containerwidget(
 59                size=(self._width, self._height),
 60                transition='in_scale',
 61                parent=bui.get_special_widget('overlay_stack'),
 62            )
 63        )
 64        bui.textwidget(
 65            parent=self._root_widget,
 66            position=(self._width * 0.5, self._height * 0.65),
 67            size=(0, 0),
 68            scale=1.2,
 69            h_align='center',
 70            v_align='center',
 71            text='Locating nearest regional servers...',
 72            maxwidth=self._width * 0.9,
 73        )
 74        self._info_text = bui.textwidget(
 75            parent=self._root_widget,
 76            position=(self._width * 0.5, self._height * 0.45),
 77            size=(0, 0),
 78            color=(0.7, 0.6, 0.7),
 79            flatness=1.0,
 80            scale=0.8,
 81            h_align='center',
 82            v_align='center',
 83            text=self._infos[0],
 84            maxwidth=self._width * 0.9,
 85        )
 86        cancel_button = bui.buttonwidget(
 87            parent=self._root_widget,
 88            autoselect=True,
 89            position=(50, 30),
 90            size=(150, 50),
 91            label=bui.Lstr(resource='cancelText'),
 92            on_activate_call=self._cancel,
 93        )
 94        bui.containerwidget(edit=self._root_widget, cancel_button=cancel_button)
 95        self._update_timer = bui.AppTimer(
 96            0.113, bui.WeakCall(self._update), repeat=True
 97        )
 98
 99    def _update(self) -> None:
100        now = time.monotonic()
101
102        plus = bui.app.plus
103        assert plus is not None
104
105        if plus.cloud.connected:
106            self._connected()
107            return
108
109        if now - self._last_info_switch_time > 5.0:
110            self._info_index = (self._info_index + 1) % len(self._infos)
111            bui.textwidget(
112                edit=self._info_text, text=self._infos[self._info_index]
113            )
114            self._last_info_switch_time = now
115
116    def _connected(self) -> None:
117        if not self._root_widget or self._root_widget.transitioning_out:
118            return
119        bui.containerwidget(
120            edit=self._root_widget,
121            transition=('out_scale'),
122        )
123        bui.pushcall(self._on_connected)
124
125    def _cancel(self) -> None:
126        if not self._root_widget or self._root_widget.transitioning_out:
127            return
128        bui.containerwidget(
129            edit=self._root_widget,
130            transition=('out_scale'),
131        )
132        if self._on_cancel is not None:
133            bui.pushcall(self._on_cancel)

Window informing the user that the game is establishing connectivity.

WaitForConnectivityWindow( on_connected: Callable[[], Any], on_cancel: Optional[Callable[[], Any]])
42    def __init__(
43        self,
44        on_connected: Callable[[], Any],
45        on_cancel: Callable[[], Any] | None,
46    ) -> None:
47        self._on_connected = on_connected
48        self._on_cancel = on_cancel
49        self._width = 650
50        self._height = 300
51        self._infos: list[str | bui.Lstr] = [
52            'This can take a few moments, especially on first launch.',
53            'Make sure your internet connection is working.',
54        ]
55        self._last_info_switch_time = time.monotonic()
56        self._info_index = 0
57        super().__init__(
58            root_widget=bui.containerwidget(
59                size=(self._width, self._height),
60                transition='in_scale',
61                parent=bui.get_special_widget('overlay_stack'),
62            )
63        )
64        bui.textwidget(
65            parent=self._root_widget,
66            position=(self._width * 0.5, self._height * 0.65),
67            size=(0, 0),
68            scale=1.2,
69            h_align='center',
70            v_align='center',
71            text='Locating nearest regional servers...',
72            maxwidth=self._width * 0.9,
73        )
74        self._info_text = bui.textwidget(
75            parent=self._root_widget,
76            position=(self._width * 0.5, self._height * 0.45),
77            size=(0, 0),
78            color=(0.7, 0.6, 0.7),
79            flatness=1.0,
80            scale=0.8,
81            h_align='center',
82            v_align='center',
83            text=self._infos[0],
84            maxwidth=self._width * 0.9,
85        )
86        cancel_button = bui.buttonwidget(
87            parent=self._root_widget,
88            autoselect=True,
89            position=(50, 30),
90            size=(150, 50),
91            label=bui.Lstr(resource='cancelText'),
92            on_activate_call=self._cancel,
93        )
94        bui.containerwidget(edit=self._root_widget, cancel_button=cancel_button)
95        self._update_timer = bui.AppTimer(
96            0.113, bui.WeakCall(self._update), repeat=True
97        )
Inherited Members
bauiv1._uitypes.Window
get_root_widget