various tool pipeline work for Emacs 29

This commit is contained in:
Eric 2023-07-31 18:48:30 -07:00
parent ba896185c1
commit 0a70c236af
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
13 changed files with 270 additions and 208 deletions

56
.efrocachemap generated
View File

@ -4068,26 +4068,26 @@
"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": "2668b413da2d1dd597a6a6b8c6ae9ee8", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "884277e559d840df55f7e0dd1c186949",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "5d38798c383cae78c227c427ae967281", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "38240f93c1ae9065cf671be2e7620684",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "0df69387ebe2fb149694a267a1df4c24", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "0480c97db92676754cf9552ee462dccb",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "153abebe70483d17d933127e894908c4", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "052b4f4804e30da165744893e84d4a64",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "fd6768fe1167b8e24db5eb9e33360456", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "32d4c7a4bdac7a8cb12d4b42868a5979",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "8377309f0d570de541e9210752463bab", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "42649b501212bea15f4b2f2741583339",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b4b774fef02d72f58f8083430cbc8334", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "03cbedec6c8f294d7fe57a6dc64803e8",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9b100c7bf923a8f01de1b5984f62e7e5", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "37b2c536cd841b40319b0efae40471ce",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ac5ecfa5b0e10bcc0d333875bfff9d29", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "85a86ab24f3a35bff85a9954d7be135a",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "241d315d379eb10ec7c2c7ccc8efa99e", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "5399d3f4924909ca1c0878f347e20a10",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "9d57aaf4d56398e67695659eedce569c", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "70784b57105accc067608e1ea50c2fbc",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "d22fdee9f1355dd8965f56a97518ad85", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "58559f7512a300586b8141591a21564e",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "b85955e00c3a076af273849fd436b18c", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "851e1bcd5f12bcee1a2bb9d503ab90a3",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "a044700e51b426cd333ab32308bfc033", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "8e98e2bb1d7d9fa34f873fd2b7d82138",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "e4bcb7821639ffb7e5b0616d509d3c3d", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "9df874848d2f0cedc815f216f9ab2958",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "91a3fcefaf965260efb388f4477c8ce3", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "49107effdf5c1ee5a0533251a99f9f6a",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "4a54dbbe24033a862a2dac3eb76f98b3", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "dd131f742bc7780f30fe9bbcd547a662",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c82081e53a00d198137c934efae1ed72", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "b59086a58f9fd2148c186a4974ef59dd",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "d8ee381eafbca03eee21e1218935f499", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "03e1623b3a2826161a8a13b09d8ee9b6",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "f6e6fc30a1d2a3ccb2d5f43bf91c4402", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "56b977883c7374d3feb006a9d40c3e18",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "498921f7eb2afd327d4b900cb70e31f9", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "498921f7eb2afd327d4b900cb70e31f9",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f",
@ -4104,14 +4104,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "92394eb19387c363471ce134ac9e6a1b", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "92394eb19387c363471ce134ac9e6a1b",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "0016db9bd4fbf158d19f5a6e84aa2f74", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "d5b059c1be49152dcc400302e27406a7",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "40c9f4c7076ef9013dde9afd05d89b95", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "606d781277bc8f8cd51b7fff37b405eb",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "4e74f1959b833486aa1cee0affa1aaef", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "0204082e71fe83d5e7e9688120a5c47d",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4e39a9a8222a683aa074a0698c26c498", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "453de7f93862b35f208993f32a681fa1",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "9509a8782beb8fd0fc477d0afe3cc6c0", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "e7f61245af268edad9ad09250e934a71",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "091fd49e9c75b202b4f481b65f91a100", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "e35706c767bba1f98c568ca1f1c54361",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "87567923e411e713f82429f56abd9d84", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "71de54551134cfb4e993d8897ba91dd3",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "5e6707e7b299474ae4a43a1df2919a55", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "88053eee3b28eb71e65eef0910d02a2d",
"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": "eeddad968b176000e31c65be6206a2bc", "src/ballistica/base/mgen/pyembed/binding_base.inc": "eeddad968b176000e31c65be6206a2bc",

View File

