adding checks for cross-featureset imports

This commit is contained in:
Eric 2023-06-12 11:30:09 -07:00
parent 2de0bed496
commit 1479395ec0
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
14 changed files with 304 additions and 151 deletions

56
.efrocachemap generated
View File

@ -4072,26 +4072,26 @@
"build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/18/4b/787a9267e17be3c49966072581a5", "build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/18/4b/787a9267e17be3c49966072581a5",
"build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/20/f6/4ce9bc3c1f3732f6adf8237fbe9b", "build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/20/f6/4ce9bc3c1f3732f6adf8237fbe9b",
"build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/a5/30/9058181df0b1255bf6950cbc7813", "build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/a5/30/9058181df0b1255bf6950cbc7813",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/f2/dc/bf56d88353b11986373e899b5bf6", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/dd/e6/324379d12d8773f739bbc1ee8742",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/3c/43/731228e0f7c8e5396b06ca916ffd", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/78/24/27722a657784f579f5824b089691",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/71/24/b8bedec2fab3fd83381a23385a9a", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/83/df/eabeb7b26fb4b5bf8b899ebcd067",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/5f/96/a43273ad50d90d9342f45c22c0e8", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/0a/99/6e19e6ad69a6f0fb4b73cacdd8e5",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/c9/75/393357c2a3f4d3eec2035bc3ecff", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/ad/bd/2f23197da76c148e41b359f0022a",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/b0/85/d8778105cf5a536cb5e6e618c723", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/29/29/2a87524a909d447f938762919de4",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e8/41/5128ac78c21f238d0613ab8e2ece", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/71/de/0b68a02b52ee2c5d356343dccd00",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7f/4d/96dadaf30683f4a69426518ca334", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ea/22/0f260a3a44e4cfdf7706705c81a1",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/14/14/9f38fb471edd66d076b9d611ba55", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/58/1e/023f58fe727fc70ade8ae6d5a880",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/12/37/d741089b132fbcb8b22d9795479a", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/1e/50/a607cd2582de36c989f0d470658e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b0/4f/e9ab4d8fc7405d9c8f667eaacb73", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/81/e2/d816ac2f91de53683636bf3144bd",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7e/2f/2e475906c60e960a63fdd3e5f24d", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/39/8e/756a7cc3ddcecd1146ea4589bf72",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/34/48/662a2168751cd25eaae50f0707df", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/3c/ad/dcabf1359a1cae7c683036b23856",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/1d/2f/ab1c77b292726178d0eb1f5699ad", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f9/06/3b9d1661d6e4cc21c42748db322b",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/44/b8/3c6e810fa14f014b9c91db7ab88a", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/cb/89/a4a0de5aaa1e1929871973587ddd",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/14/59/2164e23d78a6b16a97b3bfe7bdb2", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7a/3b/35ea440785a5ac39cb802b159c8a",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/4f/91/83fa21e46183f74300820e98f4a1", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/53/9b/817e65aebfe3574d50385a08be52",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/61/f5/18b5f9055fb48a1c91ce25f45dee", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/84/b0/70de1c4c94a2c1c8d1fe54da695f",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/87/53/556e49d3273d4be8bfeba546ecb8", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/ba/ec/009c2ead7a78de11c0e55e447881",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/98/9b/73c254c31fe68fc21cae40a1761e", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/1f/8d/cdfe64de06a6861c27828b9120e8",
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/29/dc/e5b08aae2dbe3222082aaa1e90e7", "build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/29/dc/e5b08aae2dbe3222082aaa1e90e7",
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/ce/bb/5796a83ce9d1c9cf58e08f3ff351", "build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/ce/bb/5796a83ce9d1c9cf58e08f3ff351",
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/31/65/014221e46f7974f40aa84c8922dc", "build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/31/65/014221e46f7974f40aa84c8922dc",
@ -4108,14 +4108,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/14/4b/68a0ece3c1f191183b695cf45a4d", "build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/14/4b/68a0ece3c1f191183b695cf45a4d",
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/1f/3f/d899a46cc0dc8bc4f1b38f9318a5", "build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/1f/3f/d899a46cc0dc8bc4f1b38f9318a5",
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/de/99/95fdcb3f614a7b83ada148bca38d", "build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/de/99/95fdcb3f614a7b83ada148bca38d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/74/cb/8be4f4dec7fd2bf11920a48c5446", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/52/08/03398c2a3fcc29a99c687d5efbb4",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/ee/30/7d0a59834145150a5a64d29f2add", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/e8/85/12943e9d34b55fd9a0d0ec0288ea",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/ad/53/a20f19509c6f90472c46004618e7", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/da/b1/a90ccef09b8305f32520688545bf",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/d7/20/8311a232ef822de08b7eea1185e5", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/aa/a0/ce7ffae656e7877a72d35677114f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/f9/bb/cfb390d5f9d37997cacc804ee7ae", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/26/ef/dcfa52d8f4bb9c518c51687b2b3d",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/a6/fa/5651f4f3329109515ad15fbf7fbc", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/09/e9/31c76975c552041232b3ffd5fbf0",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/d8/49/3f000f69e2b50364b7d444f90b3f", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/b0/35/a132ee60e1a20af514abe1276236",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/7b/bd/aff34983fc5a00bfb59fd47d14cb", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/a4/94/64fc55a516281cc28fcfccebbd5b",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa", "src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa",
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1", "src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/ea/6a/6a4721b144e5e297b542d2a0eea2", "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/ea/6a/6a4721b144e5e297b542d2a0eea2",

