This commit is contained in:
Eric 2023-08-30 20:15:54 -07:00
parent eb213d6268
commit 2a3373aa6a
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
45 changed files with 297 additions and 247 deletions

88
.efrocachemap generated
View File

@ -4064,50 +4064,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d3d9fb45a4c9b2d03c3d8d92b21e391c", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d17c2ee21e1fb7845763e9ccc9e7966d",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "4046514b27b8de5eec099669270e760a", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "742d02168b023ef812b53fed2e581f7d",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1eb01901da8e4e6a9aae10d93e75f669", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b41cfcdd17a4ce3a85707426c62144ee",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b2bc222a442085ae9e77c4736c1a47c2", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "a799400fd4b28b724a5cd7022c016a1c",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "98cc6c34ae3baf9f03483ecf718f0860", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "0651c8caba1b5258acf06cf515829e94",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "f55ff138c57aeb6d3b5061b6e5289c89", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "c67d36bac8c20c59cf58fe67ff5aab6f",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "47b4af4d42c6ab169bb33d9b1016a321", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "a932c27c89add5dd0b0b5054ccbc9c30",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "37b2fd64034132fef6a8f202760fc833", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "bcccf5b9506727ae7339d172946e9cba",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b4c9e97df51d5cc4f4086c20f75fadea", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ad79f1fb9a69488395dcb8e9909b18e2",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "017b34a328d86dc83a975504c3228a23", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "1c4c72504904d6ac6003401cffef8550",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f3f4e7aac95d70d36f1458f793df846a", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "3be75ed39f701ea673fdf4c41cc85fee",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "5e0c95b6088822a1a8dbb11d889832e3", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "b6caf556a041fd297a42d022dd28bbbd",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "adb8dfd68d6aea6f450b2ad5ccad3d67", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "32bce4f3dc1068d13c7a8c13f6f65d39",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "951745d14df5d233952a002468b37efa", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "633069c441e56f01cbe5a15d2a3202d4",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "bdd54abe7304f4458867692c28ad1d35", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "02350d3de51cd2056d3144ff34fe24d2",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6585700cc49deb2c42c4119042648ebd", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "562c39ba329fcd64b23d86a56cd5f7bb",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "aae37dce0c102274289663de0ac083d5", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "a173972be3a16bc2637dabbe124aaea6",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "3c30cbf4fb4bde6ce99f0f287052a4a2", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "f0b9f9514c4da093c8720a89e54c069c",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "63bf6d378e6af7f7c02837d201d06a17", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "f7df321426c7add9f4ea31e266ed5c66",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "85aaa5262f488e0a411d8ca8ec6e8987", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "72435cbb4e1b80f31652950f32021464",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "cbb5ca4147284608ee43aaefe1f9bcfb",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "b9aabf060ca52f9957e5c0c68975dd0d", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "788b336518c767880ce7392d7f595852",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "cbb5ca4147284608ee43aaefe1f9bcfb",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "b9aabf060ca52f9957e5c0c68975dd0d", "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "788b336518c767880ce7392d7f595852",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "21b01b868f38182cbe30dead5e6f6688", "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "cccb7895ed8f412f72ce04c676eae235",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "5bafa4627b87a3cfc6558d51c2760560", "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "f792c55164f95f8b33f00e7d809c90f7",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "21b01b868f38182cbe30dead5e6f6688", "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "cccb7895ed8f412f72ce04c676eae235",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "5bafa4627b87a3cfc6558d51c2760560", "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "f792c55164f95f8b33f00e7d809c90f7",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "9ba592d991ebb8724de8cab368bd1ac7", "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "460f8c445f95f1789820ab1d4556c03a",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "79630364e1f71cedf87140c40b913785", "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "911f93f977b96774cfa3c82f5e5a4cc8",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "9ba592d991ebb8724de8cab368bd1ac7", "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "460f8c445f95f1789820ab1d4556c03a",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "79630364e1f71cedf87140c40b913785", "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "911f93f977b96774cfa3c82f5e5a4cc8",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "7e3d1a1c0bdb8a814f7227f71862fa1d", "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "8d7077f5e2b9ed0cf9dcf8cbb75ef696",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "016af4cf5eea1232e05db579bda8ee4b",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "6c7d4caaad12d39c61b291fe33eef2af", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "5d848f38d9a8056de078a26f78538051",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "016af4cf5eea1232e05db579bda8ee4b",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "facd9669de199a464287b985d9373c0f", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3dd5639a27b74c03e77e3ef706889466",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "deff82055a269fa905dd0cd7622adb64", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c374e1187e51a6c7af83b3158e9ece34",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "e5ebf7e622ff126bc6b91dd7148fac4f", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "92888461dc4f86381cfade96b43ca944",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "ad8c2bae99b72b48a510cdf1ce849358", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "95c4b8c64bcfb62f782a4b3b74189b80",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5302ab082d0555788b32e7485e07620", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bb99cd26d290a01a90f538fc9dcc4af6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "0376b9a3e88c8c7305b33160f11a3de9", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "eb5316cfd1213ed4eb61f780ea9ad5ef",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1260620b96e0615fd993bfa19d5368c8", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1c436928b8fdae376046661097a85851",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2ab0357736b91e5be4cd03c153f92c36", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "b5e3f67b28943b3afe6e8d62811f2844",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318", "src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "ad347097a38e0d7ede9eb6dec6a80ee9", "src/ballistica/base/mgen/pyembed/binding_base.inc": "ad347097a38e0d7ede9eb6dec6a80ee9",

View File

@ -1088,6 +1088,7 @@
<w>fnames</w> <w>fnames</w>
<w>fnmatch</w> <w>fnmatch</w>
<w>fnode</w> <w>fnode</w>
<w>fnsu</w>
<w>fnum</w> <w>fnum</w>
<w>fobjc</w> <w>fobjc</w>
<w>foof</w> <w>foof</w>
@ -1335,6 +1336,7 @@
<w>hdpi</w> <w>hdpi</w>
<w>headercheckline</w> <w>headercheckline</w>
<w>headerregistry</w> <w>headerregistry</w>
<w>headlessly</w>
<w>heapqmodule</w> <w>heapqmodule</w>
<w>hehe</w> <w>hehe</w>
<w>heldfile</w> <w>heldfile</w>
@ -1393,7 +1395,6 @@
<w>ignorevar</w> <w>ignorevar</w>
<w>iiarcade</w> <w>iiarcade</w>
<w>iiiiisssi</w> <w>iiiiisssi</w>
<w>iircade</w>
<w>ilang</w> <w>ilang</w>
<w>ilck</w> <w>ilck</w>
<w>ilogput</w> <w>ilogput</w>

View File