@ -1,4 +1,4 @@
### 1.7.25 (build 21206, api 8, 2023-07-29) ### 1.7.25 (build 21208, api 8, 2023-07-31)
- `getconfig` and `setconfig` in `efrotools` are now `getprojectconfig` and - `getconfig` and `setconfig` in `efrotools` are now `getprojectconfig` and
`setprojectconfig` (to reflect the file name changes that happened in 1.7.20). `setprojectconfig` (to reflect the file name changes that happened in 1.7.20).
@ -31,6 +31,12 @@
dirs and only moved into their final locations once that completes dirs and only moved into their final locations once that completes
successfully. Its extra important to be safe now that its possible to share successfully. Its extra important to be safe now that its possible to share
local efrocache dirs between projects or otherwise keep them around longer. local efrocache dirs between projects or otherwise keep them around longer.
- Experimenting a bit with adding support for
[Pyright](https://github.com/microsoft/pyright) type-checking. This could
theoretically allow for a really great interactive Python environment in
Visual Studio Code (and potentially other editors), so am seeing if it is
worth officially supporting in addition to or as a replacement for Mypy. See
`tools/pcommand pyright`
### 1.7.24 (build 21199, api 8, 2023-07-27) ### 1.7.24 (build 21199, api 8, 2023-07-27)

View File

@ -1,34 +1,9 @@
;;; Directory Local Variables for emacs clang flycheck ;; -*- lexical-binding: t; -*-
;;; For more information see (info "(emacs) Directory Variables")
;;; Turn flycheck mode on for our c++ stuff and tell jedi where to look for our python stuff.
( (
;; (c++-mode (eval . (flycheck-mode)))
;; Specify some extra paths that project.el searches and whatnot should ignore.
(python-ts-mode (jedi:server-args . ("--sys-path" "__EFRO_PROJECT_ROOT__/tools" ;; Note that gitignored stuff is ignored implicitly.
"--sys-path" "__EFRO_PROJECT_ROOT__/src/assets/ba_data/python"
"--sys-path" "__EFRO_PROJECT_ROOT__/build/dummymodules"
;; "--log-level" "DEBUG" "--log" "/Users/ericf/Desktop/jedilog"
))
(python-black-extra-args . __PYTHON_BLACK_EXTRA_ARGS__))
;; Shorter name in projectile status bar to save valuable space.
(nil . ((projectile-project-name . "__EFRO_PROJECT_SHORTNAME__")))
;; Projectile indexing and search will ignore the following
;; (in addition to git-ignored stuff which it ignores by default)
;; NOTE TO SELF: this means searches in spinoff projects will mostly fail
;; because everything is gitignored; should search in parent repo instead.
(nil . ((projectile-globally-ignored-directories . ("docs"
"submodules"
"src/external"
"src/assets/ba_data/python-site-packages"
"src/assets/pylib-android"
"src/assets/pylib-apple"
"src/assets/windows"))))
;; Trying to get project.el to work the same as projectile since its built in.
(nil . ((project-vc-ignores . ("docs" (nil . ((project-vc-ignores . ("docs"
"submodules" "submodules"
"src/external" "src/external"
@ -37,4 +12,32 @@
"src/assets/pylib-apple" "src/assets/pylib-apple"
"src/assets/windows")))) "src/assets/windows"))))
;; Set up clangd as our C++ language server.
(c++-ts-mode . ((eglot-server-programs . ((c++-ts-mode . ("clangd" "--compile-commands-dir=.cache/compile_commands_db"))))))
;; Set up python-lsp-server as our Python language server.
(python-ts-mode . (
(eglot-server-programs . (
(python-ts-mode . ("__EFRO_PY_BIN__" "-m" "pylsp"))))
(python-shell-interpreter . "__EFRO_PY_BIN__")
(eglot-workspace-configuration . (
(:pylsp . (:plugins (
:pylint (:enabled t)
:flake8 (:enabled :json-false)
:pycodestyle (:enabled :json-false)
:mccabe (:enabled :json-false)
:autopep8 (:enabled :json-false)
:pyflakes (:enabled :json-false)
:rope_autoimport (:enabled :json-false)
:rope_completion (:enabled :json-false)
:rope_rename (:enabled :json-false)
:yapf (:enabled :json-false)
:black (:enabled t
:skip_string_normalization t
:line_length 80
:cache_config t)
:jedi (:extra_paths [__EFRO_PYTHON_PATHS_Q_REL_STR__])
:pylsp_mypy (:enabled t
:live_mode nil
:dmypy t))))))))
) )

View File

@ -17,6 +17,7 @@ a more focused way.
from efro.util import set_canonical_module_names from efro.util import set_canonical_module_names
import _babase import _babase
from _babase import ( from _babase import (
add_clean_frame_callback, add_clean_frame_callback,

View File

@ -24,6 +24,7 @@ from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import __main__ import __main__
if TYPE_CHECKING: if TYPE_CHECKING:
from efro.log import LogHandler from efro.log import LogHandler
@ -50,7 +51,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 = 21206 TARGET_BALLISTICA_BUILD = 21208
TARGET_BALLISTICA_VERSION = '1.7.25' TARGET_BALLISTICA_VERSION = '1.7.25'

View File

@ -18,8 +18,8 @@ if TYPE_CHECKING:
from typing import Any from typing import Any
import bascenev1 import bascenev1
PlayerT = TypeVar('PlayerT', bound=Player) PlayerT = TypeVar("PlayerT", bound=Player)
TeamT = TypeVar('TeamT', bound=Team) TeamT = TypeVar("TeamT", bound=Team)
class Activity(DependencyComponent, Generic[PlayerT, TeamT]): class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
@ -300,7 +300,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
self._expire() self._expire()
else: else:
raise RuntimeError( raise RuntimeError(
f'destroy() called when' f' already expired for {self}' f"destroy() called when" f" already expired for {self}"
) )
def retain_actor(self, actor: bascenev1.Actor) -> None: def retain_actor(self, actor: bascenev1.Actor) -> None:
@ -410,7 +410,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
# Set up the globals node based on our settings. # Set up the globals node based on our settings.
with self.context: with self.context:
glb = self._globalsnode = _bascenev1.newnode('globals') glb = self._globalsnode = _bascenev1.newnode("globals")
# Now that it's going to be front and center, # Now that it's going to be front and center,
# set some global values based on what the activity wants. # set some global values based on what the activity wants.
@ -452,7 +452,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_transition_in() self.on_transition_in()
except Exception: except Exception:
logging.exception('Error in on_transition_in for %s.', self) logging.exception("Error in on_transition_in for %s.", self)
# Tell the C++ layer that this activity is the main one, so it uses # Tell the C++ layer that this activity is the main one, so it uses
# settings from our globals, directs various events to us, etc. # settings from our globals, directs various events to us, etc.
@ -466,7 +466,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_transition_out() self.on_transition_out()
except Exception: except Exception:
logging.exception('Error in on_transition_out for %s.', self) logging.exception("Error in on_transition_out for %s.", self)
def begin(self, session: bascenev1.Session) -> None: def begin(self, session: bascenev1.Session) -> None:
"""Begin the activity. """Begin the activity.
@ -562,7 +562,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_player_join(player) self.on_player_join(player)
except Exception: except Exception:
logging.exception('Error in on_player_join for %s.', self) logging.exception("Error in on_player_join for %s.", self)
def remove_player(self, sessionplayer: bascenev1.SessionPlayer) -> None: def remove_player(self, sessionplayer: bascenev1.SessionPlayer) -> None:
"""Remove a player from the Activity while it is running. """Remove a player from the Activity while it is running.
@ -592,11 +592,11 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_player_leave(player) self.on_player_leave(player)
except Exception: except Exception:
logging.exception('Error in on_player_leave for %s.', self) logging.exception("Error in on_player_leave for %s.", self)
try: try:
player.leave() player.leave()
except Exception: except Exception:
logging.exception('Error on leave for %s in %s.', player, self) logging.exception("Error on leave for %s in %s.", player, self)
self._reset_session_player_for_no_activity(sessionplayer) self._reset_session_player_for_no_activity(sessionplayer)
@ -621,7 +621,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_team_join(team) self.on_team_join(team)
except Exception: except Exception:
logging.exception('Error in on_team_join for %s.', self) logging.exception("Error in on_team_join for %s.", self)
def remove_team(self, sessionteam: bascenev1.SessionTeam) -> None: def remove_team(self, sessionteam: bascenev1.SessionTeam) -> None:
"""Remove a team from a Running Activity """Remove a team from a Running Activity
@ -643,11 +643,11 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_team_leave(team) self.on_team_leave(team)
except Exception: except Exception:
logging.exception('Error in on_team_leave for %s.', self) logging.exception("Error in on_team_leave for %s.", self)
try: try:
team.leave() team.leave()
except Exception: except Exception:
logging.exception('Error on leave for %s in %s.', team, self) logging.exception("Error on leave for %s in %s.", team, self)
sessionteam.activityteam = None sessionteam.activityteam = None
@ -668,7 +668,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
sessionplayer.setnode(None) sessionplayer.setnode(None)
except Exception: except Exception:
logging.exception( logging.exception(
'Error resetting SessionPlayer node on %s for %s.', "Error resetting SessionPlayer node on %s for %s.",
sessionplayer, sessionplayer,
self, self,
) )
@ -676,7 +676,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
sessionplayer.resetinput() sessionplayer.resetinput()
except Exception: except Exception:
logging.exception( logging.exception(
'Error resetting SessionPlayer input on %s for %s.', "Error resetting SessionPlayer input on %s for %s.",
sessionplayer, sessionplayer,
self, self,
) )
@ -701,17 +701,17 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
if not isinstance(self._playertype, type): if not isinstance(self._playertype, type):
self._playertype = Player self._playertype = Player
print( print(
f'ERROR: {type(self)} was not passed a Player' f"ERROR: {type(self)} was not passed a Player"
f' type argument; please explicitly pass bascenev1.Player' f" type argument; please explicitly pass bascenev1.Player"
f' if you do not want to override it.' f" if you do not want to override it."
) )
self._teamtype = type(self).__orig_bases__[-1].__args__[1] self._teamtype = type(self).__orig_bases__[-1].__args__[1]
if not isinstance(self._teamtype, type): if not isinstance(self._teamtype, type):
self._teamtype = Team self._teamtype = Team
print( print(
f'ERROR: {type(self)} was not passed a Team' f"ERROR: {type(self)} was not passed a Team"
f' type argument; please explicitly pass bascenev1.Team' f" type argument; please explicitly pass bascenev1.Team"
f' if you do not want to override it.' f" if you do not want to override it."
) )
assert issubclass(self._playertype, Player) assert issubclass(self._playertype, Player)
assert issubclass(self._teamtype, Team) assert issubclass(self._teamtype, Team)
@ -729,24 +729,24 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
activity = activity_ref() activity = activity_ref()
print( print(
'ERROR: Activity is not dying when expected:', "ERROR: Activity is not dying when expected:",
activity, activity,
'(warning ' + str(counter[0] + 1) + ')', "(warning " + str(counter[0] + 1) + ")",
) )
print( print(
'This means something is still strong-referencing it.\n' "This means something is still strong-referencing it.\n"
'Check out methods such as efro.debug.printrefs() to' "Check out methods such as efro.debug.printrefs() to"
' help debug this sort of thing.' " help debug this sort of thing."
) )
# Note: no longer calling gc.get_referrers() here because it's # Note: no longer calling gc.get_referrers() here because it's
# usage can bork stuff. (see notes at top of efro.debug) # usage can bork stuff. (see notes at top of efro.debug)
counter[0] += 1 counter[0] += 1
if counter[0] == 4: if counter[0] == 4:
print('Killing app due to stuck activity... :-(') print("Killing app due to stuck activity... :-(")
babase.quit() babase.quit()
except Exception: except Exception:
logging.exception('Error on _check_activity_death.') logging.exception("Error on _check_activity_death.")
def _expire(self) -> None: def _expire(self) -> None:
"""Put the activity in a state where it can be garbage-collected. """Put the activity in a state where it can be garbage-collected.
@ -760,12 +760,12 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self.on_expire() self.on_expire()
except Exception: except Exception:
logging.exception('Error in Activity on_expire() for %s.', self) logging.exception("Error in Activity on_expire() for %s.", self)
try: try:
self._customdata = None self._customdata = None
except Exception: except Exception:
logging.exception('Error clearing customdata for %s.', self) logging.exception("Error clearing customdata for %s.", self)
# Don't want to be holding any delay-delete refs at this point. # Don't want to be holding any delay-delete refs at this point.
self._prune_delay_deletes() self._prune_delay_deletes()
@ -780,7 +780,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
self._activity_data.expire() self._activity_data.expire()
except Exception: except Exception:
logging.exception('Error expiring _activity_data for %s.', self) logging.exception("Error expiring _activity_data for %s.", self)
def _expire_actors(self) -> None: def _expire_actors(self) -> None:
# Expire all Actors. # Expire all Actors.
@ -792,7 +792,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
actor.on_expire() actor.on_expire()
except Exception: except Exception:
logging.exception( logging.exception(
'Error in Actor.on_expire() for %s.', actor_ref() "Error in Actor.on_expire() for %s.", actor_ref()
) )
def _expire_players(self) -> None: def _expire_players(self) -> None:
@ -810,7 +810,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
player.expire() player.expire()
except Exception: except Exception:
logging.exception('Error expiring %s.', player) logging.exception("Error expiring %s.", player)
# Reset the SessionPlayer to a not-in-an-activity state. # Reset the SessionPlayer to a not-in-an-activity state.
try: try:
@ -821,7 +821,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
# until now whos underlying SessionPlayer left long ago... # until now whos underlying SessionPlayer left long ago...
pass pass
except Exception: except Exception:
logging.exception('Error expiring %s.', player) logging.exception("Error expiring %s.", player)
def _expire_teams(self) -> None: def _expire_teams(self) -> None:
# Issue warnings for any teams that left the game but don't # Issue warnings for any teams that left the game but don't
@ -838,7 +838,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
try: try:
team.expire() team.expire()
except Exception: except Exception:
logging.exception('Error expiring %s.', team) logging.exception("Error expiring %s.", team)
try: try:
sessionteam = team.sessionteam sessionteam = team.sessionteam
@ -850,7 +850,7 @@ class Activity(DependencyComponent, Generic[PlayerT, TeamT]):
# player/team has left the game) # player/team has left the game)
pass pass
except Exception: except Exception:
logging.exception('Error expiring Team %s.', team) logging.exception("Error expiring Team %s.", team)
def _prune_delay_deletes(self) -> None: def _prune_delay_deletes(self) -> None:
self._delay_delete_players.clear() self._delay_delete_players.clear()

View File

@ -15,6 +15,7 @@ from bascenev1._player import EmptyPlayer # pylint: disable=W0611
from bascenev1._team import EmptyTeam # pylint: disable=W0611 from bascenev1._team import EmptyTeam # pylint: disable=W0611
from bascenev1._music import MusicType, setmusic from bascenev1._music import MusicType, setmusic
if TYPE_CHECKING: if TYPE_CHECKING:
import bascenev1 import bascenev1
from bascenev1._lobby import JoinInfo from bascenev1._lobby import JoinInfo

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 = 21206; const int kEngineBuildNumber = 21208;
const char* kEngineVersion = "1.7.25"; const char* kEngineVersion = "1.7.25";
#if BA_MONOLITHIC_BUILD #if BA_MONOLITHIC_BUILD

View File

@ -22,7 +22,6 @@ from efrotools.filecache import FileCache
# pylint: enable=useless-suppression, wrong-import-order # pylint: enable=useless-suppression, wrong-import-order
if TYPE_CHECKING: if TYPE_CHECKING:
from typing import Any from typing import Any

View File

@ -566,7 +566,11 @@ def _check_warm_start_entries(entries: list[tuple[str, str]]) -> None:
def warm_start_cache() -> None: def warm_start_cache() -> None:
"""Run a pre-pass on the efrocache to improve efficiency.""" """Run a pre-pass on the efrocache to improve efficiency.
This may fetch an initial cache archive, batch update mod times
to reflect new cache maps, etc.
"""
import tempfile import tempfile
base_url = get_repository_base_url() base_url = get_repository_base_url()

View File

@ -449,125 +449,16 @@ def androidstudiocode() -> None:
def tool_config_install() -> None: def tool_config_install() -> None:
"""Install a tool config file (with some filtering).""" """Install a tool config file (with some filtering)."""
from efro.terminal import Clr
from efro.error import CleanError from efro.error import CleanError
import efrotools.toolconfig
if len(sys.argv) != 4: if len(sys.argv) != 4:
raise CleanError('expected 2 args') raise CleanError('expected 2 args')
src = Path(sys.argv[2]) src = Path(sys.argv[2])
dst = Path(sys.argv[3]) dst = Path(sys.argv[3])
print(f'Creating tool config: {Clr.BLD}{dst}{Clr.RST}') efrotools.toolconfig.install_tool_config(PROJROOT, src, dst)
with src.open(encoding='utf-8') as infile:
cfg = infile.read()
# Some substitutions, etc.
cfg = _filter_tool_config(cfg)
# Add an auto-generated notice.
comment = None
if dst.name in ['.dir-locals.el']:
comment = ';;'
elif dst.name in [
'.mypy.ini',
'.pycheckers',
'.pylintrc',
'.style.yapf',
'.clang-format',
'.editorconfig',
]:
comment = '#'
if comment is not None:
cfg = (
f'{comment} THIS FILE WAS AUTOGENERATED; DO NOT EDIT.\n'
f'{comment} Source: {src}.\n\n' + cfg
)
with dst.open('w', encoding='utf-8') as outfile:
outfile.write(cfg)
def _filter_tool_config(cfg: str) -> str:
import textwrap
from efrotools import getprojectconfig
# Stick project-root wherever they want.
cfg = cfg.replace('__EFRO_PROJECT_ROOT__', str(PROJROOT))
# Stick a colon-separated list of project Python paths wherever they want.
name = '__EFRO_PYTHON_PATHS__'
if name in cfg:
pypaths = getprojectconfig(PROJROOT).get('python_paths')
if pypaths is None:
raise RuntimeError('python_paths not set in project config')
assert not any(' ' in p for p in pypaths)
cfg = cfg.replace(name, ':'.join(f'{PROJROOT}/{p}' for p in pypaths))
# Short project name.
short_names = {
'ballistica-internal': 'ba-i',
'ballistica': 'ba',
'ballistica-master-server': 'bmas',
'ballistica-master-server-legacy': 'bmasl',
'ballistica-server-node': 'basn',
}
shortname = short_names.get(PROJROOT.name, PROJROOT.name)
cfg = cfg.replace('__EFRO_PROJECT_SHORTNAME__', shortname)
mypy_standard_settings = textwrap.dedent(
"""
# We don't want all of our plain scripts complaining
# about __main__ being redefined.
scripts_are_modules = True
# Try to be as strict as we can about using types everywhere.
no_implicit_optional = True
warn_unused_ignores = True
warn_no_return = True
warn_return_any = True
warn_redundant_casts = True
warn_unreachable = True
warn_unused_configs = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
disallow_untyped_calls = True
disallow_any_unimported = True
disallow_subclassing_any = True
strict_equality = True
local_partial_types = True
no_implicit_reexport = True
enable_error_code = redundant-expr, truthy-bool, \
truthy-function, unused-awaitable
"""
).strip()
cfg = cfg.replace('__EFRO_MYPY_STANDARD_SETTINGS__', mypy_standard_settings)
name = '__PYTHON_BLACK_EXTRA_ARGS__'
if name in cfg:
from efrotools.code import black_base_args
bargs = black_base_args()
assert bargs[2] == 'black'
cfg = cfg.replace(
name, '(' + ' '.join(f'"{b}"' for b in bargs[3:]) + ')'
)
# Gen a pylint init hook which sets up our python paths.
pylint_init_tag = '__EFRO_PYLINT_INIT__'
if pylint_init_tag in cfg:
pypaths = getprojectconfig(PROJROOT).get('python_paths')
if pypaths is None:
raise RuntimeError('python_paths not set in project config')
cstr = 'init-hook=import sys;'
for path in pypaths:
cstr += f" sys.path.append('{PROJROOT}/{path}');"
cfg = cfg.replace(pylint_init_tag, cstr)
return cfg
def sync_all() -> None: def sync_all() -> None:

View File

@ -0,0 +1,155 @@
# Released under the MIT License. See LICENSE for details.
#
"""Functionality for wrangling tool config files.
This lets us auto-populate values such as python-paths or versions
into tool config files automatically instead of having to update
everything everywhere manually. It also provides a centralized location
for some tool defaults across all my projects.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from efro.terminal import Clr
if TYPE_CHECKING:
from pathlib import Path
def install_tool_config(projroot: Path, src: Path, dst: Path) -> None:
"""Install a config."""
print(f'Creating tool config: {Clr.BLD}{dst}{Clr.RST}')
with src.open(encoding='utf-8') as infile:
cfg = infile.read()
# Some substitutions, etc.
cfg = _filter_tool_config(projroot, cfg)
# Add an auto-generated notice.
comment = None
if dst.name in ['.dir-locals.el']:
comment = ';;'
elif dst.name in [
'.mypy.ini',
'.pycheckers',
'.pylintrc',
'.style.yapf',
'.clang-format',
'.editorconfig',
]:
comment = '#'
if comment is not None:
cfg = (
f'{comment} THIS FILE WAS AUTOGENERATED; DO NOT EDIT.\n'
f'{comment} Source: {src}.\n\n' + cfg
)
with dst.open('w', encoding='utf-8') as outfile:
outfile.write(cfg)
def _filter_tool_config(projroot: Path, cfg: str) -> str:
# pylint: disable=too-many-locals
import textwrap
from efrotools import getprojectconfig, PYVER
# Stick project-root wherever they want.
cfg = cfg.replace('__EFRO_PROJECT_ROOT__', str(projroot))
# Project Python version; '3.11', etc.
name = '__EFRO_PY_VER__'
if name in cfg:
cfg = cfg.replace(name, PYVER)
# Project Python version as a binary name; 'python3.11', etc.
name = '__EFRO_PY_BIN__'
if name in cfg:
cfg = cfg.replace(name, f'python{PYVER}')
# Colon-separated list of project Python paths.
name = '__EFRO_PYTHON_PATHS__'
if name in cfg:
pypaths = getprojectconfig(projroot).get('python_paths')
if pypaths is None:
raise RuntimeError('python_paths not set in project config')
assert not any(' ' in p for p in pypaths)
cfg = cfg.replace(name, ':'.join(f'{projroot}/{p}' for p in pypaths))
# Quoted relative space-separated list of project Python paths.
name = '__EFRO_PYTHON_PATHS_Q_REL_STR__'
if name in cfg:
pypaths = getprojectconfig(projroot).get('python_paths')
if pypaths is None:
raise RuntimeError('python_paths not set in project config')
assert not any(' ' in p for p in pypaths)
cfg = cfg.replace(name, ' '.join(f'"{p}"' for p in pypaths))
# Short project name.
short_names = {
'ballistica-internal': 'ba-i',
'ballistica': 'ba',
'ballistica-master-server': 'bmas',
'ballistica-master-server-legacy': 'bmasl',
'ballistica-server-node': 'basn',
}
shortname = short_names.get(projroot.name, projroot.name)
cfg = cfg.replace('__EFRO_PROJECT_SHORTNAME__', shortname)
mypy_standard_settings = textwrap.dedent(
"""
# We don't want all of our plain scripts complaining
# about __main__ being redefined.
scripts_are_modules = True
# Try to be as strict as we can about using types everywhere.
no_implicit_optional = True
warn_unused_ignores = True
warn_no_return = True
warn_return_any = True
warn_redundant_casts = True
warn_unreachable = True
warn_unused_configs = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
disallow_untyped_calls = True
disallow_any_unimported = True
disallow_subclassing_any = True
strict_equality = True
local_partial_types = True
no_implicit_reexport = True
enable_error_code = redundant-expr, truthy-bool, \
truthy-function, unused-awaitable
"""
).strip()
cfg = cfg.replace('__EFRO_MYPY_STANDARD_SETTINGS__', mypy_standard_settings)
name = '__PYTHON_BLACK_EXTRA_ARGS__'
if name in cfg:
from efrotools.code import black_base_args
bargs = black_base_args()
assert bargs[2] == 'black'
cfg = cfg.replace(
name, '(' + ' '.join(f'"{b}"' for b in bargs[3:]) + ')'
)
# Gen a pylint init hook that sets up our Python paths.
pylint_init_tag = '__EFRO_PYLINT_INIT__'
if pylint_init_tag in cfg:
pypaths = getprojectconfig(projroot).get('python_paths')
if pypaths is None:
raise RuntimeError('python_paths not set in project config')
cstr = 'init-hook=import sys;'
# Stuff our paths in at the beginning in the order they appear
# in our projectconfig.
for i, path in enumerate(pypaths):
cstr += f" sys.path.insert({i}, '{projroot}/{path}');"
cfg = cfg.replace(pylint_init_tag, cstr)
return cfg

View File

@ -15,6 +15,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
# Pull in commands we want to expose. Its more efficient to define them in # Pull in commands we want to expose. Its more efficient to define them in
# modules rather than inline here because we'll be able to load them via pyc. # modules rather than inline here because we'll be able to load them via pyc.
# pylint: disable=unused-import # pylint: disable=unused-import