View File

@ -1093,8 +1093,11 @@
<w>fsets</w> <w>fsets</w>
<w>fsettings</w> <w>fsettings</w>
<w>fsmetapackagename</w> <w>fsmetapackagename</w>
<w>fsmodulename</w>
<w>fsmodulepath</w>
<w>fsname</w> <w>fsname</w>
<w>fspackagename</w> <w>fspackagename</w>
<w>fspackagesroot</w>
<w>fsplit</w> <w>fsplit</w>
<w>fsrc</w> <w>fsrc</w>
<w>fstab</w> <w>fstab</w>
@ -1359,6 +1362,7 @@
<w>imghdr</w> <w>imghdr</w>
<w>imgw</w> <w>imgw</w>
<w>importlines</w> <w>importlines</w>
<w>importparts</w>
<w>incentivized</w> <w>incentivized</w>
<w>includelines</w> <w>includelines</w>
<w>includetest</w> <w>includetest</w>
@ -1574,8 +1578,10 @@
<w>linenumber</w> <w>linenumber</w>
<w>linenums</w> <w>linenums</w>
<w>linestart</w> <w>linestart</w>
<w>linestripped</w>
<w>linetype</w> <w>linetype</w>
<w>linetypes</w> <w>linetypes</w>
<w>linewords</w>
<w>linflav</w> <w>linflav</w>
<w>linkstoryboards</w> <w>linkstoryboards</w>
<w>linkto</w> <w>linkto</w>
@ -1765,6 +1771,7 @@
<w>moduledir</w> <w>moduledir</w>
<w>modulefinder</w> <w>modulefinder</w>
<w>modulename</w> <w>modulename</w>
<w>modulenames</w>
<w>modulepath</w> <w>modulepath</w>
<w>modutils</w> <w>modutils</w>
<w>moola</w> <w>moola</w>

View File

@ -1,4 +1,4 @@
### 1.7.20 (build 21090, api 8, 2023-06-10) ### 1.7.20 (build 21091, api 8, 2023-06-12)
- This seems like a good time for a `refactoring` release in anticipation of - This seems like a good time for a `refactoring` release in anticipation of
changes coming in 1.8. Basically this means that a lot of things will be changes coming in 1.8. Basically this means that a lot of things will be

View File

@ -649,8 +649,11 @@
<w>fsetname</w> <w>fsetname</w>
<w>fsets</w> <w>fsets</w>
<w>fsmetapackagename</w> <w>fsmetapackagename</w>
<w>fsmodulename</w>
<w>fsmodulepath</w>
<w>fsname</w> <w>fsname</w>
<w>fspackagename</w> <w>fspackagename</w>
<w>fspackagesroot</w>
<w>fstestspackagename</w> <w>fstestspackagename</w>
<w>fsum</w> <w>fsum</w>
<w>ftos</w> <w>ftos</w>
@ -799,6 +802,7 @@
<w>imagewidget</w> <w>imagewidget</w>
<w>imayushsaini</w> <w>imayushsaini</w>
<w>importlines</w> <w>importlines</w>
<w>importparts</w>
<w>incentivized</w> <w>incentivized</w>
<w>includelines</w> <w>includelines</w>
<w>indata</w> <w>indata</w>
@ -907,6 +911,8 @@
<w>linebegin</w> <w>linebegin</w>
<w>linemax</w> <w>linemax</w>
<w>linestart</w> <w>linestart</w>
<w>linestripped</w>
<w>linewords</w>
<w>linkstoryboards</w> <w>linkstoryboards</w>
<w>listobj</w> <w>listobj</w>
<w>llock</w> <w>llock</w>
@ -1013,6 +1019,7 @@
<w>modetype</w> <w>modetype</w>
<w>modstr</w> <w>modstr</w>
<w>modtime</w> <w>modtime</w>
<w>modulenames</w>
<w>moduletype</w> <w>moduletype</w>
<w>momemtary</w> <w>momemtary</w>
<w>morecnt</w> <w>morecnt</w>

