ba_data update

This commit is contained in:
Ayush Saini 2024-01-27 21:25:16 +05:30
parent 2174ae566d
commit 7ba24ecbcf
146 changed files with 1756 additions and 347 deletions

View file

@ -48,6 +48,7 @@ from _babase import (
fatal_error,
get_display_resolution,
get_immediate_return_code,
get_input_idle_time,
get_low_level_config_value,
get_max_graphics_quality,
get_replays_dir,
@ -60,6 +61,7 @@ from _babase import (
have_permission,
in_logic_thread,
increment_analytics_count,
invoke_main_menu,
is_os_playing_music,
is_xcode_build,
lock_all_input,
@ -116,7 +118,6 @@ from babase._apputils import (
get_remote_app_name,
AppHealthMonitor,
)
from babase._cloud import CloudSubsystem
from babase._devconsole import (
DevConsoleTab,
DevConsoleTabEntry,
@ -211,7 +212,6 @@ __all__ = [
'clipboard_has_text',
'clipboard_is_supported',
'clipboard_set_text',
'CloudSubsystem',
'commit_app_config',
'ContextCall',
'ContextError',
@ -235,6 +235,7 @@ __all__ = [
'garbage_collect',
'get_display_resolution',
'get_immediate_return_code',
'get_input_idle_time',
'get_ip_address_type',
'get_low_level_config_value',
'get_max_graphics_quality',
@ -254,6 +255,7 @@ __all__ = [
'increment_analytics_count',
'InputDeviceNotFoundError',
'InputType',
'invoke_main_menu',
'is_browser_likely_available',
'is_browser_likely_available',
'is_os_playing_music',

View file

@ -1,15 +1,17 @@
# Released under the MIT License. See LICENSE for details.
#
# pylint: disable=too-many-lines
"""Functionality related to the high level state of the app."""
from __future__ import annotations
import os
import logging
from enum import Enum
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, TypeVar
from concurrent.futures import ThreadPoolExecutor
from functools import cached_property
from typing_extensions import override
from efro.call import tpartial
import _babase
@ -26,7 +28,7 @@ from babase._devconsole import DevConsoleSubsystem
if TYPE_CHECKING:
import asyncio
from typing import Any, Callable, Coroutine
from typing import Any, Callable, Coroutine, Generator, Awaitable
from concurrent.futures import Future
import babase
@ -42,6 +44,8 @@ if TYPE_CHECKING:
# __FEATURESET_APP_SUBSYSTEM_IMPORTS_END__
T = TypeVar('T')
class App:
"""A class for high level app functionality and state.
@ -124,6 +128,7 @@ class App:
statically in a spinoff project.
"""
@override
def app_mode_for_intent(
self, intent: AppIntent
) -> type[AppMode] | None:
@ -199,7 +204,8 @@ class App:
self._called_on_running = False
self._subsystem_registration_ended = False
self._pending_apply_app_config = False
self._aioloop: asyncio.AbstractEventLoop | None = None
self._asyncio_loop: asyncio.AbstractEventLoop | None = None
self._asyncio_tasks: set[asyncio.Task] = set()
self._asyncio_timer: babase.AppTimer | None = None
self._config: babase.AppConfig | None = None
self._pending_intent: AppIntent | None = None
@ -239,18 +245,68 @@ class App:
return _babase.app_is_active()
@property
def aioloop(self) -> asyncio.AbstractEventLoop:
def asyncio_loop(self) -> asyncio.AbstractEventLoop:
"""The logic thread's asyncio event loop.
This allow async tasks to be run in the logic thread.
Generally you should call App.create_async_task() to schedule
async code to run instead of using this directly. That will
handle retaining the task and logging errors automatically.
Only schedule tasks onto asyncio_loop yourself when you intend
to hold on to the returned task and await its results. Releasing
the task reference can lead to subtle bugs such as unreported
errors and garbage-collected tasks disappearing before their
work is done.
Note that, at this time, the asyncio loop is encapsulated
and explicitly stepped by the engine's logic thread loop and
thus things like asyncio.get_running_loop() will not return this
loop from most places in the logic thread; only from within a
task explicitly created in this loop.
thus things like asyncio.get_running_loop() will unintuitively
*not* return this loop from most places in the logic thread;
only from within a task explicitly created in this loop.
Hopefully this situation will be improved in the future with a
unified event loop.
"""
assert self._aioloop is not None
return self._aioloop
assert _babase.in_logic_thread()
assert self._asyncio_loop is not None
return self._asyncio_loop
def create_async_task(
self,
coro: Generator[Any, Any, T] | Coroutine[Any, Any, T],
*,
name: str | None = None,
) -> None:
"""Create a fully managed async task.
This will automatically retain and release a reference to the task
and log any exceptions that occur in it. If you need to await a task
or otherwise need more control, schedule a task directly using
App.asyncio_loop.
"""
assert _babase.in_logic_thread()
# Hold a strong reference to the task until it is done.
# Otherwise it is possible for it to be garbage collected and
# disappear midway if the caller does not hold on to the
# returned task, which seems like a great way to introduce
# hard-to-track bugs.
task = self.asyncio_loop.create_task(coro, name=name)
self._asyncio_tasks.add(task)
task.add_done_callback(self._on_task_done)
# return task
def _on_task_done(self, task: asyncio.Task) -> None:
# Report any errors that occurred.
try:
exc = task.exception()
if exc is not None:
logging.error(
"Error in async task '%s'.", task.get_name(), exc_info=exc
)
except Exception:
logging.exception('Error reporting async task error.')
self._asyncio_tasks.remove(task)
@property
def config(self) -> babase.AppConfig:
@ -437,6 +493,12 @@ class App:
self._native_shutdown_complete_called = True
self._update_state()
def on_native_active_changed(self) -> None:
"""Called by the native layer when the app active state changes."""
assert _babase.in_logic_thread()
if self._mode is not None:
self._mode.on_app_active_changed()
def read_config(self) -> None:
"""(internal)"""
from babase._appconfig import read_app_config
@ -588,7 +650,7 @@ class App:
_env.on_app_state_initing()
self._aioloop = _asyncio.setup_asyncio()
self._asyncio_loop = _asyncio.setup_asyncio()
self.health_monitor = AppHealthMonitor()
# __FEATURESET_APP_SUBSYSTEM_CREATE_BEGIN__
@ -868,8 +930,8 @@ class App:
)
# Now kick off any async shutdown task(s).
assert self._aioloop is not None
self._shutdown_task = self._aioloop.create_task(self._shutdown())
assert self._asyncio_loop is not None
self._shutdown_task = self._asyncio_loop.create_task(self._shutdown())
def _on_shutdown_complete(self) -> None:
"""(internal)"""

View file

@ -52,3 +52,10 @@ class AppMode:
def on_deactivate(self) -> None:
"""Called when the mode is being deactivated."""
def on_app_active_changed(self) -> None:
"""Called when babase.app.active changes.
The app-mode may want to take action such as pausing a running
game in such cases.
"""

View file

@ -40,16 +40,16 @@ class AppSubsystem:
"""Called when the app reaches the running state."""
def on_app_suspend(self) -> None:
"""Called when the app enters the paused state."""
"""Called when the app enters the suspended state."""
def on_app_unsuspend(self) -> None:
"""Called when the app exits the paused state."""
"""Called when the app exits the suspended state."""
def on_app_shutdown(self) -> None:
"""Called when the app is shutting down."""
"""Called when the app begins shutting down."""
def on_app_shutdown_complete(self) -> None:
"""Called when the app is done shutting down."""
"""Called when the app completes shutting down."""
def do_apply_app_config(self) -> None:
"""Called when the app config should be applied."""

View file

@ -10,9 +10,11 @@ from threading import Thread
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing_extensions import override
from efro.call import tpartial
from efro.log import LogLevel
from efro.dataclassio import ioprepped, dataclass_to_json, dataclass_from_json
import _babase
from babase._appsubsystem import AppSubsystem
@ -386,6 +388,7 @@ class AppHealthMonitor(AppSubsystem):
self._response = False
self._first_check = True
@override
def on_app_loading(self) -> None:
# If any traceback dumps happened last run, log and clear them.
log_dumped_app_state(from_previous_run=True)
@ -449,10 +452,12 @@ class AppHealthMonitor(AppSubsystem):
self._first_check = False
@override
def on_app_suspend(self) -> None:
assert _babase.in_logic_thread()
self._running = False
@override
def on_app_unsuspend(self) -> None:
assert _babase.in_logic_thread()
self._running = True

View file

@ -8,6 +8,8 @@ from typing import TYPE_CHECKING
from dataclasses import dataclass
import logging
from typing_extensions import override
import _babase
if TYPE_CHECKING:
@ -96,6 +98,7 @@ class DevConsoleTab:
class DevConsoleTabPython(DevConsoleTab):
"""The Python dev-console tab."""
@override
def refresh(self) -> None:
self.python_terminal()
@ -103,6 +106,7 @@ class DevConsoleTabPython(DevConsoleTab):
class DevConsoleTabTest(DevConsoleTab):
"""Test dev-console tab."""
@override
def refresh(self) -> None:
import random

View file

@ -5,6 +5,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from bacommon.app import AppExperience
import _babase
@ -18,15 +19,18 @@ if TYPE_CHECKING:
class EmptyAppMode(AppMode):
"""An empty app mode that can be used as a fallback/etc."""
@override
@classmethod
def get_app_experience(cls) -> AppExperience:
return AppExperience.EMPTY
@override
@classmethod
def _supports_intent(cls, intent: AppIntent) -> bool:
# We support default and exec intents currently.
return isinstance(intent, AppIntentExec | AppIntentDefault)
@override
def handle_intent(self, intent: AppIntent) -> None:
if isinstance(intent, AppIntentExec):
_babase.empty_app_mode_handle_intent_exec(intent.code)
@ -34,10 +38,12 @@ class EmptyAppMode(AppMode):
assert isinstance(intent, AppIntentDefault)
_babase.empty_app_mode_handle_intent_default()
@override
def on_activate(self) -> None:
# Let the native layer do its thing.
_babase.on_empty_app_mode_activate()
@override
def on_deactivate(self) -> None:
# Let the native layer do its thing.
_babase.on_empty_app_mode_deactivate()

View file

@ -9,6 +9,7 @@ import logging
import warnings
from typing import TYPE_CHECKING
from typing_extensions import override
from efro.log import LogLevel
if TYPE_CHECKING:
@ -216,6 +217,7 @@ def _feed_logs_to_babase(log_handler: LogHandler) -> None:
class _CustomHelper:
"""Replacement 'help' that behaves better for our setup."""
@override
def __repr__(self) -> str:
return 'Type help(object) for help about object.'

View file

@ -10,6 +10,7 @@ import logging
import inspect
from typing import TYPE_CHECKING, TypeVar, Protocol, NewType
from typing_extensions import override
from efro.terminal import Clr
import _babase
@ -178,6 +179,7 @@ class _WeakCall:
def __call__(self, *args_extra: Any) -> Any:
return self._call(*self._args + args_extra, **self._keywds)
@override
def __str__(self) -> str:
return (
'<ba.WeakCall object; _call='
@ -224,6 +226,7 @@ class _Call:
def __call__(self, *args_extra: Any) -> Any:
return self._call(*self._args + args_extra, **self._keywds)
@override
def __str__(self) -> str:
return (
'<ba.Call object; _call='
@ -268,6 +271,7 @@ class WeakMethod:
return None
return self._func(*((obj,) + args), **keywds)
@override
def __str__(self) -> str:
return '<ba.WeakMethod object; call=' + str(self._func) + '>'

View file

@ -8,6 +8,8 @@ import json
import logging
from typing import TYPE_CHECKING, overload
from typing_extensions import override
import _babase
from babase._appsubsystem import AppSubsystem
@ -217,6 +219,7 @@ class LanguageSubsystem(AppSubsystem):
color=(0, 1, 0),
)
@override
def do_apply_app_config(self) -> None:
assert _babase.in_logic_thread()
assert isinstance(_babase.app.config, dict)
@ -598,9 +601,11 @@ class Lstr:
_error.print_exception('_get_json failed for', self.args)
return 'JSON_ERR'
@override
def __str__(self) -> str:
return '<ba.Lstr: ' + self._get_json() + '>'
@override
def __repr__(self) -> str:
return '<ba.Lstr: ' + self._get_json() + '>'
@ -648,5 +653,6 @@ class AttrDict(dict):
assert not isinstance(val, bytes)
return val
@override
def __setattr__(self, attr: str, value: Any) -> None:
raise AttributeError()

View file

@ -9,6 +9,7 @@ import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING, final
from typing_extensions import override
from bacommon.login import LoginType
import _babase
@ -353,6 +354,7 @@ class LoginAdapterNative(LoginAdapter):
self._sign_in_attempt_num = 123
self._sign_in_attempts: dict[int, Callable[[str | None], None]] = {}
@override
def get_sign_in_token(
self, completion_cb: Callable[[str | None], None]
) -> None:
@ -363,6 +365,7 @@ class LoginAdapterNative(LoginAdapter):
self.login_type.value, attempt_id
)
@override
def on_back_end_active_change(self, active: bool) -> None:
_babase.login_adapter_back_end_active_change(
self.login_type.value, active

View file

@ -26,7 +26,7 @@ EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = {
'plugin': 'babase.Plugin',
# DEPRECATED as of 12/2023. Currently am warning if finding these
# but should take this out eventually.
'keyboard': 'babase.Keyboard',
'keyboard': 'bauiv1.Keyboard',
}
T = TypeVar('T')

View file

@ -149,78 +149,84 @@ class SpecialChar(Enum):
PLAY_PAUSE_BUTTON = 13
FAST_FORWARD_BUTTON = 14
DPAD_CENTER_BUTTON = 15
OUYA_BUTTON_O = 16
OUYA_BUTTON_U = 17
OUYA_BUTTON_Y = 18
OUYA_BUTTON_A = 19
OUYA_LOGO = 20
LOGO = 21
TICKET = 22
GOOGLE_PLAY_GAMES_LOGO = 23
GAME_CENTER_LOGO = 24
DICE_BUTTON1 = 25
DICE_BUTTON2 = 26
DICE_BUTTON3 = 27
DICE_BUTTON4 = 28
GAME_CIRCLE_LOGO = 29
PARTY_ICON = 30
TEST_ACCOUNT = 31
TICKET_BACKING = 32
TROPHY1 = 33
TROPHY2 = 34
TROPHY3 = 35
TROPHY0A = 36
TROPHY0B = 37
TROPHY4 = 38
LOCAL_ACCOUNT = 39
EXPLODINARY_LOGO = 40
FLAG_UNITED_STATES = 41
FLAG_MEXICO = 42
FLAG_GERMANY = 43
FLAG_BRAZIL = 44
FLAG_RUSSIA = 45
FLAG_CHINA = 46
FLAG_UNITED_KINGDOM = 47
FLAG_CANADA = 48
FLAG_INDIA = 49
FLAG_JAPAN = 50
FLAG_FRANCE = 51
FLAG_INDONESIA = 52
FLAG_ITALY = 53
FLAG_SOUTH_KOREA = 54
FLAG_NETHERLANDS = 55
FEDORA = 56
HAL = 57
CROWN = 58
YIN_YANG = 59
EYE_BALL = 60
SKULL = 61
HEART = 62
DRAGON = 63
HELMET = 64
MUSHROOM = 65
NINJA_STAR = 66
VIKING_HELMET = 67
MOON = 68
SPIDER = 69
FIREBALL = 70
FLAG_UNITED_ARAB_EMIRATES = 71
FLAG_QATAR = 72
FLAG_EGYPT = 73
FLAG_KUWAIT = 74
FLAG_ALGERIA = 75
FLAG_SAUDI_ARABIA = 76
FLAG_MALAYSIA = 77
FLAG_CZECH_REPUBLIC = 78
FLAG_AUSTRALIA = 79
FLAG_SINGAPORE = 80
OCULUS_LOGO = 81
STEAM_LOGO = 82
NVIDIA_LOGO = 83
FLAG_IRAN = 84
FLAG_POLAND = 85
FLAG_ARGENTINA = 86
FLAG_PHILIPPINES = 87
FLAG_CHILE = 88
MIKIROG = 89
V2_LOGO = 90
PLAY_STATION_CROSS_BUTTON = 16
PLAY_STATION_CIRCLE_BUTTON = 17
PLAY_STATION_TRIANGLE_BUTTON = 18
PLAY_STATION_SQUARE_BUTTON = 19
PLAY_BUTTON = 20
PAUSE_BUTTON = 21
OUYA_BUTTON_O = 22
OUYA_BUTTON_U = 23
OUYA_BUTTON_Y = 24
OUYA_BUTTON_A = 25
OUYA_LOGO = 26
LOGO = 27
TICKET = 28
GOOGLE_PLAY_GAMES_LOGO = 29
GAME_CENTER_LOGO = 30
DICE_BUTTON1 = 31
DICE_BUTTON2 = 32
DICE_BUTTON3 = 33
DICE_BUTTON4 = 34
GAME_CIRCLE_LOGO = 35
PARTY_ICON = 36
TEST_ACCOUNT = 37
TICKET_BACKING = 38
TROPHY1 = 39
TROPHY2 = 40
TROPHY3 = 41
TROPHY0A = 42
TROPHY0B = 43
TROPHY4 = 44
LOCAL_ACCOUNT = 45
EXPLODINARY_LOGO = 46
FLAG_UNITED_STATES = 47
FLAG_MEXICO = 48
FLAG_GERMANY = 49
FLAG_BRAZIL = 50
FLAG_RUSSIA = 51
FLAG_CHINA = 52
FLAG_UNITED_KINGDOM = 53
FLAG_CANADA = 54
FLAG_INDIA = 55
FLAG_JAPAN = 56
FLAG_FRANCE = 57
FLAG_INDONESIA = 58
FLAG_ITALY = 59
FLAG_SOUTH_KOREA = 60
FLAG_NETHERLANDS = 61
FEDORA = 62
HAL = 63
CROWN = 64
YIN_YANG = 65
EYE_BALL = 66
SKULL = 67
HEART = 68
DRAGON = 69
HELMET = 70
MUSHROOM = 71
NINJA_STAR = 72
VIKING_HELMET = 73
MOON = 74
SPIDER = 75
FIREBALL = 76
FLAG_UNITED_ARAB_EMIRATES = 77
FLAG_QATAR = 78
FLAG_EGYPT = 79
FLAG_KUWAIT = 80
FLAG_ALGERIA = 81
FLAG_SAUDI_ARABIA = 82
FLAG_MALAYSIA = 83
FLAG_CZECH_REPUBLIC = 84
FLAG_AUSTRALIA = 85
FLAG_SINGAPORE = 86
OCULUS_LOGO = 87
STEAM_LOGO = 88
NVIDIA_LOGO = 89
FLAG_IRAN = 90
FLAG_POLAND = 91
FLAG_ARGENTINA = 92
FLAG_PHILIPPINES = 93
FLAG_CHILE = 94
MIKIROG = 95
V2_LOGO = 96

View file

@ -8,6 +8,8 @@ import logging
import importlib.util
from typing import TYPE_CHECKING
from typing_extensions import override
import _babase
from babase._appsubsystem import AppSubsystem
@ -158,6 +160,7 @@ class PluginSubsystem(AppSubsystem):
if config_changed:
_babase.app.config.commit()
@override
def on_app_running(self) -> None:
# Load up our plugins and go ahead and call their on_app_running
# calls.
@ -170,6 +173,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_running()')
@override
def on_app_suspend(self) -> None:
for plugin in self.active_plugins:
try:
@ -179,6 +183,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_suspend()')
@override
def on_app_unsuspend(self) -> None:
for plugin in self.active_plugins:
try:
@ -188,6 +193,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_unsuspend()')
@override
def on_app_shutdown(self) -> None:
for plugin in self.active_plugins:
try:
@ -197,6 +203,7 @@ class PluginSubsystem(AppSubsystem):
_error.print_exception('Error in plugin on_app_shutdown()')
@override
def on_app_shutdown_complete(self) -> None:
for plugin in self.active_plugins:
try:

View file

@ -5,6 +5,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from typing_extensions import override
from babase._stringedit import StringEditAdapter
import _babase
@ -24,9 +26,11 @@ class DevConsoleStringEditAdapter(StringEditAdapter):
description, initial_text, max_length, screen_space_center
)
@override
def _do_apply(self, new_text: str) -> None:
_babase.set_dev_console_input_text(new_text)
_babase.dev_console_input_adapter_finish()
@override
def _do_cancel(self) -> None:
_babase.dev_console_input_adapter_finish()