langs and async task support improvements

This commit is contained in:
Eric 2024-01-16 12:30:39 -08:00
parent f11d4ac261
commit 7182a29c03
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
12 changed files with 177 additions and 94 deletions

98
.efrocachemap generated
View File

@ -421,7 +421,7 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "bb60812044af0a8d1bdefee759ff2522",
"build/assets/ba_data/data/langdata.json": "29a60e77c26b1f397617f8d8c8d652f9",
"build/assets/ba_data/data/languages/arabic.json": "0db32e21b6d5337ccca478381744aa88",
"build/assets/ba_data/data/languages/belarussian.json": "a112dfca3e188387516788bd8229c5b0",
"build/assets/ba_data/data/languages/chinese.json": "93f3ca9f90d86dc7c8d0923f5f11ef46",
@ -429,23 +429,23 @@
"build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa",
"build/assets/ba_data/data/languages/czech.json": "c9d518a324870066b987b8f412881dd3",
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
"build/assets/ba_data/data/languages/dutch.json": "5cbf1a68a9d93dee00dbc27f834d878a",
"build/assets/ba_data/data/languages/dutch.json": "b0900d572c9141897d53d6574c471343",
"build/assets/ba_data/data/languages/english.json": "1c4037fea1066d39d6eced419f314f35",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "0031cbb8eb6a638a94fb43c5d892346c",
"build/assets/ba_data/data/languages/french.json": "8bc35eb4b20a0b30c3348bcc9a3844a6",
"build/assets/ba_data/data/languages/french.json": "cc8ac601f5443dd539893728db983f5c",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "b461539243e8efe3137137b886256ba7",
"build/assets/ba_data/data/languages/greek.json": "287c0ec437b38772284ef9d3e4fb2fc3",
"build/assets/ba_data/data/languages/hindi.json": "8848f6b0caec0fcf9d85bc6e683809ec",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
"build/assets/ba_data/data/languages/indonesian.json": "408fb026e84c24a8dd7a43cb2b794541",
"build/assets/ba_data/data/languages/indonesian.json": "9103845242b572aa8ba48e24f81ddb68",
"build/assets/ba_data/data/languages/italian.json": "f550810b6866ea9bcf1985b7228f8cff",
"build/assets/ba_data/data/languages/korean.json": "03fd99d5e1155e81053fc028f69df982",
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
"build/assets/ba_data/data/languages/persian.json": "9728d631cf7d9ad3b209ae1244bb59c0",
"build/assets/ba_data/data/languages/polish.json": "3a90b2d9e2c59305580c96f8098fc839",
"build/assets/ba_data/data/languages/portuguese.json": "0274cb9a4b7d2bd49c8eb8120144a1bf",
"build/assets/ba_data/data/languages/portuguese.json": "b52164747c6308fc9d054eb6c0ff3c54",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
"build/assets/ba_data/data/languages/russian.json": "30d5f3d2415088e1fb6558fcd6ccfa98",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
@ -4060,50 +4060,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "cd19dfdf480de6e73949db674e1b02d2",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "8c08cdda59e731a3830624000de5ca7f",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "14685eca62b8540cc2a268883d0ebc5d",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "f81876d7827a10be412306c52b03fa08",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b8370845743ebba86ed6eaa6ee1d79d5",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "cdf04825dedae8fb2c26502ec2a505db",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "4036493f98646b58de8bf425bee227cb",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "1cf36c63f68ecaa954fb9c48a132725e",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b757a940c5157197a0138e12e308f859",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "92a07f83fceeddf3b29cfe2ead57f7e3",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "90002c085c66be4af378d4b3fc8e0260",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "eeb363d0d48e68f5f2ac2e536a26aeeb",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "e119b480fc7e542f33ceb16e8c04585f",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "6e657aa09d052765ed891789ec60dfb2",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "2d4eab8ea8399defd1afdbe548216e9c",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "b03bb9d5d1eb695a11843f64f24906ef",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "163fbc40b479ef1db1c753f7beb73c0f",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "37291abd76871f4556348f77e12dd363",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "acca6904f2f2f952ecae99922c602b9d",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "3c2dfd9cf26e77a0b803ed43c85df113",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "3af5cf00e5eb30d55030e8705b83353a",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "be337c05f72235b5b486277bb1a9c259",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "3af5cf00e5eb30d55030e8705b83353a",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "be337c05f72235b5b486277bb1a9c259",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "17c7d0041bc7c84077bf6692b16e3988",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "4affbfea91e8a33ab62da763ffc07ddd",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "17c7d0041bc7c84077bf6692b16e3988",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "4affbfea91e8a33ab62da763ffc07ddd",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "58656b49d34e6c650983fbf79b5c41ae",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "3ce5652e0ff5d277e256f517dec4eb61",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "58656b49d34e6c650983fbf79b5c41ae",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "3ce5652e0ff5d277e256f517dec4eb61",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "b94fff3a719003c1d8f5dd16dffdb3fc",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5d68e1957febe6053815bbee3f068e76",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "85bbca447ca8a1d0fad984afc6f0700a",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5d68e1957febe6053815bbee3f068e76",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "7f2ed141a475e051d3350d571ef6cb0c",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "93fb764531ae16a30d4886eb183c3681",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "750cd7ef428f4faf65ccbeff50c21f8e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "104cf85df9f1f7ffbf4de5997f7c6879",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "af85fb387d755b152c42f8dfb0891ad7",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "01ce8e0619b342e4cc2cc5f18f81a727",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "f8aae2e04f95f4cfb863791da36ff931",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "66252d58a1be97db8523bd0bf8098a16",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "c1f5b6a9fe5aee5baab40248a00eb606",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "88888a9139b8a047d1dde25ae0aa9ea6",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "e51014b672283258ba29f546f3a8833e",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "811973441c2d7998445182b2ab4bcc24",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "01e0fe6152b79211acec7e88a99c6579",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "9e2b7acbcd3892af6be5f85bfe328c2c",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "2f54025a53bb947c89eee520131eae52",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "b9df392dca06e52b958ea3c9b676ae6a",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f2ed10e0b5956ce8ef5b87c3e0c75eea",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "e1c27e7ecb5272f92e6cfdb91b0750d3",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "67827bd210a484f7d93974b581b95a85",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "c03d44f4096cbffe0d1b3391a7b09555",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "a78c8b08a19dc23d1881eee37fdbcfdd",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ca2caba96a855ac6fa7459855bfa49bb",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "9521bca3d6dc02e896fa01ab0ccdfd0c",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "31762c816772ba2c0516c26589428c08",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "ab72b100f5c1eaaac6264b8f662fabb7",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "edf145cc7855aced80f60766a9420df5",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4d4e6e57f179666e8f5a50352b9cda9b",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "20babca2eb9cc062f583ecea557a945e",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "8ccecbffbaa9886636741cca293d2893",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "42679aef4dd8b35b39a2c968ff20ed45",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "8ccecbffbaa9886636741cca293d2893",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "42679aef4dd8b35b39a2c968ff20ed45",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "b2c2c33149201227ba96459dbeeba012",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "2b27b84fe8305b7f3829aa28ab5e5705",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "b2c2c33149201227ba96459dbeeba012",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "2b27b84fe8305b7f3829aa28ab5e5705",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "f6b49cee7baf1ee49598b803566d9914",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "a15dc59a2de8a8d32b32f07fe25d41b1",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "f6b49cee7baf1ee49598b803566d9914",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "a15dc59a2de8a8d32b32f07fe25d41b1",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "80fd9070d92797ff6e26c0a5493dcb42",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "07c2b1098c1c08d2e28934a6f0e1fcf2",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "724d8dcd34fb6c2c0109906d44a4fb12",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "07c2b1098c1c08d2e28934a6f0e1fcf2",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "698b55a6c11f38e5c28587a7039e6175",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "753db5761ce823966fcef472b73e06d1",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b1e41720089a0d7724337071442238c9",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "37d3e9fa31a003dd9609f476d4165d12",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "105f4dc0399235e4a9c25c3977febec8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "820c04dd9965698a86e4f5efffdb729d",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "070727ad10a727b22beef6ee736c7a5f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "6d2969401a8a022e28f4680b01004a50",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -1,4 +1,4 @@
### 1.7.33 (build 21757, api 8, 2024-01-06)
### 1.7.33 (build 21760, api 8, 2024-01-16)
- Stress test input-devices are now a bit smarter; they won't press any buttons
while UIs are up (this could cause lots of chaos if it happened).
- Added a 'Show Demos When Idle' option in advanced settings. If enabled, the