@ -1,4 +1,4 @@
### 1.7.27 (build 21272, api 8, 2023-08-30) ### 1.7.27 (build 21281, api 8, 2023-08-30)
- Fixed a rare crash that could occur if the app shuts down while a background - Fixed a rare crash that could occur if the app shuts down while a background
thread is making a web request. The app will now try to wait for any such thread is making a web request. The app will now try to wait for any such
@ -29,9 +29,9 @@
thinking I'll have to bite the bullet and implement something that asks the thinking I'll have to bite the bullet and implement something that asks the
user what the thing is to solve cases like that. user what the thing is to solve cases like that.
- Added tags allowing easily stripping code out of spinoff projects when a - Added tags allowing easily stripping code out of spinoff projects when a
specific feature-set is not present. For example, for feature-set 'foo', one specific feature-set is not present. For example, to strip lines out when
can strip lines out by adding `__SPINOFF_REQUIRE_FOO_BEGIN__` and feature-set 'foo' is not present, surround them by lines containing
`__SPINOFF_REQUIRE_FOO_END__` tags. `__SPINOFF_REQUIRE_FOO_BEGIN__` and `__SPINOFF_REQUIRE_FOO_END__`.
### 1.7.26 (build 21259, api 8, 2023-08-29) ### 1.7.26 (build 21259, api 8, 2023-08-29)

View File

@ -662,6 +662,7 @@
<w>flushhhhh</w> <w>flushhhhh</w>
<w>fname</w> <w>fname</w>
<w>fnode</w> <w>fnode</w>
<w>fnsu</w>
<w>fnumc</w> <w>fnumc</w>
<w>fobjc</w> <w>fobjc</w>
<w>focuswindow</w> <w>focuswindow</w>
@ -805,6 +806,7 @@
<w>havn't</w> <w>havn't</w>
<w>havnt</w> <w>havnt</w>
<w>hdiutil</w> <w>hdiutil</w>
<w>headlessly</w>
<w>healthcare</w> <w>healthcare</w>
<w>heldfile</w> <w>heldfile</w>
<w>hexval</w> <w>hexval</w>
@ -843,7 +845,6 @@
<w>ignorevar</w> <w>ignorevar</w>
<w>iiiiisss</w> <w>iiiiisss</w>
<w>iiiiisssi</w> <w>iiiiisssi</w>
<w>iircade</w>
<w>illum</w> <w>illum</w>
<w>ilock</w> <w>ilock</w>
<w>imagewidget</w> <w>imagewidget</w>

View File

@ -29,7 +29,6 @@
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_demo.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_android_demo.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_generic.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_android_generic.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_google.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_android_google.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_iircade.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_oculus.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_android_oculus.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_android_template.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_android_template.h" />
<file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_common.h" /> <file path="$PROJECT_DIR$/../src/ballistica/config/config_windows_common.h" />

View File

@ -4,7 +4,6 @@
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
from __future__ import annotations from __future__ import annotations
import os
import logging import logging
from enum import Enum from enum import Enum
@ -144,12 +143,34 @@ class App:
the single shared instance. the single shared instance.
""" """
if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1': self.env: babase.Env = _babase.Env()
if self.env.running_with_dummy_modules:
return return
self.state = self.State.NOT_RUNNING self.state = self.State.NOT_RUNNING
self.env: babase.Env = _babase.Env() # Controls which app-modes we use for handling given
# app-intents. Plugins can override this to change high level
# app behavior and spinoff projects can change the default
# implementation for the same effect.
self.mode_selector: babase.AppModeSelector | None = None
# Default executor which can be used for misc background
# processing. It should also be passed to any additional asyncio
# loops we create so that everything shares the same single set
# of worker threads.
self.threadpool = ThreadPoolExecutor(thread_name_prefix='baworker')
self.meta = MetadataSubsystem()
self.net = NetworkSubsystem()
self.workspaces = WorkspaceSubsystem()
self.components = AppComponentSubsystem()
# This is incremented any time the app is backgrounded or
# foregrounded; can be a simple way to determine if network data
# should be refreshed/etc.
self.fg_state = 0
self.config_file_healthy: bool = False
self._subsystems: list[AppSubsystem] = [] self._subsystems: list[AppSubsystem] = []
self._native_bootstrapping_completed = False self._native_bootstrapping_completed = False
@ -164,43 +185,9 @@ class App:
self._called_on_running = False self._called_on_running = False
self._subsystem_registration_ended = False self._subsystem_registration_ended = False
self._pending_apply_app_config = False self._pending_apply_app_config = False
self.config_file_healthy: bool = False
# This is incremented any time the app is backgrounded or
# foregrounded; can be a simple way to determine if network data
# should be refreshed/etc.
self.fg_state = 0
self._aioloop: asyncio.AbstractEventLoop | None = None self._aioloop: asyncio.AbstractEventLoop | None = None
self._asyncio_timer: babase.AppTimer | None = None
self._env = _babase.env()
self.protocol_version: int = self._env['protocol_version']
assert isinstance(self.protocol_version, int)
# self.toolbar_test: bool = self._env['toolbar_test']
# assert isinstance(self.toolbar_test, bool)
self.demo_mode: bool = self._env['demo_mode']
assert isinstance(self.demo_mode, bool)
self.arcade_mode: bool = self._env['arcade_mode']
assert isinstance(self.arcade_mode, bool)
self.headless_mode: bool = self._env['headless_mode']
assert isinstance(self.headless_mode, bool)
# Default executor which can be used for misc background
# processing. It should also be passed to any additional asyncio
# loops we create so that everything shares the same single set
# of worker threads.
self.threadpool = ThreadPoolExecutor(thread_name_prefix='baworker')
self._config: babase.AppConfig | None = None self._config: babase.AppConfig | None = None
self.components = AppComponentSubsystem()
# Testing this.
self.meta = MetadataSubsystem()
self.net = NetworkSubsystem()
self.workspaces = WorkspaceSubsystem()
self._pending_intent: AppIntent | None = None self._pending_intent: AppIntent | None = None
self._intent: AppIntent | None = None self._intent: AppIntent | None = None
self._mode: AppMode | None = None self._mode: AppMode | None = None
@ -209,18 +196,10 @@ class App:
self._wait_for_shutdown_suppressions() self._wait_for_shutdown_suppressions()
] ]
# Controls which app-modes we use for handling given
# app-intents. Plugins can override this to change high level
# app behavior and spinoff projects can change the default
# implementation for the same effect.
self.mode_selector: babase.AppModeSelector | None = None
self._asyncio_timer: babase.AppTimer | None = None
def postinit(self) -> None: def postinit(self) -> None:
"""Called after we've been inited and assigned to babase.app.""" """Called after we've been inited and assigned to babase.app."""
if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1': if self.env.running_with_dummy_modules:
return return
# NOTE: the reason we need a postinit here is that # NOTE: the reason we need a postinit here is that
@ -1011,3 +990,50 @@ class App:
return self.ui_v1.use_toolbars return self.ui_v1.use_toolbars
# __SPINOFF_REQUIRE_UI_V1_END__ # __SPINOFF_REQUIRE_UI_V1_END__
@property
def arcade_mode(self) -> bool:
"""Whether the app is currently running on arcade hardware."""
warnings.warn(
'app.arcade_mode is deprecated; use app.env.arcade',
DeprecationWarning,
stacklevel=2,
)
return self.env.arcade
@property
def headless_mode(self) -> bool:
"""Whether the app is running headlessly."""
warnings.warn(
'app.headless_mode is deprecated; use app.env.headless',
DeprecationWarning,
stacklevel=2,
)
return self.env.headless
@property
def demo_mode(self) -> bool:
"""Whether the app is targeting a demo experience."""
warnings.warn(
'app.demo_mode is deprecated; use app.env.demo',
DeprecationWarning,
stacklevel=2,
)
return self.env.demo
# __SPINOFF_REQUIRE_SCENE_V1_BEGIN__
@property
def protocol_version(self) -> int:
"""(internal)."""
import bascenev1
warnings.warn(
'app.protocol_version is deprecated;'
' use bascenev1.protocol_version()',
DeprecationWarning,
stacklevel=2,
)
return bascenev1.protocol_version()
# __SPINOFF_REQUIRE_SCENE_V1_END__

