diff --git a/.efrocachemap b/.efrocachemap index b45920fe..766871e3 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3995,26 +3995,26 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", - "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/16/55/a14a247c0db04420117a8ed371f6", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/00/ce/c04891665cbcfbdcd40befef320e", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b9/47/7ec5ce0741537a0a63bb812519e9", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/67/16065d61c11709286cbf58a8c1d3", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ef/0a/ac07d9d822e90baa8f7342041017", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f6/55/75ec6378098ac6c398432c4b2abc", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/11/b0/2e4b8b67b4ed827e6c70c5d4566a", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/fd/849f092a3abf28486999b5393552", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/05/91/4ebfc45bc0b5da7384ae8f93c921", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/09/d7/12317ddd52d8c59ed93423aaed46", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/16/b6/2f8c82eb93716e8aaad8613a2b6a", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b1/17/2893e78c6482b5d0e8cd3c267f41", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/71/18/ca3952e50e1b4961dac32174daef", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cf/85/5e1fb710aa4eabbf4d54d2fd5e43", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ad/c9/9fa020ee678e12074f5d1f848055", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/25/fe/5084d63800be13121bbce5e2b718", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/67/52/13872d8fedb93a23be3931ab4ac8", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/82/7a/0eff468145e4ae32e9de2f564ede", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/7f/1b/4853e57aa94b004b8dd301ac0482", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/20/e6/9f3058021a438a944da4511fce3f", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c7/0e/47a1cc6413aaad0c0afe0884b716", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/6f/5daf49965bace69f17f7b4ed2e55", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/35/4e8366fc775df35f7633d7a224ae", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/93/f2/0d4333951f150ea0aadfeaaae852", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e7/01/2bec5299c6ff6bc9722f51b7839e", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/70/90c234a390e49a1eff61a0de9eca", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2d/33/2ef1276ec090ed01884623346dd7", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/49/21/89e770f7339c8fa9782c7280c0af", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/62/15/699580dbe1d45625e063e056a547", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4b/45/d857357c0c226d768434ade291d3", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/53/e0a72c39bbc8980f6cf3309e8074", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8b/6d/7c315ab5f44211be0f025d7b2c68", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/32/ad/5f826af4b9773a900b2709298943", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/82/31/94fef121e7a83af30760e550d800", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9a/12/e77b1a75fd08a625755d862700c4", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3d/4a/a0a222d942d7b36d4a58325c3f95", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/50/e8/001aa174b93d5ee0f076390add7a", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/15/2d/f1bc569de45c97fd5c1a769a4cb2", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/14/4f/6729d832b56076aeeb5b62db0b18", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/fc/ac/fdeac05ecc7a4ff5d4a0e33b4cd4", "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/13/6a/baff53fa7c286e51469b0b32f05b", "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/57/24/9f56b62f3d49ffcab8813e155311", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/db/15/191884a40ea1128a47058b19da6b", diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f7b5ada..30576c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### 1.7.7 (build 20690, api 7, 2022-08-11) +- added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread +- improved logging of missing playlist game types +- some ba.Lstr functionality can now be used in background threads + + ### 1.7.6 (build 20687, api 7, 2022-08-11) - Cleaned up da MetaSubsystem code. - It is now possible to tell the meta system about arbitrary classes (ba_meta export foo.bar.Class) instead of just the preset types 'plugin', 'game', etc. diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash index a2b13ee8..311f309a 100644 --- a/assets/src/ba_data/python/._ba_sources_hash +++ b/assets/src/ba_data/python/._ba_sources_hash @@ -1 +1 @@ -105185559858403296763219852162674470262 \ No newline at end of file +58062653605658487107918437258195542763 \ No newline at end of file diff --git a/assets/src/ba_data/python/ba/_gameutils.py b/assets/src/ba_data/python/ba/_gameutils.py index 65d93345..97cac63a 100644 --- a/assets/src/ba_data/python/ba/_gameutils.py +++ b/assets/src/ba_data/python/ba/_gameutils.py @@ -399,24 +399,3 @@ def cameraflash(duration: float = 999.0) -> None: light.node.delete, timeformat=TimeFormat.MILLISECONDS) activity.camera_flash_data.append(light) # type: ignore - - -def get_game_types() -> list[type[ba.GameActivity]]: - """Return all available game types.""" - # pylint: disable=cyclic-import - from ba._general import getclass - from ba._gameactivity import GameActivity - from ba._store import get_unowned_game_types - - gameclassnames = _ba.app.meta.wait_for_scan_results().exports_of_class( - GameActivity) - gameclasses = [] - for gameclassname in gameclassnames: - try: - cls = getclass(gameclassname, GameActivity) - gameclasses.append(cls) - except Exception: - from ba import _error - _error.print_exception('error importing ' + str(gameclassname)) - unowned = get_unowned_game_types() - return [cls for cls in gameclasses if cls not in unowned] diff --git a/assets/src/ba_data/python/ba/_meta.py b/assets/src/ba_data/python/ba/_meta.py index 7e16b741..1ff7a004 100644 --- a/assets/src/ba_data/python/ba/_meta.py +++ b/assets/src/ba_data/python/ba/_meta.py @@ -12,6 +12,7 @@ from pathlib import Path from typing import TYPE_CHECKING, TypeVar from dataclasses import dataclass, field +from efro.call import tpartial import _ba if TYPE_CHECKING: @@ -81,23 +82,73 @@ class MetadataSubsystem: self._scan = DirectoryScan( [_ba.app.python_directory_app, _ba.app.python_directory_user]) - Thread(target=self._do_scan_dirs, daemon=True).start() + Thread(target=self._run_scan_in_bg, daemon=True).start() def start_extra_scan(self) -> None: - """Provide extra dirs to be scanned (namely Workspace dirs). + """Proceed to the extra_scan_dirs portion of the scan. - This is the bare minimum part of the scan that must be delayed until - workspaces have been synced/etc. This must be called exactly once. + This is for parts of the scan that must be delayed until + workspace sync completion or other such events. This must be + called exactly once. """ assert self._scan is not None self._scan.set_extras(self.extra_scan_dirs) - def wait_for_scan_results(self) -> ScanResults: + def load_exported_classes( + self, + cls: type[T], + completion_cb: Callable[[list[type[T]]], None], + completion_cb_in_bg_thread: bool = False, + ) -> None: + """High level function to load meta-exported classes. + + Will wait for scanning to complete if necessary, and will load all + registered classes of a particular type in a background thread before + calling the passed callback in the logic thread. Errors may be logged + to messaged to the user in some way but the callback will be called + regardless. + To run the completion callback directly in the bg thread where the + loading work happens, pass completion_cb_in_bg_thread=True. + """ + Thread( + target=tpartial(self._load_exported_classes, cls, completion_cb, + completion_cb_in_bg_thread), + daemon=True, + ).start() + + def _load_exported_classes( + self, + cls: type[T], + completion_cb: Callable[[list[type[T]]], None], + completion_cb_in_bg_thread: bool, + ) -> None: + from ba._general import getclass + classes: list[type[T]] = [] + try: + classnames = self._wait_for_scan_results().exports_of_class(cls) + for classname in classnames: + try: + classes.append(getclass(classname, cls)) + except Exception: + logging.exception('error importing %s', classname) + + except Exception: + logging.exception('Error loading exported classes.') + + completion_call = tpartial(completion_cb, classes) + if completion_cb_in_bg_thread: + completion_call() + else: + _ba.pushcall(completion_call, from_other_thread=True) + + def _wait_for_scan_results(self) -> ScanResults: """Return scan results, blocking if the scan is not yet complete.""" if self.scanresults is None: - logging.warning('ba.meta.wait_for_scan_results()' - ' called before scan completed;' - ' this can cause hitches.') + if _ba.in_game_thread(): + logging.warning( + 'ba.meta._wait_for_scan_results()' + ' called in logic thread before scan completed;' + ' this can cause hitches.') # Now wait a bit for the scan to complete. # Eventually error though if it doesn't. @@ -109,6 +160,20 @@ class MetadataSubsystem: 'timeout waiting for meta scan to complete.') return self.scanresults + def _run_scan_in_bg(self) -> None: + """Runs a scan (for use in background thread).""" + try: + assert self._scan is not None + self._scan.run() + results = self._scan.results + self._scan = None + except Exception as exc: + results = ScanResults(errors=[f'Scan exception: {exc}']) + + # Place results and tell the logic thread they're ready. + self.scanresults = results + _ba.pushcall(self._handle_scan_results, from_other_thread=True) + def _handle_scan_results(self) -> None: """Called in the logic thread with results of a completed scan.""" from ba._language import Lstr @@ -139,20 +204,6 @@ class MetadataSubsystem: assert self._scan_complete_cb is not None self._scan_complete_cb() - def _do_scan_dirs(self) -> None: - """Runs a scan (for use in background thread).""" - try: - assert self._scan is not None - self._scan.run() - results = self._scan.results - self._scan = None - except Exception as exc: - results = ScanResults(errors=[f'Scan exception: {exc}']) - - # Place results and tell the logic thread they're ready. - self.scanresults = results - _ba.pushcall(self._handle_scan_results, from_other_thread=True) - class DirectoryScan: """Scans directories for metadata.""" diff --git a/assets/src/ba_data/python/ba/_multiteamsession.py b/assets/src/ba_data/python/ba/_multiteamsession.py index efc7a421..cfe4a7c9 100644 --- a/assets/src/ba_data/python/ba/_multiteamsession.py +++ b/assets/src/ba_data/python/ba/_multiteamsession.py @@ -94,9 +94,11 @@ class MultiTeamSession(Session): playlist = _playlist.get_default_free_for_all_playlist() # Resolve types and whatnot to get our final playlist. - playlist_resolved = _playlist.filter_playlist(playlist, - sessiontype=type(self), - add_resolved_type=True) + playlist_resolved = _playlist.filter_playlist( + playlist, + sessiontype=type(self), + add_resolved_type=True, + name='default teams' if self.use_teams else 'default ffa') if not playlist_resolved: raise RuntimeError('Playlist contains no valid games.') diff --git a/assets/src/ba_data/python/ba/_playlist.py b/assets/src/ba_data/python/ba/_playlist.py index 848259a2..1550934c 100644 --- a/assets/src/ba_data/python/ba/_playlist.py +++ b/assets/src/ba_data/python/ba/_playlist.py @@ -18,7 +18,8 @@ def filter_playlist(playlist: PlaylistType, sessiontype: type[_session.Session], add_resolved_type: bool = False, remove_unowned: bool = True, - mark_unowned: bool = False) -> PlaylistType: + mark_unowned: bool = False, + name: str = '?') -> PlaylistType: """Return a filtered version of a playlist. Strips out or replaces invalid or unowned game types, makes sure all @@ -139,7 +140,7 @@ def filter_playlist(playlist: PlaylistType, entry['settings'][setting.name] = setting.default goodlist.append(entry) except ImportError as exc: - _ba.log(f'Import failed while scanning playlist: {exc}', + _ba.log(f'Import failed while scanning playlist \'{name}\': {exc}', to_server=False) except Exception: from ba import _error diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index 7bb22e6d..fb7ee327 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -36,7 +36,7 @@ from ba._store import (get_available_sale_time, get_available_purchase_count, get_store_item, get_clean_price, get_unowned_maps, get_unowned_game_types) from ba._tournament import get_tournament_prize_strings -from ba._gameutils import get_trophy_string, get_game_types +from ba._gameutils import get_trophy_string __all__ = [ 'get_unowned_maps', 'get_unowned_game_types', 'get_map_class', @@ -56,6 +56,5 @@ __all__ = [ 'get_default_teams_playlist', 'filter_playlist', 'get_available_sale_time', 'get_available_purchase_count', 'get_store_item_name_translated', 'get_store_item_display_size', 'get_store_layout', 'get_store_item', - 'get_clean_price', 'get_tournament_prize_strings', 'get_trophy_string', - 'get_game_types' + 'get_clean_price', 'get_tournament_prize_strings', 'get_trophy_string' ] diff --git a/assets/src/ba_data/python/bastd/ui/gather/privatetab.py b/assets/src/ba_data/python/bastd/ui/gather/privatetab.py index 4eac79ef..6e35922d 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/privatetab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/privatetab.py @@ -184,7 +184,9 @@ class PrivateGatherTab(GatherTab): if playlist is None: playlist = pvars.get_default_list_call() - hcfg.playlist = filter_playlist(playlist, sessiontype) + hcfg.playlist = filter_playlist(playlist, + sessiontype, + name=playlist_name) randomize = cfg.get(f'{pvars.config_name} Playlist Randomize') if not isinstance(randomize, bool): diff --git a/assets/src/ba_data/python/bastd/ui/playlist/addgame.py b/assets/src/ba_data/python/bastd/ui/playlist/addgame.py index 065749c4..728c270b 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/addgame.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/addgame.py @@ -116,10 +116,39 @@ class PlaylistAddGameWindow(ba.Window): ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) + self._game_types: list[type[ba.GameActivity]] = [] + + # Get actual games loading in the bg. + ba.app.meta.load_exported_classes(ba.GameActivity, + self._on_game_types_loaded, + completion_cb_in_bg_thread=True) + + # Refresh with our initial empty list. We'll refresh again once + # game loading is complete. self._refresh() + def _on_game_types_loaded(self, + gametypes: list[type[ba.GameActivity]]) -> None: + from ba.internal import get_unowned_game_types + + # We asked for a bg thread completion cb so we can do some + # filtering here in the bg thread where its not gonna cause hitches. + assert not _ba.in_game_thread() + sessiontype = self._editcontroller.get_session_type() + unowned = get_unowned_game_types() + self._game_types = [ + gt for gt in gametypes + if gt not in unowned and gt.supports_session_type(sessiontype) + ] + + # Sort in the current language. + self._game_types.sort(key=lambda g: g.get_display_string().evaluate()) + + # Tell ourself to refresh back in the logic thread. + ba.pushcall(self._refresh, from_other_thread=True) + def _refresh(self, select_get_more_games_button: bool = False) -> None: - from ba.internal import get_game_types + # from ba.internal import get_game_types if self._column is not None: self._column.delete() @@ -128,15 +157,7 @@ class PlaylistAddGameWindow(ba.Window): border=2, margin=0) - gametypes = [ - gt for gt in get_game_types() if gt.supports_session_type( - self._editcontroller.get_session_type()) - ] - - # Sort in the current language. - gametypes.sort(key=lambda g: g.get_display_string().evaluate()) - - for i, gametype in enumerate(gametypes): + for i, gametype in enumerate(self._game_types): def _doit() -> None: if self._select_button: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/browser.py b/assets/src/ba_data/python/bastd/ui/playlist/browser.py index eace126d..5b5270ea 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/browser.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/browser.py @@ -429,7 +429,8 @@ class PlaylistBrowserWindow(ba.Window): playlist = filter_playlist(playlist, self._sessiontype, remove_unowned=False, - mark_unowned=True) + mark_unowned=True, + name=name) for entry in playlist: mapname = entry['settings']['map'] maptype: type[ba.Map] | None diff --git a/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py b/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py index c7801351..664f6499 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py @@ -52,7 +52,8 @@ class PlaylistEditController: appconfig[self._pvars.config_name + ' Playlists'][existing_playlist_name], sessiontype=sessiontype, - remove_unowned=False) + remove_unowned=False, + name=existing_playlist_name) self._edit_ui_selection = None else: if playlist is not None: diff --git a/assets/src/ba_data/python/bastd/ui/playoptions.py b/assets/src/ba_data/python/bastd/ui/playoptions.py index b200aec5..d95731ba 100644 --- a/assets/src/ba_data/python/bastd/ui/playoptions.py +++ b/assets/src/ba_data/python/bastd/ui/playoptions.py @@ -86,7 +86,8 @@ class PlayOptionsWindow(popup.PopupWindow): plst = filter_playlist(plst, self._sessiontype, remove_unowned=False, - mark_unowned=True) + mark_unowned=True, + name=name) game_count = len(plst) for entry in plst: mapname = entry['settings']['map'] diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 9c23a482..1917f74f 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,8 +21,8 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20687; -const char* kAppVersion = "1.7.6"; +const int kAppBuildNumber = 20690; +const char* kAppVersion = "1.7.7"; // Our standalone globals. // These are separated out for easy access. diff --git a/src/ballistica/game/game.cc b/src/ballistica/game/game.cc index 8cf2888f..e2beef2c 100644 --- a/src/ballistica/game/game.cc +++ b/src/ballistica/game/game.cc @@ -1569,7 +1569,10 @@ void Game::SetLanguageKeys( } auto DoCompileResourceString(cJSON* obj) -> std::string { - assert(InGameThread()); + // NOTE: We currently talk to Python here so need to be sure + // we're holding the GIL. Perhaps in the future we could handle this + // stuff completely in C++ and be free of this limitation. + assert(Python::HaveGIL()); assert(obj != nullptr); std::string result; @@ -1707,8 +1710,8 @@ auto DoCompileResourceString(cJSON* obj) -> std::string { if (subs->type != cJSON_Array) { throw Exception("expected an array for 'subs'"); } - int subsCount = cJSON_GetArraySize(subs); - for (int i = 0; i < subsCount; i++) { + int subs_count = cJSON_GetArraySize(subs); + for (int i = 0; i < subs_count; i++) { cJSON* sub = cJSON_GetArrayItem(subs, i); if (sub->type != cJSON_Array || cJSON_GetArraySize(sub) != 2) { throw Exception( @@ -1753,7 +1756,6 @@ auto DoCompileResourceString(cJSON* obj) -> std::string { auto Game::CompileResourceString(const std::string& s, const std::string& loc, bool* valid) -> std::string { - assert(InGameThread()); assert(g_python != nullptr); bool dummyvalid; diff --git a/src/ballistica/python/python.cc b/src/ballistica/python/python.cc index f1e68283..dba85088 100644 --- a/src/ballistica/python/python.cc +++ b/src/ballistica/python/python.cc @@ -1078,7 +1078,7 @@ Python::~Python() { Reset(false); } auto Python::GetResource(const char* key, const char* fallback_resource, const char* fallback_value) -> std::string { - assert(InGameThread()); + assert(HaveGIL()); PythonRef results; BA_PRECONDITION(key != nullptr); const PythonRef& get_resource_call(obj(ObjID::kGetResourceCall)); @@ -1130,7 +1130,7 @@ auto Python::GetResource(const char* key, const char* fallback_resource, auto Python::GetTranslation(const char* category, const char* s) -> std::string { - assert(InGameThread()); + assert(HaveGIL()); PythonRef results; PythonRef args(Py_BuildValue("(ss)", category, s), PythonRef::kSteal); // Don't print errors.