View File

@ -49,9 +49,6 @@
<file path="$PROJECT_DIR$/../src/external/python-android-debug" />
<file path="$PROJECT_DIR$/../src/external/python-apple" />
<file path="$PROJECT_DIR$/../src/external/python-apple-debug" />
<file path="$PROJECT_DIR$/../src/external/sdl-1.2.14_ef" />
<file path="$PROJECT_DIR$/../src/external/sdl2-ef_android" />
<file path="$PROJECT_DIR$/../src/external/sdl2-ef_ios" />
<file path="$PROJECT_DIR$/../src/external/tremor" />
<file path="$PROJECT_DIR$/../src/external/windows" />
<file path="$PROJECT_DIR$/../src/meta" />

View File

@ -1,12 +1,13 @@
# 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
@ -26,7 +27,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 +43,8 @@ if TYPE_CHECKING:
# __FEATURESET_APP_SUBSYSTEM_IMPORTS_END__
T = TypeVar('T')
class App:
"""A class for high level app functionality and state.
@ -199,7 +202,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 +243,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:
@ -594,7 +648,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__
@ -874,8 +928,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

@ -229,9 +229,7 @@ class AdsSubsystem:
await asyncio.sleep(1.0)
payload.run(fallback=True)
_fallback_task = babase.app.aioloop.create_task(
add_fallback_task()
)
babase.app.create_async_task(add_fallback_task())
self.show_ad('between_game', on_completion_call=payload.run)
else:
babase.pushcall(call) # Just run the callback without the ad.

View File

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

View File

@ -5,9 +5,13 @@
from __future__ import annotations
import time
from typing import TYPE_CHECKING
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any
class PromoCodeWindow(bui.Window):
"""Window for entering promo codes."""
@ -167,9 +171,6 @@ class PromoCodeWindow(bui.Window):
if not self._root_widget or self._root_widget.transitioning_out:
return
plus = bui.app.plus
assert plus is not None
bui.containerwidget(
edit=self._root_widget, transition=self._transition_out
)
@ -179,11 +180,22 @@ class PromoCodeWindow(bui.Window):
AdvancedSettingsWindow(transition='in_left').get_root_widget(),
from_window=self._root_widget,
)
plus.add_v1_account_transaction(
{
'type': 'PROMO_CODE',
'expire_time': time.time() + 5,
'code': bui.textwidget(query=self._text_field),
}
)
plus.run_v1_account_transactions()
code: Any = bui.textwidget(query=self._text_field)
assert isinstance(code, str)
bui.app.create_async_task(_run_code(code))
async def _run_code(code: str) -> None:
plus = bui.app.plus
assert plus is not None
plus.add_v1_account_transaction(
{
'type': 'PROMO_CODE',
'expire_time': time.time() + 5,
'code': code,
}
)
plus.run_v1_account_transactions()

View File

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

View File

@ -31,7 +31,7 @@ class DirectoryManifest:
files: Annotated[dict[str, DirectoryManifestFile], IOAttrs('f')]
_empty_hash: str | None = None
# _empty_hash: str | None = None
@classmethod
def create_from_disk(cls, path: Path) -> DirectoryManifest:
@ -92,12 +92,12 @@ class DirectoryManifest:
)
break # 1 error is enough for now.
@classmethod
def get_empty_hash(cls) -> str:
"""Return the hash for an empty file."""
if cls._empty_hash is None:
import hashlib
# @classmethod
# def get_empty_hash(cls) -> str:
# """Return the hash for an empty file."""
# if cls._empty_hash is None:
# import hashlib
sha = hashlib.sha256()
cls._empty_hash = sha.hexdigest()
return cls._empty_hash
# sha = hashlib.sha256()
# cls._empty_hash = sha.hexdigest()
# return cls._empty_hash

View File

@ -70,6 +70,13 @@ class IOExtendedData:
Can be overridden to migrate old data formats to new, etc.
"""
def did_input(self) -> None:
"""Called on a class instance after created from data.
Can be useful to correct values from the db, etc. in the
type-safe form.
"""
def _is_valid_for_codec(obj: Any, codec: Codec) -> bool:
"""Return whether a value consists solely of json-supported types.

View File

@ -64,11 +64,23 @@ class _Inputter(Generic[T]):
# For special extended data types, call their 'will_output' callback.
tcls = self._cls
if issubclass(tcls, IOExtendedData):
is_ext = True
tcls.will_input(values)
else:
is_ext = False
out = self._dataclass_from_input(self._cls, '', values)
assert isinstance(out, self._cls)
if is_ext:
# mypy complains that we're no longer returning a T
# if we operate on out directly.
out2 = out
assert isinstance(out2, IOExtendedData)
out2.did_input()
return out
def _value_from_input(

View File

@ -174,17 +174,20 @@ def empty_weakref(objtype: type[T]) -> weakref.ref[T]:
# Just create an object and let it die. Is there a cleaner way to do this?
# return weakref.ref(_EmptyObj()) # type: ignore
# Sharing a single ones seems at least a bit better.
return _g_empty_weak_ref # type: ignore
def data_size_str(bytecount: int) -> str:
def data_size_str(bytecount: int, compact: bool = False) -> str:
"""Given a size in bytes, returns a short human readable string.
This should be 6 or fewer chars for most all sane file sizes.
In compact mode this should be 6 or fewer chars for most all
sane file sizes.
"""
# pylint: disable=too-many-return-statements
if bytecount <= 999:
return f'{bytecount} B'
suffix = 'B' if compact else 'bytes'
return f'{bytecount} {suffix}'
kbytecount = bytecount / 1024
if round(kbytecount, 1) < 10.0:
return f'{kbytecount:.1f} KB'
@ -623,7 +626,7 @@ def check_non_optional(obj: T | None) -> T:
Use assert_non_optional for a more efficient (but less safe) equivalent.
"""
if obj is None:
raise TypeError('Got None value in check_non_optional.')
raise ValueError('Got None value in check_non_optional.')
return obj