View File

@ -222,8 +222,7 @@ def garbage_collect() -> None:
def print_corrupt_file_error() -> None: def print_corrupt_file_error() -> None:
"""Print an error if a corrupt file is found.""" """Print an error if a corrupt file is found."""
# FIXME - filter this out for builds without bauiv1. if _babase.app.env.gui:
if not _babase.app.headless_mode:
_babase.apptimer( _babase.apptimer(
2.0, 2.0,
lambda: _babase.screenmessage( lambda: _babase.screenmessage(

View File

@ -92,7 +92,7 @@ def connection_failed_message() -> None:
def temporarily_unavailable_message() -> None: def temporarily_unavailable_message() -> None:
from babase._language import Lstr from babase._language import Lstr
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage( _babase.screenmessage(
Lstr(resource='getTicketsWindow.unavailableTemporarilyText'), Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
@ -103,7 +103,7 @@ def temporarily_unavailable_message() -> None:
def in_progress_message() -> None: def in_progress_message() -> None:
from babase._language import Lstr from babase._language import Lstr
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage( _babase.screenmessage(
Lstr(resource='getTicketsWindow.inProgressText'), Lstr(resource='getTicketsWindow.inProgressText'),
@ -114,7 +114,7 @@ def in_progress_message() -> None:
def error_message() -> None: def error_message() -> None:
from babase._language import Lstr from babase._language import Lstr
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0)) _babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
@ -122,7 +122,7 @@ def error_message() -> None:
def purchase_not_valid_error() -> None: def purchase_not_valid_error() -> None:
from babase._language import Lstr from babase._language import Lstr
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage( _babase.screenmessage(
Lstr( Lstr(
@ -136,7 +136,7 @@ def purchase_not_valid_error() -> None:
def purchase_already_in_progress_error() -> None: def purchase_already_in_progress_error() -> None:
from babase._language import Lstr from babase._language import Lstr
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage( _babase.screenmessage(
Lstr(resource='store.purchaseAlreadyInProgressText'), Lstr(resource='store.purchaseAlreadyInProgressText'),
@ -195,7 +195,7 @@ def award_dual_wielding_achievement() -> None:
def play_gong_sound() -> None: def play_gong_sound() -> None:
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('gong').play() _babase.getsimplesound('gong').play()
@ -263,7 +263,7 @@ def ui_remote_press() -> None:
"""Handle a press by a remote device that is only usable for nav.""" """Handle a press by a remote device that is only usable for nav."""
from babase._language import Lstr from babase._language import Lstr
if _babase.app.headless_mode: if _babase.app.env.headless:
return return
# Can be called without a context; need a context for getsound. # Can be called without a context; need a context for getsound.
@ -358,7 +358,7 @@ def show_client_too_old_error() -> None:
): ):
return return
if not _babase.app.headless_mode: if _babase.app.env.gui:
_babase.getsimplesound('error').play() _babase.getsimplesound('error').play()
_babase.screenmessage( _babase.screenmessage(

View File

@ -42,7 +42,7 @@ class AccountV1Subsystem:
if babase.app.plus is None: if babase.app.plus is None:
return return
if ( if (
babase.app.headless_mode babase.app.env.headless
or babase.app.config.get('Auto Account State') == 'Local' or babase.app.config.get('Auto Account State') == 'Local'
): ):
babase.app.plus.sign_in_v1('Local') babase.app.plus.sign_in_v1('Local')

View File

@ -545,7 +545,7 @@ class StoreSubsystem:
""" """
plus = babase.app.plus plus = babase.app.plus
unowned_maps: set[str] = set() unowned_maps: set[str] = set()
if not babase.app.headless_mode: if babase.app.env.gui:
for map_section in self.get_store_layout()['maps']: for map_section in self.get_store_layout()['maps']:
for mapitem in map_section['items']: for mapitem in map_section['items']:
if plus is None or not plus.get_purchased(mapitem): if plus is None or not plus.get_purchased(mapitem):
@ -558,7 +558,7 @@ class StoreSubsystem:
try: try:
plus = babase.app.plus plus = babase.app.plus
unowned_games: set[type[bascenev1.GameActivity]] = set() unowned_games: set[type[bascenev1.GameActivity]] = set()
if not babase.app.headless_mode: if babase.app.env.gui:
for section in self.get_store_layout()['minigames']: for section in self.get_store_layout()['minigames']:
for mname in section['items']: for mname in section['items']:
if plus is None or not plus.get_purchased(mname): if plus is None or not plus.get_purchased(mname):

View File

@ -128,6 +128,10 @@ class ClassicSubsystem(babase.AppSubsystem):
assert isinstance(self._env['platform'], str) assert isinstance(self._env['platform'], str)
return self._env['platform'] return self._env['platform']
def scene_v1_protocol_version(self) -> int:
"""(internal)"""
return bascenev1.protocol_version()
@property @property
def subplatform(self) -> str: def subplatform(self) -> str:
"""String for subplatform. """String for subplatform.
@ -216,7 +220,7 @@ class ClassicSubsystem(babase.AppSubsystem):
self.special_offer = cfg['pendingSpecialOffer']['o'] self.special_offer = cfg['pendingSpecialOffer']['o']
show_offer() show_offer()
if not babase.app.headless_mode: if babase.app.env.gui:
babase.apptimer(3.0, check_special_offer) babase.apptimer(3.0, check_special_offer)
# If there's a leftover log file, attempt to upload it to the # If there's a leftover log file, attempt to upload it to the
@ -747,7 +751,7 @@ class ClassicSubsystem(babase.AppSubsystem):
from bauiv1lib.party import PartyWindow from bauiv1lib.party import PartyWindow
from babase import app from babase import app
assert not app.headless_mode assert app.env.gui
bauiv1.getsound('swish').play() bauiv1.getsound('swish').play()
@ -770,7 +774,7 @@ class ClassicSubsystem(babase.AppSubsystem):
if not in_main_menu: if not in_main_menu:
set_ui_input_device(device_id) set_ui_input_device(device_id)
if not babase.app.headless_mode: if babase.app.env.gui:
bauiv1.getsound('swish').play() bauiv1.getsound('swish').play()
babase.app.ui_v1.set_main_menu_window( babase.app.ui_v1.set_main_menu_window(

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21272 TARGET_BALLISTICA_BUILD = 21281
TARGET_BALLISTICA_VERSION = '1.7.27' TARGET_BALLISTICA_VERSION = '1.7.27'

View File

@ -112,6 +112,7 @@ from _bascenev1 import (
newnode, newnode,
Node, Node,
printnodes, printnodes,
protocol_version,
release_gamepad_input, release_gamepad_input,
release_keyboard_input, release_keyboard_input,
reset_random_player_names, reset_random_player_names,
@ -383,6 +384,7 @@ __all__ = [
'PowerupMessage', 'PowerupMessage',
'print_live_object_warnings', 'print_live_object_warnings',
'printnodes', 'printnodes',
'protocol_version',
'pushcall', 'pushcall',
'register_map', 'register_map',
'release_gamepad_input', 'release_gamepad_input',

View File

@ -53,7 +53,8 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
super().on_begin() super().on_begin()
# Show achievements remaining. # Show achievements remaining.
if not (babase.app.demo_mode or babase.app.arcade_mode): env = babase.app.env
if not (env.demo or env.arcade):
_bascenev1.timer( _bascenev1.timer(
3.8, babase.WeakCall(self._show_remaining_achievements) 3.8, babase.WeakCall(self._show_remaining_achievements)
) )

View File

@ -211,7 +211,7 @@ class CoopSession(Session):
# Hmm; no players anywhere. Let's end the entire session if we're # Hmm; no players anywhere. Let's end the entire session if we're
# running a GUI (or just the current game if we're running headless). # running a GUI (or just the current game if we're running headless).
else: else:
if not babase.app.headless_mode: if babase.app.env.gui:
self.end() self.end()
else: else:
if isinstance(activity, GameActivity): if isinstance(activity, GameActivity):
@ -277,6 +277,7 @@ class CoopSession(Session):
from bascenev1._score import ScoreType from bascenev1._score import ScoreType
app = babase.app app = babase.app
env = app.env
classic = app.classic classic = app.classic
assert classic is not None assert classic is not None
@ -291,7 +292,7 @@ class CoopSession(Session):
# If we're running with a gui and at any point we have no # If we're running with a gui and at any point we have no
# in-game players, quit out of the session (this can happen if # in-game players, quit out of the session (this can happen if
# someone leaves in the tutorial for instance). # someone leaves in the tutorial for instance).
if not babase.app.headless_mode: if env.gui:
active_players = [p for p in self.sessionplayers if p.in_game] active_players = [p for p in self.sessionplayers if p.in_game]
if not active_players: if not active_players:
self.end() self.end()
@ -317,7 +318,7 @@ class CoopSession(Session):
if ( if (
isinstance(activity, JoinActivity) isinstance(activity, JoinActivity)
and self.campaign_level_name == 'Onslaught Training' and self.campaign_level_name == 'Onslaught Training'
and not (app.demo_mode or app.arcade_mode) and not (env.demo or env.arcade)
): ):
if self._tutorial_activity is None: if self._tutorial_activity is None:
raise RuntimeError('Tutorial not preloaded properly.') raise RuntimeError('Tutorial not preloaded properly.')
@ -339,7 +340,7 @@ class CoopSession(Session):
# Now flip the current activity.. # Now flip the current activity..
self.setactivity(next_game) self.setactivity(next_game)
if not (app.demo_mode or app.arcade_mode): if not (env.demo or env.arcade):
if self.tournament_id is not None: if self.tournament_id is not None:
self._custom_menu_ui = [ self._custom_menu_ui = [
{ {

View File

@ -65,7 +65,7 @@ class JoinInfo:
) )
) )
if babase.app.demo_mode or babase.app.arcade_mode: if babase.app.env.demo or babase.app.env.arcade:
self._messages = [self._joinmsg] self._messages = [self._joinmsg]
else: else:
msg1 = babase.Lstr( msg1 = babase.Lstr(
@ -434,6 +434,7 @@ class Chooser:
"""Reload all player profiles.""" """Reload all player profiles."""
app = babase.app app = babase.app
env = app.env
assert app.classic is not None assert app.classic is not None
# Re-construct our profile index and other stuff since the profile # Re-construct our profile index and other stuff since the profile
@ -475,17 +476,13 @@ class Chooser:
self._profiles['_random'] = {} self._profiles['_random'] = {}
# In kiosk mode we disable account profiles to force random. # In kiosk mode we disable account profiles to force random.
if app.demo_mode or app.arcade_mode: if env.demo or env.arcade:
if '__account__' in self._profiles: if '__account__' in self._profiles:
del self._profiles['__account__'] del self._profiles['__account__']
# For local devices, add it an 'edit' option which will pop up # For local devices, add it an 'edit' option which will pop up
# the profile window. # the profile window.
if ( if not is_remote and not is_test_input and not (env.demo or env.arcade):
not is_remote
and not is_test_input
and not (app.demo_mode or app.arcade_mode)
):
self._profiles['_edit'] = {} self._profiles['_edit'] = {}
# Build a sorted name list we can iterate through. # Build a sorted name list we can iterate through.

View File

@ -69,7 +69,7 @@ def get_player_profile_colors(
# Special case: when being asked for a random color in kiosk mode, # Special case: when being asked for a random color in kiosk mode,
# always return default purple. # always return default purple.
if (babase.app.demo_mode or babase.app.arcade_mode) and profilename is None: if (babase.app.env.demo or babase.app.env.arcade) and profilename is None:
color = (0.5, 0.4, 1.0) color = (0.5, 0.4, 1.0)
highlight = (0.4, 0.4, 0.5) highlight = (0.4, 0.4, 0.5)
else: else:

View File

@ -45,6 +45,9 @@ class CoopJoinActivity(bs.JoinActivity):
def _show_remaining_achievements(self) -> None: def _show_remaining_achievements(self) -> None:
from bascenev1lib.actor.text import Text from bascenev1lib.actor.text import Text
app = bs.app
env = app.env
# We only show achievements and challenges for CoopGameActivities. # We only show achievements and challenges for CoopGameActivities.
session = self.session session = self.session
assert isinstance(session, bs.CoopSession) assert isinstance(session, bs.CoopSession)
@ -64,19 +67,15 @@ class CoopJoinActivity(bs.JoinActivity):
ts_h_offs = 60 ts_h_offs = 60
# Show remaining achievements in some cases. # Show remaining achievements in some cases.
if bs.app.classic is not None and not ( if app.classic is not None and not (env.demo or env.arcade):
bs.app.demo_mode or bs.app.arcade_mode
):
achievements = [ achievements = [
a a
for a in bs.app.classic.ach.achievements_for_coop_level( for a in app.classic.ach.achievements_for_coop_level(levelname)
levelname
)
if not a.complete if not a.complete
] ]
have_achievements = bool(achievements) have_achievements = bool(achievements)
achievements = [a for a in achievements if not a.complete] achievements = [a for a in achievements if not a.complete]
vrmode = bs.app.env.vr vrmode = env.vr
if have_achievements: if have_achievements:
Text( Text(
bs.Lstr(resource='achievementsRemainingText'), bs.Lstr(resource='achievementsRemainingText'),

View File

@ -351,6 +351,8 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
assert bui.app.classic is not None assert bui.app.classic is not None
env = bui.app.env
delay = 0.7 if (self._score is not None) else 0.0 delay = 0.7 if (self._score is not None) else 0.0
# If there's no players left in the game, lets not show the UI # If there's no players left in the game, lets not show the UI
@ -406,9 +408,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
else: else:
pass pass
show_next_button = self._is_more_levels and not ( show_next_button = self._is_more_levels and not (env.demo or env.arcade)
bui.app.demo_mode or bui.app.arcade_mode
)
if not show_next_button: if not show_next_button:
h_offs += 70 h_offs += 70
@ -486,7 +486,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
v_offs + 560.0, v_offs + 560.0,
) )
if bui.app.demo_mode or bui.app.arcade_mode: if env.demo or env.arcade:
self._league_rank_button = None self._league_rank_button = None
self._store_button_instance = None self._store_button_instance = None
else: else:
@ -595,7 +595,9 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
super().on_begin() super().on_begin()
plus = bs.app.plus app = bs.app
env = app.env
plus = app.plus
assert plus is not None assert plus is not None
self._begin_time = bs.time() self._begin_time = bs.time()
@ -624,7 +626,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
# If this is the first time we completed it, set the next one # If this is the first time we completed it, set the next one
# as current. # as current.
if self._newly_complete: if self._newly_complete:
cfg = bs.app.config cfg = app.config
cfg['Selected Coop Game'] = ( cfg['Selected Coop Game'] = (
self._campaign.name + ':' + self._next_level_name self._campaign.name + ':' + self._next_level_name
) )
@ -637,7 +639,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self._is_complete self._is_complete
and self._victory and self._victory
and self._is_more_levels and self._is_more_levels
and not (bs.app.demo_mode or bs.app.arcade_mode) and not (env.demo or env.arcade)
): ):
Text( Text(
bs.Lstr( bs.Lstr(
@ -715,7 +717,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
position=(0, 230), position=(0, 230),
).autoretain() ).autoretain()
if bs.app.classic is not None and bs.app.classic.server is None: if app.classic is not None and app.classic.server is None:
# If we're running in normal non-headless build, show this text # If we're running in normal non-headless build, show this text
# because only host can continue the game. # because only host can continue the game.
adisp = plus.get_v1_account_display_string() adisp = plus.get_v1_account_display_string()
@ -828,7 +830,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
) )
if plus.get_v1_account_state() != 'signed_in': if plus.get_v1_account_state() != 'signed_in':
# We expect this only in kiosk mode; complain otherwise. # We expect this only in kiosk mode; complain otherwise.
if not (bs.app.demo_mode or bs.app.arcade_mode): if not (env.demo or env.arcade):
logging.error('got not-signed-in at score-submit; unexpected') logging.error('got not-signed-in at score-submit; unexpected')
bs.pushcall(bs.WeakCall(self._got_score_results, None)) bs.pushcall(bs.WeakCall(self._got_score_results, None))
else: else:

View File

@ -487,8 +487,8 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
super().on_begin() super().on_begin()
# Show controls help in kiosk mode. # Show controls help in demo or arcade mode.
if bs.app.demo_mode or bs.app.arcade_mode: if bs.app.env.demo or bs.app.env.arcade:
controlsguide.ControlsGuide( controlsguide.ControlsGuide(
delay=3.0, lifespan=10.0, bright=True delay=3.0, lifespan=10.0, bright=True
).autoretain() ).autoretain()

View File

@ -550,8 +550,9 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
] ]
elif self._preset in {Preset.UBER, Preset.UBER_EASY}: elif self._preset in {Preset.UBER, Preset.UBER_EASY}:
# Show controls help in demo/arcade modes. # Show controls help in demo or arcade modes.
if bs.app.demo_mode or bs.app.arcade_mode: env = bs.app.env
if env.demo or env.arcade:
ControlsGuide( ControlsGuide(
delay=3.0, lifespan=10.0, bright=True delay=3.0, lifespan=10.0, bright=True
).autoretain() ).autoretain()

View File

@ -171,7 +171,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# Throw in test build info. # Throw in test build info.
self.beta_info = self.beta_info_2 = None self.beta_info = self.beta_info_2 = None
if env.test and not (app.demo_mode or app.arcade_mode): if env.test and not (env.demo or env.arcade):
pos = (230, 35) pos = (230, 35)
self.beta_info = bs.NodeActor( self.beta_info = bs.NodeActor(
bs.newnode( bs.newnode(
@ -292,10 +292,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
random.seed() random.seed()
if ( if not (env.demo or env.arcade) and not app.ui_v1.use_toolbars:
not (app.demo_mode or app.arcade_mode)
and not app.ui_v1.use_toolbars
):
self._news = NewsDisplay(self) self._news = NewsDisplay(self)
# Bring up the last place we were, or start at the main menu otherwise. # Bring up the last place we were, or start at the main menu otherwise.
@ -312,7 +309,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# When coming back from a kiosk-mode game, jump to # When coming back from a kiosk-mode game, jump to
# the kiosk start screen. # the kiosk start screen.
if bs.app.demo_mode or bs.app.arcade_mode: if env.demo or env.arcade:
# pylint: disable=cyclic-import # pylint: disable=cyclic-import
from bauiv1lib.kiosk import KioskWindow from bauiv1lib.kiosk import KioskWindow
@ -399,6 +396,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
# pylint: disable=too-many-statements # pylint: disable=too-many-statements
app = bs.app app = bs.app
env = app.env
assert app.classic is not None assert app.classic is not None
# Update logo in case it changes. # Update logo in case it changes.
@ -442,7 +440,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
base_x = -270.0 base_x = -270.0
x = base_x - 20.0 x = base_x - 20.0
spacing = 85.0 * base_scale spacing = 85.0 * base_scale
y_extra = 0.0 if (app.demo_mode or app.arcade_mode) else 0.0 y_extra = 0.0 if (env.demo or env.arcade) else 0.0
self._make_logo( self._make_logo(
x - 110 + 50, x - 110 + 50,
113 + y + 1.2 * y_extra, 113 + y + 1.2 * y_extra,
@ -507,7 +505,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
base_x = -170 base_x = -170
x = base_x - 20 x = base_x - 20
spacing = 55 * base_scale spacing = 55 * base_scale
y_extra = 0 if (app.demo_mode or app.arcade_mode) else 0 y_extra = 0 if (env.demo or env.arcade) else 0
xv1 = x xv1 = x
delay1 = delay delay1 = delay
for shadow in (True, False): for shadow in (True, False):

View File

@ -1169,7 +1169,7 @@ class PublicGatherTab(GatherTab):
plus.add_v1_account_transaction( plus.add_v1_account_transaction(
{ {
'type': 'PUBLIC_PARTY_QUERY', 'type': 'PUBLIC_PARTY_QUERY',
'proto': bui.app.protocol_version, 'proto': bs.protocol_version(),
'lang': bui.app.lang.language, 'lang': bui.app.lang.language,
}, },
callback=bui.WeakCall(self._on_public_party_query_result), callback=bui.WeakCall(self._on_public_party_query_result),

View File

@ -88,7 +88,7 @@ class KioskWindow(bui.Window):
resource='demoText', resource='demoText',
fallback_resource='mainMenu.demoMenuText', fallback_resource='mainMenu.demoMenuText',
) )
if bui.app.demo_mode if bui.app.env.demo
else 'ARCADE' else 'ARCADE'
), ),
flatness=1.0, flatness=1.0,
@ -332,7 +332,7 @@ class KioskWindow(bui.Window):
self._b4 = self._b5 = self._b6 = None self._b4 = self._b5 = self._b6 = None
self._b7: bui.Widget | None self._b7: bui.Widget | None
if bui.app.arcade_mode: if bui.app.env.arcade:
self._b7 = bui.buttonwidget( self._b7 = bui.buttonwidget(
parent=self._root_widget, parent=self._root_widget,
autoselect=True, autoselect=True,

View File

@ -50,8 +50,8 @@ class MainMenuWindow(bui.Window):
) )
# Grab this stuff in case it changes. # Grab this stuff in case it changes.
self._is_demo = bui.app.demo_mode self._is_demo = bui.app.env.demo
self._is_arcade = bui.app.arcade_mode self._is_arcade = bui.app.env.arcade
self._tdelay = 0.0 self._tdelay = 0.0
self._t_delay_inc = 0.02 self._t_delay_inc = 0.02
@ -617,7 +617,7 @@ class MainMenuWindow(bui.Window):
) )
) )
# In kiosk mode, provide a button to get back to the kiosk menu. # In kiosk mode, provide a button to get back to the kiosk menu.
if bui.app.demo_mode or bui.app.arcade_mode: if bui.app.env.demo or bui.app.env.arcade:
h, v, scale = positions[self._p_index] h, v, scale = positions[self._p_index]
this_b_width = self._button_width * 0.4 * scale this_b_width = self._button_width * 0.4 * scale
demo_menu_delay = ( demo_menu_delay = (
@ -634,7 +634,7 @@ class MainMenuWindow(bui.Window):
textcolor=(0.7, 0.8, 0.7), textcolor=(0.7, 0.8, 0.7),
label=bui.Lstr( label=bui.Lstr(
resource='modeArcadeText' resource='modeArcadeText'
if bui.app.arcade_mode if bui.app.env.arcade
else 'modeDemoText' else 'modeDemoText'
), ),
transition_delay=demo_menu_delay, transition_delay=demo_menu_delay,

View File

@ -43,8 +43,8 @@ void AssetsServer::PushPendingPreload(Object::Ref<Asset>* asset_ref_ptr) {
}); });
} }
void AssetsServer::PushBeginWriteReplayCall() { void AssetsServer::PushBeginWriteReplayCall(uint16_t protocol_version) {
event_loop()->PushCall([this] { event_loop()->PushCall([this, protocol_version] {
if (replays_broken_) { if (replays_broken_) {
return; return;
} }
@ -79,7 +79,7 @@ void AssetsServer::PushBeginWriteReplayCall() {
// NOTE: We always write replays in our host protocol version // NOTE: We always write replays in our host protocol version
// no matter what the client stream is. // no matter what the client stream is.
uint32_t file_id = kBrpFileID; uint32_t file_id = kBrpFileID;
uint16_t version = kProtocolVersion; uint16_t version = protocol_version;
if ((fwrite(&file_id, sizeof(file_id), 1, replay_out_file_) != 1) if ((fwrite(&file_id, sizeof(file_id), 1, replay_out_file_) != 1)
|| (fwrite(&version, sizeof(version), 1, replay_out_file_) != 1)) { || (fwrite(&version, sizeof(version), 1, replay_out_file_) != 1)) {
fclose(replay_out_file_); fclose(replay_out_file_);

View File

@ -15,7 +15,7 @@ class AssetsServer {
public: public:
AssetsServer(); AssetsServer();
void OnMainThreadStartApp(); void OnMainThreadStartApp();
void PushBeginWriteReplayCall(); void PushBeginWriteReplayCall(uint16_t protocol_version);
void PushEndWriteReplayCall(); void PushEndWriteReplayCall();
void PushAddMessageToReplayCall(const std::vector<uint8_t>& data); void PushAddMessageToReplayCall(const std::vector<uint8_t>& data);
void PushPendingPreload(Object::Ref<Asset>* asset_ref_ptr); void PushPendingPreload(Object::Ref<Asset>* asset_ref_ptr);

View File

@ -1526,9 +1526,6 @@ auto JoystickInput::GetDeviceIdentifier() -> std::string {
} }
auto JoystickInput::GetPartyButtonName() const -> std::string { auto JoystickInput::GetPartyButtonName() const -> std::string {
if (g_buildconfig.iircade_build()) {
return "X";
}
return g_base->assets->CharStr(SpecialChar::kTopButton); return g_base->assets->CharStr(SpecialChar::kTopButton);
} }

View File

@ -145,12 +145,35 @@ void PythonClassEnv::SetupType(PyTypeObject* cls) {
"a non-standard environment, and that python-path modifications may\n" "a non-standard environment, and that python-path modifications may\n"
"cause modules to be loaded from other locations."); "cause modules to be loaded from other locations.");
envs["tv"] = BoolEntry_(g_core->platform->IsRunningOnTV(), envs["tv"] =
"Whether the app is currently running on a TV."); BoolEntry_(g_core->platform->IsRunningOnTV(),
"Whether the app is targeting a TV-centric experience.");
envs["vr"] = BoolEntry_(g_core->IsVRMode(), envs["vr"] = BoolEntry_(g_core->IsVRMode(),
"Whether the app is currently running in VR."); "Whether the app is currently running in VR.");
envs["arcade"] =
BoolEntry_(g_buildconfig.arcade_build(),
"Whether the app is targeting an arcade-centric experience.");
envs["headless"] =
BoolEntry_(g_buildconfig.headless_build(),
"Whether the app is running headlessly (without a gui).\n"
"\n"
"This is the opposite of `gui`.");
envs["gui"] = BoolEntry_(!g_buildconfig.headless_build(),
"Whether the app is running with a gui.\n"
"\n"
"This is the opposite of `headless`.");
envs["demo"] = BoolEntry_(g_buildconfig.demo_build(),
"Whether the app is targeting a demo experience.");
auto* envval = getenv("BA_RUNNING_WITH_DUMMY_MODULES");
envs["running_with_dummy_modules"] =
BoolEntry_(envval && !strcmp(envval, "1"), "(internal)");
bool first = true; bool first = true;
for (auto&& entry : envs) { for (auto&& entry : envs) {
if (!first) { if (!first) {

View File

@ -756,8 +756,8 @@ static auto PyEnv(PyObject* self) -> PyObject* {
// "sO" // toolbar_test // "sO" // toolbar_test
"sO" // demo_mode "sO" // demo_mode
"sO" // arcade_mode "sO" // arcade_mode
"sO" // iircade_mode // "sO" // iircade_mode
"si" // protocol_version // "si" // protocol_version
"sO" // headless_mode "sO" // headless_mode
"sO" // python_directory_app_site "sO" // python_directory_app_site
"ss" // device_name "ss" // device_name
@ -779,11 +779,10 @@ static auto PyEnv(PyObject* self) -> PyObject* {
"ui_scale", ui_scale, "ui_scale", ui_scale,
"on_tv", g_core->platform->IsRunningOnTV() ? Py_True : Py_False, "on_tv", g_core->platform->IsRunningOnTV() ? Py_True : Py_False,
"vr_mode", g_core->IsVRMode() ? Py_True : Py_False, "vr_mode", g_core->IsVRMode() ? Py_True : Py_False,
// "toolbar_test", BA_TOOLBAR_TEST ? Py_True : Py_False,
"demo_mode", g_buildconfig.demo_build() ? Py_True : Py_False, "demo_mode", g_buildconfig.demo_build() ? Py_True : Py_False,
"arcade_mode", g_buildconfig.arcade_build() ? Py_True : Py_False, "arcade_mode", g_buildconfig.arcade_build() ? Py_True : Py_False,
"iircade_mode", g_buildconfig.iircade_build() ? Py_True: Py_False, // "iircade_mode", g_buildconfig.iircade_build() ? Py_True: Py_False,
"protocol_version", kProtocolVersion, // "protocol_version", kProtocolVersion,
"headless_mode", g_core->HeadlessMode() ? Py_True : Py_False, "headless_mode", g_core->HeadlessMode() ? Py_True : Py_False,
"python_directory_app_site", "python_directory_app_site",
site_py_dir ? *PythonRef::FromString(*site_py_dir) : Py_None, site_py_dir ? *PythonRef::FromString(*site_py_dir) : Py_None,

View File

@ -214,9 +214,8 @@ void AppConfig::SetupEntries() {
bool_entries_[BoolID::kKickIdlePlayers] = bool_entries_[BoolID::kKickIdlePlayers] =
BoolEntry("Kick Idle Players", false); BoolEntry("Kick Idle Players", false);
// (default to internal keyboard on iircade; not elsewhere)
bool_entries_[BoolID::kAlwaysUseInternalKeyboard] = bool_entries_[BoolID::kAlwaysUseInternalKeyboard] =
BoolEntry("Always Use Internal Keyboard", g_buildconfig.iircade_build()); BoolEntry("Always Use Internal Keyboard", false);
bool_entries_[BoolID::kShowFPS] = BoolEntry("Show FPS", false); bool_entries_[BoolID::kShowFPS] = BoolEntry("Show FPS", false);
bool_entries_[BoolID::kShowPing] = BoolEntry("Show Ping", false); bool_entries_[BoolID::kShowPing] = BoolEntry("Show Ping", false);
bool_entries_[BoolID::kEnableTVBorder] = bool_entries_[BoolID::kEnableTVBorder] =

View File

@ -36,9 +36,7 @@ UI::UI() {
} }
if (!force_scale_) { if (!force_scale_) {
// Use automatic val. // Use automatic val.
if (g_buildconfig.iircade_build()) { // NOLINT(bugprone-branch-clone) if (g_core->IsVRMode() || g_core->platform->IsRunningOnTV()) {
scale_ = UIScale::kMedium;
} else if (g_core->IsVRMode() || g_core->platform->IsRunningOnTV()) {
// VR and tv builds always use medium. // VR and tv builds always use medium.
scale_ = UIScale::kMedium; scale_ = UIScale::kMedium;
} else { } else {

View File

@ -588,8 +588,6 @@ auto CorePlatform::GetLegacyUserAgentString() -> std::string {
subplatform = "DeMo"; subplatform = "DeMo";
} else if (g_buildconfig.arcade_build()) { } else if (g_buildconfig.arcade_build()) {
subplatform = "ArCd"; subplatform = "ArCd";
} else if (g_buildconfig.iircade_build()) {
subplatform = "iiRcd";
} else { } else {
subplatform = "TstB"; subplatform = "TstB";
} }
@ -699,9 +697,6 @@ auto CorePlatform::GetDeviceV1AccountID() -> std::string {
// Everything else is just considered a 'local' account, though we may // Everything else is just considered a 'local' account, though we may
// give unique ids for unique builds.. // give unique ids for unique builds..
if (g_buildconfig.iircade_build()) {
return "L-iRc" + GetLegacyDeviceUUID();
}
return "L-" + GetLegacyDeviceUUID(); return "L-" + GetLegacyDeviceUUID();
} }

View File

@ -1718,6 +1718,24 @@ static PyMethodDef PyHandleAppIntentExecDef = {
"(internal)", "(internal)",
}; };
// ----------------------- handle_app_intent_default ---------------------------
static auto PyProtocolVersion(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
return PyLong_FromLong(kProtocolVersion);
BA_PYTHON_CATCH;
}
static PyMethodDef PyProtocolVersionDef = {
"protocol_version", // name
(PyCFunction)PyProtocolVersion, // method
METH_NOARGS, // flags
"protocol_version() -> int\n"
"\n"
"(internal)\n",
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> { auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> {
@ -1757,6 +1775,7 @@ auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> {
PyAppModeDeactivateDef, PyAppModeDeactivateDef,
PyHandleAppIntentDefaultDef, PyHandleAppIntentDefaultDef,
PyHandleAppIntentExecDef, PyHandleAppIntentExecDef,
PyProtocolVersionDef,
}; };
} }

View File

@ -25,6 +25,43 @@ class BaseFeatureSet;
namespace ballistica::scene_v1 { namespace ballistica::scene_v1 {
// Protocol version we host games with and write replays to.
// This should be incremented whenever there are changes made to the
// session-commands layer (new/removed/changed nodes, attrs, data files,
// behavior, etc.)
// Note that the packet/gamepacket/message layer can vary more organically based
// on build-numbers of connected clients/servers since none of that data is
// stored; this just needs to be observed for all the scene stuff that
// goes into replays since a single stream can get played/replayed on different
// builds (as long as they support that protocol version).
const int kProtocolVersion = 33;
// Oldest protocol version we can act as a client to.
// This can generally be left as-is as long as only
// new nodes/attrs/commands are added and existing
// stuff is unchanged.
const int kProtocolVersionMin = 24;
// FIXME: We should separate out connection protocol from scene protocol. We
// want to be able to watch really old replays if possible but being able to
// connect to old clients is much less important (and slows progress).
// Protocol additions:
// 25: added a few new achievement graphics and new node attrs for displaying
// stuff in front of the UI
// 26: added penguin
// 27: added templates for LOTS of characters
// 28: added cyborg and enabled fallback sounds and textures
// 29: added bunny and eggs
// 30: added support for resource-strings in text-nodes and screen-messages
// 31: added support for short-form resource-strings, time-display-node, and
// string-to-string attr connections
// 32: added json based player profiles message, added shield
// alwaysShowHealthBar attr
// 33: handshake/handshake-response now send json dicts instead of
// just player-specs
// 34: new image_node enums, data assets.
// Sim step size in milliseconds. // Sim step size in milliseconds.
const int kGameStepMilliseconds = 8; const int kGameStepMilliseconds = 8;

View File

@ -17,7 +17,7 @@ ClientSessionNet::ClientSessionNet() {
"g_replay_open true at netclient start; shouldn't happen."); "g_replay_open true at netclient start; shouldn't happen.");
} }
assert(g_base->assets_server); assert(g_base->assets_server);
g_base->assets_server->PushBeginWriteReplayCall(); g_base->assets_server->PushBeginWriteReplayCall(kProtocolVersion);
writing_replay_ = true; writing_replay_ = true;
g_core->replay_open = true; g_core->replay_open = true;
} }

View File

@ -556,11 +556,6 @@ void SceneV1AppMode::UpdateGameRoster() {
bool include_self = (connections()->GetConnectedClientCount() > 0); bool include_self = (connections()->GetConnectedClientCount() > 0);
// Previously were gonna enable this with the UI revision.
// #if BA_TOOLBAR_TEST
// include_self = true;
// #endif // BA_TOOLBAR_TEST
if (auto* hs = dynamic_cast<HostSession*>(GetForegroundSession())) { if (auto* hs = dynamic_cast<HostSession*>(GetForegroundSession())) {
// Add our host-y self. // Add our host-y self.
if (include_self) { if (include_self) {

View File

@ -32,7 +32,7 @@ SessionStream::SessionStream(HostSession* host_session, bool save_replay)
"g_replay_open true at replay start; shouldn't happen."); "g_replay_open true at replay start; shouldn't happen.");
} }
assert(g_base->assets_server); assert(g_base->assets_server);
g_base->assets_server->PushBeginWriteReplayCall(); g_base->assets_server->PushBeginWriteReplayCall(kProtocolVersion);
writing_replay_ = true; writing_replay_ = true;
g_core->replay_open = true; g_core->replay_open = true;
} }

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21272; const int kEngineBuildNumber = 21281;
const char* kEngineVersion = "1.7.27"; const char* kEngineVersion = "1.7.27";
const int kEngineApiVersion = 8; const int kEngineApiVersion = 8;

View File

@ -18,9 +18,6 @@
#include "ballistica/shared/foundation/macros.h" #include "ballistica/shared/foundation/macros.h"
#include "ballistica/shared/foundation/types.h" #include "ballistica/shared/foundation/types.h"
// BA 2.0 UI testing.
#define BA_TOOLBAR_TEST 0
// There are one or two places where we include this from regular C // There are one or two places where we include this from regular C
// or Objective-C code so want to gracefully handle that case. // or Objective-C code so want to gracefully handle that case.
#ifdef __cplusplus #ifdef __cplusplus
@ -31,43 +28,6 @@ extern const int kEngineBuildNumber;
extern const char* kEngineVersion; extern const char* kEngineVersion;
extern const int kEngineApiVersion; extern const int kEngineApiVersion;
// Protocol version we host games with and write replays to.
// This should be incremented whenever there are changes made to the
// session-commands layer (new/removed/changed nodes, attrs, data files,
// behavior, etc.)
// Note that the packet/gamepacket/message layer can vary more organically based
// on build-numbers of connected clients/servers since none of that data is
// stored; this just needs to be observed for all the scene stuff that
// goes into replays since a single stream can get played/replayed on different
// builds (as long as they support that protocol version).
const int kProtocolVersion = 33;
// Oldest protocol version we can act as a client to.
// This can generally be left as-is as long as only
// new nodes/attrs/commands are added and existing
// stuff is unchanged.
const int kProtocolVersionMin = 24;
// FIXME: We should separate out connection protocol from scene protocol. We
// want to be able to watch really old replays if possible but being able to
// connect to old clients is much less important (and slows progress).
// Protocol additions:
// 25: added a few new achievement graphics and new node attrs for displaying
// stuff in front of the UI
// 26: added penguin
// 27: added templates for LOTS of characters
// 28: added cyborg and enabled fallback sounds and textures
// 29: added bunny and eggs
// 30: added support for resource-strings in text-nodes and screen-messages
// 31: added support for short-form resource-strings, time-display-node, and
// string-to-string attr connections
// 32: added json based player profiles message, added shield
// alwaysShowHealthBar attr
// 33: handshake/handshake-response now send json dicts instead of
// just player-specs
// 34: new image_node enums, data assets.
const int kDefaultPort = 43210; const int kDefaultPort = 43210;
const float kTVBorder = 0.075f; const float kTVBorder = 0.075f;

View File

@ -84,11 +84,6 @@ namespace ballistica {
#define BA_XCODE_BUILD 0 #define BA_XCODE_BUILD 0
#endif #endif
// Is this our android iircade build?
#ifndef BA_IIRCADE_BUILD
#define BA_IIRCADE_BUILD 0
#endif
// Does this build use SDL 1.x? (old mac only) // Does this build use SDL 1.x? (old mac only)
#ifndef BA_SDL_BUILD #ifndef BA_SDL_BUILD
#define BA_SDL_BUILD 0 #define BA_SDL_BUILD 0
@ -268,7 +263,6 @@ class BuildConfig {
bool google_build() const { return EXPBOOL_(BA_GOOGLE_BUILD); } bool google_build() const { return EXPBOOL_(BA_GOOGLE_BUILD); }
bool demo_build() const { return EXPBOOL_(BA_DEMO_BUILD); } bool demo_build() const { return EXPBOOL_(BA_DEMO_BUILD); }
bool arcade_build() const { return EXPBOOL_(BA_ARCADE_BUILD); } bool arcade_build() const { return EXPBOOL_(BA_ARCADE_BUILD); }
bool iircade_build() const { return EXPBOOL_(BA_IIRCADE_BUILD); }
bool contains_python_dist() const { bool contains_python_dist() const {
return EXPBOOL_(BA_CONTAINS_PYTHON_DIST); return EXPBOOL_(BA_CONTAINS_PYTHON_DIST);
} }

View File

@ -2848,7 +2848,7 @@ static PyMethodDef PyIsPartyIconVisibleDef = {
static auto PyToolbarTest(PyObject* self) -> PyObject* { static auto PyToolbarTest(PyObject* self) -> PyObject* {
BA_PYTHON_TRY; BA_PYTHON_TRY;
if (BA_TOOLBAR_TEST) { if (BA_UI_V1_TOOLBAR_TEST) {
Py_RETURN_TRUE; Py_RETURN_TRUE;
} else { } else {
Py_RETURN_FALSE; Py_RETURN_FALSE;

View File

@ -13,7 +13,7 @@
namespace ballistica::ui_v1 { namespace ballistica::ui_v1 {
// Phasing these out; replaced by buttons in our rootwidget. // Phasing these out; replaced by buttons in our rootwidget.
#define DO_OLD_MENU_PARTY_BUTTONS (!BA_TOOLBAR_TEST) #define DO_OLD_MENU_PARTY_BUTTONS (!BA_UI_V1_TOOLBAR_TEST)
const float kMenuButtonSize = 40.0f; const float kMenuButtonSize = 40.0f;
const float kMenuButtonDrawDepth = -0.07f; const float kMenuButtonDrawDepth = -0.07f;

View File

@ -12,6 +12,9 @@
// It predeclares our feature-set's various types and globals and other // It predeclares our feature-set's various types and globals and other
// bits. // bits.
// BA 2.0 UI testing.
#define BA_UI_V1_TOOLBAR_TEST 0
// Predeclared types from other feature sets that we use. // Predeclared types from other feature sets that we use.
namespace ballistica::core { namespace ballistica::core {
class CoreFeatureSet; class CoreFeatureSet;

View File

@ -313,7 +313,7 @@ void RootWidget::AddMeter(float h_align, float x, int type, float r, float g,
#pragma clang diagnostic pop #pragma clang diagnostic pop
void RootWidget::Setup() { void RootWidget::Setup() {
if (!explicit_bool(BA_TOOLBAR_TEST)) { if (!explicit_bool(BA_UI_V1_TOOLBAR_TEST)) {
return; return;
} }
@ -1096,7 +1096,7 @@ void RootWidget::SetScreenWidget(StackWidget* w) {
void RootWidget::SetOverlayWidget(StackWidget* w) { void RootWidget::SetOverlayWidget(StackWidget* w) {
// this needs to happen after our buttons and things get added.. // this needs to happen after our buttons and things get added..
if (explicit_bool(BA_TOOLBAR_TEST)) { if (explicit_bool(BA_UI_V1_TOOLBAR_TEST)) {
assert(!buttons_.empty()); assert(!buttons_.empty());
} }
AddWidget(w); AddWidget(w);