View File

@ -7,7 +7,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
if TYPE_CHECKING: if TYPE_CHECKING:
pass pass
@ -105,7 +105,7 @@ def get_all_tips() -> list[str]:
'color of sparks from its fuse: yellow..orange..red..BOOM.' 'color of sparks from its fuse: yellow..orange..red..BOOM.'
), ),
] ]
app = _babase.app app = babase.app
if not app.iircade_mode: if not app.iircade_mode:
tips += [ tips += [
'If your framerate is choppy, try turning down resolution\nor ' 'If your framerate is choppy, try turning down resolution\nor '

View File

@ -28,7 +28,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 = 21090 TARGET_BALLISTICA_BUILD = 21091
TARGET_BALLISTICA_VERSION = '1.7.20' TARGET_BALLISTICA_VERSION = '1.7.20'
_g_env_config: EnvConfig | None = None _g_env_config: EnvConfig | None = None

View File

@ -7,7 +7,8 @@ from __future__ import annotations
import weakref import weakref
from typing import Generic, TypeVar, TYPE_CHECKING from typing import Generic, TypeVar, TYPE_CHECKING
import _babase import babase
import _bascenev1 import _bascenev1
if TYPE_CHECKING: if TYPE_CHECKING:
@ -304,7 +305,7 @@ class AssetPackage(DependencyComponent):
super().__init__() super().__init__()
# This is used internally by the get_package_xxx calls. # This is used internally by the get_package_xxx calls.
self.context = _babase.ContextRef() self.context = babase.ContextRef()
entry = self._dep_entry() entry = self._dep_entry()
assert entry is not None assert entry is not None
@ -424,7 +425,7 @@ def test_depset() -> None:
# To test this, add prints on __del__ for stuff used above; # To test this, add prints on __del__ for stuff used above;
# everything should be dead at this point if we have no cycles. # everything should be dead at this point if we have no cycles.
print('everything should be cleaned up...') print('everything should be cleaned up...')
_babase.quit() babase.quit()
class DependencyError(Exception): class DependencyError(Exception):

View File

@ -7,7 +7,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import _bascenev1 import _bascenev1
if TYPE_CHECKING: if TYPE_CHECKING:
@ -17,9 +18,9 @@ if TYPE_CHECKING:
def launch_main_menu_session() -> None: def launch_main_menu_session() -> None:
assert _babase.app.classic is not None assert babase.app.classic is not None
_bascenev1.new_host_session(_babase.app.classic.get_main_menu_session()) _bascenev1.new_host_session(babase.app.classic.get_main_menu_session())
def get_player_icon(sessionplayer: bascenev1.SessionPlayer) -> dict[str, Any]: def get_player_icon(sessionplayer: bascenev1.SessionPlayer) -> dict[str, Any]:
@ -45,7 +46,7 @@ def filter_chat_message(msg: str, client_id: int) -> str | None:
def local_chat_message(msg: str) -> None: def local_chat_message(msg: str) -> None:
classic = _babase.app.classic classic = babase.app.classic
assert classic is not None assert classic is not None
party_window = ( party_window = (
None if classic.party_window is None else classic.party_window() None if classic.party_window is None else classic.party_window()

View File

@ -9,7 +9,8 @@ import weakref
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import _babase import babase
import _bauiv1 import _bauiv1
if TYPE_CHECKING: if TYPE_CHECKING:
@ -199,8 +200,8 @@ def uicleanupcheck(obj: Any, widget: bauiv1.Widget) -> None:
widget.add_delete_callback(foobar) widget.add_delete_callback(foobar)
assert _babase.app.classic is not None assert babase.app.classic is not None
_babase.app.ui_v1.cleanupchecks.append( babase.app.ui_v1.cleanupchecks.append(
UICleanupCheck( UICleanupCheck(
obj=weakref.ref(obj), widget=widget, widget_death_time=None obj=weakref.ref(obj), widget=widget, widget_death_time=None
) )
@ -209,10 +210,10 @@ def uicleanupcheck(obj: Any, widget: bauiv1.Widget) -> None:
def ui_upkeep() -> None: def ui_upkeep() -> None:
"""Run UI cleanup checks, etc. should be called periodically.""" """Run UI cleanup checks, etc. should be called periodically."""
assert _babase.app.classic is not None assert babase.app.classic is not None
ui = _babase.app.ui_v1 ui = babase.app.ui_v1
remainingchecks = [] remainingchecks = []
now = _babase.apptime() now = babase.apptime()
for check in ui.cleanupchecks: for check in ui.cleanupchecks:
obj = check.obj() obj = check.obj()

View File

@ -10,7 +10,7 @@ from typing import cast
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import babase import babase
from _babase import screenmessage
import _bauiv1 import _bauiv1
from bauiv1._uitypes import Window from bauiv1._uitypes import Window
@ -379,12 +379,12 @@ class OnScreenKeyboardWindow(Window):
self._load_keyboard() self._load_keyboard()
if len(kbexports) < 2: if len(kbexports) < 2:
_bauiv1.getsound('error').play() _bauiv1.getsound('error').play()
screenmessage( babase.screenmessage(
babase.Lstr(resource='keyboardNoOthersAvailableText'), babase.Lstr(resource='keyboardNoOthersAvailableText'),
color=(1, 0, 0), color=(1, 0, 0),
) )
else: else:
screenmessage( babase.screenmessage(
babase.Lstr( babase.Lstr(
resource='keyboardSwitchText', resource='keyboardSwitchText',
subs=[('${NAME}', self._keyboard.name)], subs=[('${NAME}', self._keyboard.name)],

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 = 21090; const int kEngineBuildNumber = 21091;
const char* kEngineVersion = "1.7.20"; const char* kEngineVersion = "1.7.20";
auto MonolithicMain(const core::CoreConfig& core_config) -> int { auto MonolithicMain(const core::CoreConfig& core_config) -> int {

View File

@ -35,11 +35,11 @@ class PyRequirement:
# entries; this accounts for manual installations or other nonstandard # entries; this accounts for manual installations or other nonstandard
# setups. # setups.
# Note 2: That is probably overkill. We can probably just replace # Note 2: That is probably overkill. We can probably just replace this
# this with a simple requirements.txt file, can't we? Feels like we're # with a simple requirements.txt file, can't we? Feels like we're mostly
# mostly reinventing the wheel here. We just need a clean way to # reinventing the wheel here. We just need a clean way to check/list
# check/list missing stuff without necessarily installing it. And as far # missing stuff without necessarily installing it. And as far as
# as manually-installed bits, pip itself must have some way to allow for # manually-installed bits, pip itself must have some way to allow for
# that, right?... # that, right?...
PY_REQUIREMENTS = [ PY_REQUIREMENTS = [
PyRequirement(modulename='pylint', minversion=[2, 17, 3]), PyRequirement(modulename='pylint', minversion=[2, 17, 3]),
@ -63,9 +63,9 @@ PY_REQUIREMENTS = [
PyRequirement(pipname='filelock', minversion=[3, 12, 0]), PyRequirement(pipname='filelock', minversion=[3, 12, 0]),
] ]
# Parts of full-tests suite we only run on particular days. # Parts of full-tests suite we only run on particular days. This runs in
# (This runs in listed order so should be randomized by hand to avoid # listed order so should be randomized by hand to avoid clustering
# clustering similar tests too much) # similar tests too much.
SPARSE_TEST_BUILDS: list[list[str]] = [ SPARSE_TEST_BUILDS: list[list[str]] = [
['ios.pylibs.debug', 'android.pylibs.arm'], ['ios.pylibs.debug', 'android.pylibs.arm'],
['linux.package', 'android.pylibs.arm64'], ['linux.package', 'android.pylibs.arm64'],
@ -82,8 +82,8 @@ SPARSE_TEST_BUILDS: list[list[str]] = [
['mac.pylibs.debug', 'android.package'], ['mac.pylibs.debug', 'android.package'],
] ]
# Currently only doing sparse-tests in core; not spinoffs. # Currently only doing sparse-tests in core; not spinoffs (whole word
# (whole word will get subbed out in spinoffs so this will be false) # will get subbed out in spinoffs so this will evaluate to False).
DO_SPARSE_TEST_BUILDS = 'ballistica' + 'kit' == 'ballisticakit' DO_SPARSE_TEST_BUILDS = 'ballistica' + 'kit' == 'ballisticakit'
@ -115,8 +115,9 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
LazyBuildContext( LazyBuildContext(
target=target, target=target,
command=command, command=command,
# Since this category can kick off cleans and blow things away, # Since this category can kick off cleans and blow things
# its not safe to have multiple builds going with it at once. # away, its not safe to have multiple builds going with it
# at once.
buildlockname=category.value, buildlockname=category.value,
# Regular paths; changes to these will trigger meta build. # Regular paths; changes to these will trigger meta build.
srcpaths=[ srcpaths=[
@ -124,12 +125,14 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
'src/meta', 'src/meta',
'src/ballistica/shared/foundation/types.h', 'src/ballistica/shared/foundation/types.h',
], ],
# Our meta Makefile targets generally don't list tools scripts # Our meta Makefile targets generally don't list tools
# that can affect their creation as sources, so let's set up # scripts that can affect their creation as sources, so
# a catch-all here: when any of our tools stuff changes we'll # let's set up a catch-all here: when any of our tools stuff
# blow away all existing meta builds. # changes we'll blow away all existing meta builds.
# Update: also including featureset-defs here; any time we're #
# mucking with those it's good to start fresh to be sure. # Update: also including featureset-defs here; any time
# we're mucking with those it's good to start fresh to be
# sure.
srcpaths_fullclean=[ srcpaths_fullclean=[
'tools/efrotools', 'tools/efrotools',
'tools/efrotoolsinternal', 'tools/efrotoolsinternal',
@ -198,9 +201,9 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
elif category is LazyBuildCategory.RESOURCES: elif category is LazyBuildCategory.RESOURCES:
LazyBuildContext( LazyBuildContext(
target=target, target=target,
# Even though this category currently doesn't run any # Even though this category currently doesn't run any clean
# clean commands, going to restrict to one use at a time for # commands, going to restrict to one use at a time for now
# now in case we want to add that. # in case we want to add that.
buildlockname=category.value, buildlockname=category.value,
srcpaths=[ srcpaths=[
'Makefile', 'Makefile',
@ -214,18 +217,18 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
elif category is LazyBuildCategory.ASSETS: elif category is LazyBuildCategory.ASSETS:
def _filefilter(root: str, filename: str) -> bool: def _filefilter(root: str, filename: str) -> bool:
# Exclude tools/spinoff; it doesn't affect asset builds # Exclude tools/spinoff; it doesn't affect asset builds and
# and we don't want to break if it is a symlink pointing # we don't want to break if it is a symlink pointing to a
# to a not-present parent repo. # not-present parent repo.
if root == 'tools' and filename == 'spinoff': if root == 'tools' and filename == 'spinoff':
return False return False
return True return True
LazyBuildContext( LazyBuildContext(
target=target, target=target,
# Even though this category currently doesn't run any # Even though this category currently doesn't run any clean
# clean commands, going to restrict to one use at a time for # commands, going to restrict to one use at a time for now
# now in case we want to add that. # in case we want to add that.
buildlockname=category.value, buildlockname=category.value,
srcpaths=[ srcpaths=[
'Makefile', 'Makefile',
@ -240,8 +243,8 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
elif category is LazyBuildCategory.DUMMYMODULES: elif category is LazyBuildCategory.DUMMYMODULES:
def _filefilter(root: str, filename: str) -> bool: def _filefilter(root: str, filename: str) -> bool:
# In our C++ sources, only look at stuff with 'python' in the # In our C++ sources, only look at stuff with 'python' in
# name. # the name.
if root.startswith('ballistica'): if root.startswith('ballistica'):
return 'python' in filename return 'python' in filename
@ -250,8 +253,8 @@ def lazybuild(target: str, category: LazyBuildCategory, command: str) -> None:
LazyBuildContext( LazyBuildContext(
target=target, target=target,
# This category builds binaries and other crazy stuff # This category builds binaries and other crazy stuff so we
# so we definitely want to restrict to one at a time. # definitely want to restrict to one at a time.
buildlockname=category.value, buildlockname=category.value,
srcpaths=[ srcpaths=[
'config/featuresets', 'config/featuresets',
@ -313,26 +316,28 @@ def gen_fulltest_buildfile_android() -> None:
""" """
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
# Its a pretty big time-suck building all architectures for # Its a pretty big time-suck building all architectures for all of
# all of our subplatforms, so lets usually just build a single one. # our subplatforms, so lets usually just build a single one. We'll
# We'll rotate it though and occasionally do all 4 at once just to # rotate it though and occasionally do all 4 at once just to be
# be safe. # safe.
dayoffset = datetime.datetime.now().timetuple().tm_yday dayoffset = datetime.datetime.now().timetuple().tm_yday
# Let's only do a full 'prod' once every two times through the loop. # Let's only do a full 'prod' once every two times through the loop.
# (it really should never catch anything that individual platforms don't) # (it really should never catch anything that individual platforms
# don't)
modes = ['arm', 'arm64', 'x86', 'x86_64'] modes = ['arm', 'arm64', 'x86', 'x86_64']
modes += modes modes += modes
modes.append('prod') modes.append('prod')
# By default we cycle through build architectures for each flavor. # By default we cycle through build architectures for each flavor.
# However, for minor flavor with low risk of platform-dependent breakage # However, for minor flavor with low risk of platform-dependent
# we stick to a single one to keep disk space costs lower. (build files # breakage we stick to a single one to keep disk space costs lower.
# amount to several gigs per mode per flavor) # (build files amount to several gigs per mode per flavor)
# UPDATE: Now that we have CPU time to spare, we simply always do 'arm64' #
# or 'prod' depending on build type; this results in 1 or 4 architectures # UPDATE: Now that we have CPU time to spare, we simply always do
# worth of build files per flavor instead of 8 (prod + 4 singles) and # 'arm64' or 'prod' depending on build type; this results in 1 or 4
# keeps our daily runs identical. # architectures worth of build files per flavor instead of 8 (prod +
# 4 singles) and keeps our daily runs identical.
lightweight_flavors = {'template', 'arcade', 'demo', 'iircade'} lightweight_flavors = {'template', 'arcade', 'demo', 'iircade'}
lines = [] lines = []
@ -433,10 +438,10 @@ def gen_fulltest_buildfile_windows() -> None:
lines: list[str] = [] lines: list[str] = []
# We want to do one regular, one headless, and one oculus build, # We want to do one regular, one headless, and one oculus build, but
# but let's switch up 32 or 64 bit based on the day. # let's switch up 32 or 64 bit based on the day. Also occasionally
# Also occasionally throw a release build in but stick to # throw a release build in but stick to mostly debug builds to keep
# mostly debug builds to keep build times speedier. # build times speedier.
pval1 = 'Win32' if dayoffset % 2 == 0 else 'x64' pval1 = 'Win32' if dayoffset % 2 == 0 else 'x64'
pval2 = 'Win32' if (dayoffset + 1) % 2 == 0 else 'x64' pval2 = 'Win32' if (dayoffset + 1) % 2 == 0 else 'x64'
pval3 = 'Win32' if (dayoffset + 2) % 2 == 0 else 'x64' pval3 = 'Win32' if (dayoffset + 2) % 2 == 0 else 'x64'
@ -692,10 +697,11 @@ def checkenv() -> None:
) )
# Make sure rsync is version 3.1.0 or newer. # Make sure rsync is version 3.1.0 or newer.
# Macs come with ancient rsync versions with significant downsides such #
# as single second file mod time resolution which has started to cause # Macs come with ancient rsync versions with significant downsides
# problems with build setups. So now am trying to make sure my Macs # such as single second file mod time resolution which has started
# have an up-to-date one installed (via homebrew). # to cause problems with build setups. So now am trying to make sure
# my Macs have an up-to-date one installed (via homebrew).
rsyncver = tuple( rsyncver = tuple(
int(s) int(s)
for s in subprocess.run( for s in subprocess.run(
@ -772,8 +778,10 @@ def checkenv() -> None:
) from exc ) from exc
# Check for some required python modules. # Check for some required python modules.
#
# FIXME: since all of these come from pip now, we should just use # FIXME: since all of these come from pip now, we should just use
# pip --list to check versions on everything instead of doing it ad-hoc. # pip --list to check versions on everything instead of doing it
# ad-hoc.
for req in PY_REQUIREMENTS: for req in PY_REQUIREMENTS:
try: try:
modname = req.modulename modname = req.modulename

View File

@ -277,6 +277,7 @@ def check_python_files(self: ProjectUpdater) -> None:
from efrotools.code import get_script_filenames from efrotools.code import get_script_filenames
scriptfiles = get_script_filenames(Path(self.projroot)) scriptfiles = get_script_filenames(Path(self.projroot))
for fname in scriptfiles: for fname in scriptfiles:
_check_python_file(self, fname) _check_python_file(self, fname)
@ -289,6 +290,7 @@ def check_python_files(self: ProjectUpdater) -> None:
'src/assets/ba_data/python', 'src/assets/ba_data/python',
'src/meta', 'src/meta',
] ]
# EXCEPT for the following specifics. # EXCEPT for the following specifics.
ignores: dict[str, set[str]] = { ignores: dict[str, set[str]] = {
'tools': { 'tools': {
@ -337,58 +339,125 @@ def check_python_files(self: ProjectUpdater) -> None:
def _check_python_file(self: ProjectUpdater, fname: str) -> None: def _check_python_file(self: ProjectUpdater, fname: str) -> None:
# pylint: disable=too-many-branches with open(os.path.join(self.projroot, fname), encoding='utf-8') as infile:
with open(fname, encoding='utf-8') as infile:
contents = infile.read() contents = infile.read()
lines = contents.splitlines() lines = contents.splitlines()
# Make sure all standalone scripts are pointing to the right version _check_python_file_shebang(self, fname, contents)
# of Python (with a few exceptions where it needs to differ) _check_python_file_license(self, fname, lines)
if contents.startswith('#!/'): _check_python_file_imports(self, fname, lines)
copyrightline = 1
if fname not in ['tools/vmshell']:
if not contents.startswith(f'#!/usr/bin/env python{PYVER}'):
raise CleanError(
f'Incorrect shebang (first line) for ' f'{fname}.'
)
else:
copyrightline = 0
# Special case: it there's spinoff autogenerate notice there,
# look below it.
if (
lines[copyrightline] == ''
and 'THIS FILE IS AUTOGENERATED' in lines[copyrightline + 1]
):
copyrightline += 2
if lines[copyrightline].startswith('# Synced from '): def _check_python_file_imports(
copyrightline += 3 self: ProjectUpdater, fname: str, lines: list[str]
) -> None:
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
fspackagesroot = 'src/assets/ba_data/python/'
# Only checking modules that are part of a featureset.
if not fname.startswith(fspackagesroot):
return
parts = fname.split('/')
if parts[4].endswith('.py'):
return
fsmodulename = parts[4]
for i, line in enumerate(lines): for i, line in enumerate(lines):
# FIXME: update this for the new feature-set world. Perhaps we linestripped = line.strip()
# can screen for imports based on feature-set dependencies or top_level = not line.startswith(' ')
# perhaps we should not even try and just let feature-set test
# builds catch problems like that.
if bool(False):
# Stuff under the babase module.
if '/babase/' in fname:
# Don't allow importing ba at the top level from within babase.
if line == 'import babase':
raise CleanError(
f'{fname}:{i+1}: no top level babase imports allowed'
f' under babase module.'
)
if '/bascenev1lib/' in fname:
# Don't allow importing _babase or _baplus anywhere here.
# (any internal needs should be in babase.internal)
if 'import _babase' in line:
raise CleanError(
f'{fname}:{i+1}: _babase or _baplus imports not'
f' allowed under bascenev1lib.'
)
linewords = linestripped.split(' ')
if len(linewords) < 2:
continue
if linewords[0] == 'import':
assert len(linewords) > 1
modulepath = linewords[1]
importparts = None
elif (
linewords[0] == 'from'
and len(linewords) > 2
and linewords[2] == 'import'
):
modulepath = linewords[1]
importparts = linewords[3:]
else:
continue
# Look for simple cases of 'from foo import bar'.
if (
importparts
and '(' not in importparts[0]
and ',' not in importparts[0]
):
single_import = importparts[0]
else:
single_import = None
modulenames = modulepath.split('.')
# These are fine.
if modulenames[0] in {'__future__', '__main__'}:
continue
# If they're importing a _foo module, make sure they are part of
# featureset foo.
if (
modulenames[0].startswith('_')
and modulenames[0] != f'_{fsmodulename}'
):
raise CleanError(
f'{fname}:{i+1}: Import of private module {modulenames[0]}'
f' not allowed from this featureset package ({fsmodulename}).'
)
# If they're importing foo._bar, make sure they are part of
# featureset foo.
for modulename in modulenames[1:]:
if modulename.startswith('_') and modulenames[0] != fsmodulename:
raise CleanError(
f'{fname}:{i+1}: import of private module {modulepath}'
f' not allowed from this featureset package'
f' ({fsmodulename}).'
)
# Modules under feature-set package foo should never be using
# the top level feature-set package foo directly; only
# individual modules under it. (foo._bar, etc). Doing this can
# lead to lots of import order problems. We currently make an
# exception for anything *not* top-level which covers
# TYPE_CHECKING blocks and functions, both of which should be
# generally ok.
if top_level and modulepath == fsmodulename:
# Also we want to allow 'from foo import bar' *IF* bar is a
# submodule. Note: currently only looking for single
# submodule imports but I don't think we ever import
# multiple.
if importparts is not None and single_import is not None:
fsmodulepath = os.path.join(
self.projroot, fspackagesroot, fsmodulename
)
assert os.path.exists(fsmodulepath)
is_submodule_import = os.path.isdir(
f'{fsmodulepath}/{single_import}'
) or os.path.isfile(f'{fsmodulepath}/{single_import}.py')
else:
is_submodule_import = False
if not is_submodule_import:
raise CleanError(
f'{fname}:{i+1}: Top level package module {modulepath}'
f' should not be imported by its own code'
' (except for within TYPE_CHECKING blocks or functions).'
' Import stuff from submodules directly.'
)
def _check_python_file_license(
self: ProjectUpdater, fname: str, lines: list[str]
) -> None:
copyrightline = _calc_python_file_copyright_line(self, lines)
# In all cases, look for our one-line legal notice. # In all cases, look for our one-line legal notice.
# In the public case, look for the rest of our public license too. # In the public case, look for the rest of our public license too.
if self.license_line_checks: if self.license_line_checks:
@ -430,6 +499,43 @@ def _check_python_file(self: ProjectUpdater, fname: str) -> None:
) )
def _calc_python_file_copyright_line(
self: ProjectUpdater, lines: list[str]
) -> int:
del self # Unused.
copyrightline = 1 if lines[0].startswith('#!/') else 0
# Special case: it there's spinoff autogenerate notice there,
# look below it.
if (
lines[copyrightline] == ''
and 'THIS FILE IS AUTOGENERATED' in lines[copyrightline + 1]
):
copyrightline += 2
if lines[copyrightline].startswith('# Synced from '):
copyrightline += 3
return copyrightline
def _check_python_file_shebang(
self: ProjectUpdater, fname: str, contents: str
) -> None:
del self # Unused.
if contents.startswith('#!'):
# Make sure all standalone scripts are pointing to the right version
# of Python (with a few exceptions where it needs to differ)
if fname not in ['tools/vmshell']:
expected = f'#!/usr/bin/env python{PYVER}'
if not contents.startswith(expected):
raise CleanError(
f'Incorrect shebang (first line) for {fname}.\n'
f'Expected:\n{expected}\n\n'
f'Found:\n{contents.splitlines()[0]}'
)
def _contains_only_pycache_and_cruft(path: str) -> bool: def _contains_only_pycache_and_cruft(path: str) -> bool:
for _root, dirs, files in os.walk(path, topdown=True): for _root, dirs, files in os.walk(path, topdown=True):
# Skip over hidden and pycache dirs. # Skip over hidden and pycache dirs.

View File

@ -6,8 +6,8 @@
from __future__ import annotations from __future__ import annotations
import os import os
import subprocess
import sys import sys
import subprocess
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -196,8 +196,17 @@ def get_code_filenames(projroot: Path, include_generated: bool) -> list[str]:
pass pass
else: else:
codefilenames.append(path) codefilenames.append(path)
codefilenames.sort() out = sorted(codefilenames)
return codefilenames
# Watch for breakage.
if not out:
print(
'WARNING: get_code_filename returning no results;'
' is something broken?',
file=sys.stderr,
)
return out
def black_base_args() -> list[str]: def black_base_args() -> list[str]:
@ -291,20 +300,33 @@ def get_script_filenames(projroot: Path) -> list[str]:
"""Return the Python filenames to lint-check or auto-format.""" """Return the Python filenames to lint-check or auto-format."""
from efrotools import getconfig from efrotools import getconfig
proot = f'{projroot}/'
filenames = set() filenames = set()
places = getconfig(projroot).get('python_source_dirs', None) places = getconfig(projroot).get('python_source_dirs', None)
if places is None: if places is None:
raise RuntimeError('python_source_dirs not declared in config') raise RuntimeError('python_source_dirs not declared in config')
for place in places: for place in places:
for root, _dirs, files in os.walk(place): for root, _dirs, files in os.walk(os.path.join(projroot, place)):
for fname in files: for fname in files:
fnamefull = os.path.join(root, fname) fnamefull = os.path.join(root, fname)
# Skip symlinks (we conceivably operate on the original too) # Skip symlinks (we conceivably operate on the original too)
if os.path.islink(fnamefull): if os.path.islink(fnamefull):
continue continue
if _should_include_script(fnamefull): if _should_include_script(fnamefull):
filenames.add(fnamefull) assert fnamefull.startswith(proot)
return sorted(list(f for f in filenames if 'flycheck_' not in f)) filenames.add(fnamefull.removeprefix(proot))
out = sorted(list(f for f in filenames if 'flycheck_' not in f))
# Watch for breakage.
if not out:
print(
'WARNING: get_script_filename returning no results;'
' is something broken?',
file=sys.stderr,
)
return out
def runpylint(projroot: Path, filenames: list[str]) -> None: def runpylint(projroot: Path, filenames: list[str]) -> None: