mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-04 14:33:28 +08:00
v1.7.26
This commit is contained in:
parent
4cf54d4f85
commit
82aa76b29b
92
.efrocachemap
generated
92
.efrocachemap
generated
@ -4064,54 +4064,54 @@
|
|||||||
"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": "2ce43921f1917e4face2bd89de255c89",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "bb5e0df17efe96476c3c2b8c41c7979b",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "cfad36d58003989bd3fb758d72900914",
|
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "056115be35ac1afc1f62b58dcc8f217a",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "11a8f7317dafd295f43e5b8573b21caa",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "cf2b052caaa06d512ef379687b3aff86",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "dca6448b3d8f3acd46632f103d270b38",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "97b8d5f261f84b8047d43df1ca81777a",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "dcf48e1ee93b7a747b0c33efca58057a",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f304ee46675e7552c31e174d81199307",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "b568da36b6a2ee329e31ff321df54810",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "70b54361b557f5e8d4271a0c976b28b6",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b9e6b511c5fea84b0a81335fd3000592",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "06c778dc4c2772acf6dbaf67eb7321c9",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "ec94eec1e4c1084535c65e9923de87d6",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "212a5c7206c1aa9a8427b61471e9e89b",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "d53c169951686dd96a85668def6dbbfc",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f3a1028602c7bbd3f8d62bd843af628d",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "b46e409cb87de94f6cf6f7d3e10e032f",
|
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "9c4c6d1c50e225dc61cfbab4a82a37a6",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "4692a22e7ddaf15e34157325252b5fb3",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "4db4b600478f1767fdd0462a137912de",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "d0ab73deaa89dd9fa1b75c65d463d293",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "628bc102cf6ef17b38804c4c9baa5265",
|
||||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "3db746bb01e002fee667c70c6f57f928",
|
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "fb9d165ab24084e8beaa6d7c51c81a77",
|
||||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "10c06bd2c02a9b2ac488993e2ffc6700",
|
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ae88283e96a9238aab7561d2afcd9a5f",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "01a466465933b84f3772e9d274ee9c40",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "e5fe958377b8dcf5d5203dbd17aaab72",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "3d3233606e03eb3b8ffe04169a5f2fce",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "f22e8af184b19b4929162e901a056454",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "c59aeaf8686b4008d0b11728a0523397",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "5fa2cb24b9e78bddb1bf9efb197d0c51",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "92dcffd261cfe8bf80806ebc765bb323",
|
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "d36f11acfa5e68f303d347c3895979d0",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "57639e6862d409cf39ad2fd609aafb20",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "570a7e325c15ecebcc419d48a046dd24",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "fa7a86c50be523dcb7ff6aadb9d79d0e",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "3155f665993e5f850db5b87c9296abe7",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d16860bc4d3ff0abae745e2fd5638149",
|
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "d1bfae5e75824ba89338892bc0f84c6b",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "620ed03a89ad8053656a466da6053676",
|
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "b1466048e319c0d60139c46751f3eb79",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d16860bc4d3ff0abae745e2fd5638149",
|
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "d1bfae5e75824ba89338892bc0f84c6b",
|
||||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "620ed03a89ad8053656a466da6053676",
|
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "b1466048e319c0d60139c46751f3eb79",
|
||||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "642d380b38d5fd4a5f50a331579e6e9c",
|
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "656176631037184b6e22b0b68c3cd1fa",
|
||||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "a767b4b9d20e61e0a6fb7289660959e9",
|
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "12b633db4dad37bbb5a5c398db0c10dd",
|
||||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "642d380b38d5fd4a5f50a331579e6e9c",
|
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "656176631037184b6e22b0b68c3cd1fa",
|
||||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "a767b4b9d20e61e0a6fb7289660959e9",
|
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "12b633db4dad37bbb5a5c398db0c10dd",
|
||||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "fecd29b4aff2924b2403f36996cdca93",
|
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "7e014214c6cb9ddaa0e95f5186ba9df6",
|
||||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "9aea5093bb559d64e28edc3c112b06b2",
|
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "45ddc559dd5ef563d2df5c5db9c9fbc0",
|
||||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "fecd29b4aff2924b2403f36996cdca93",
|
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "7e014214c6cb9ddaa0e95f5186ba9df6",
|
||||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "9aea5093bb559d64e28edc3c112b06b2",
|
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "45ddc559dd5ef563d2df5c5db9c9fbc0",
|
||||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "8ce1ea0d1d64dac282100599159ad2a3",
|
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "1a15bf7d809addab4992827da9d89895",
|
||||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "adf78a2ab5fb271d83e80fb72b68784f",
|
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "a1e03b7d13482beab8852691b5698974",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "864807f34140eed4dada8832878a1173",
|
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "807e3629d9d4611cd93feb87face4e51",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "adf78a2ab5fb271d83e80fb72b68784f",
|
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "a1e03b7d13482beab8852691b5698974",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "8d271eb87a692db53219288d762a5194",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "7f7bc04993982b164f6e86ad6ce350ef",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "3a2e88e7788e47cc86ac87df0ea46ce3",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "d24102dd35c29b6a77cdf3d9921695da",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "d0db9d64f7ff618cb6a62f59a70a00f0",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "8edef08a22594617d2b4273e0e4cba40",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "308f59dbc2f3193b1adb321db9a09ff1",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "cb6c0c6efad034b53fe1a8f930f2ce81",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "d66fe8cbfcd4d472ff3536c274f2a8d4",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "3ec4aadf128132116fc5479a46bd1f71",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "89d7812f28754a00ad797bb994c81846",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "14c2cf0812e3022391caffd9409d0650",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "ea8906f5c66ba5606bff77e8e57f3ade",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "67c207425afc5023cea9740e3bd459c3",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "d117fce0b21244310ce6771a29c237be",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "7219b9034f14c5b769818b80135ea61b",
|
||||||
"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": "ad5475b871dadc69bc2cf8ccac550878",
|
"src/ballistica/base/mgen/pyembed/binding_base.inc": "ad347097a38e0d7ede9eb6dec6a80ee9",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "ef931ec35861d4ad37850b7278588922",
|
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "077bf63282b23d1880287200c9f6035f",
|
||||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
|
||||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
||||||
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
### 1.7.26 (build 21250, api 8, 2023-08-23)
|
### 1.7.26 (build 21256, api 8, 2023-08-25)
|
||||||
|
|
||||||
- Android should now be better at detecting hardware keyboards (you will see
|
- Android should now be better at detecting hardware keyboards (you will see
|
||||||
'Configure Keyboard' and 'Configure Keyboard P2' buttons under
|
'Configure Keyboard' and 'Configure Keyboard P2' buttons under
|
||||||
@ -24,14 +24,19 @@
|
|||||||
functionality, but rather adapt the app to a particular paradigm or api (VR,
|
functionality, but rather adapt the app to a particular paradigm or api (VR,
|
||||||
Headless, SDL GUI, etc.). Also am trying to move any functionality out of
|
Headless, SDL GUI, etc.). Also am trying to move any functionality out of
|
||||||
those classes that does not fit that definition.
|
those classes that does not fit that definition.
|
||||||
- Started cleaning up the app exit process. This will allow the app to
|
- Started cleaning up the app shutdown process. This will allow the app to
|
||||||
gracefully run tasks such as syncing account data to the cloud or disk or
|
gracefully run tasks such as syncing account data to the cloud or disk or
|
||||||
properly closing the audio system when shutting down. It also means there
|
properly closing the audio system when shutting down. It also means there
|
||||||
should be more consistent use of the 'Quit?' confirm window. Please holler if
|
should be more consistent use of the 'Quit?' confirm window. Please holler if
|
||||||
you see any odd behavior when trying to quit the app.
|
you see any odd behavior when trying to quit the app.
|
||||||
|
- Unix TERM signal now triggers graceful app shutdown.
|
||||||
- Added `ba.app.add_shutdown_task()` to register coroutines to be run as part of
|
- Added `ba.app.add_shutdown_task()` to register coroutines to be run as part of
|
||||||
shutdown.
|
shutdown.
|
||||||
- Removed `babase.app.iircade_mode`. RIP iiRcade :(.
|
- Removed `babase.app.iircade_mode`. RIP iiRcade :(.
|
||||||
|
- Changed `AppState.INITIAL` to `AppState.NOT_RUNNING`, added a
|
||||||
|
`AppState.NATIVE_BOOTSTRAPPING`, and changed `AppState.LAUNCHING` to
|
||||||
|
`AppState.INITING`. These better describe what the app is actually doing while
|
||||||
|
in those states.
|
||||||
|
|
||||||
### 1.7.25 (build 21211, api 8, 2023-08-03)
|
### 1.7.25 (build 21211, api 8, 2023-08-03)
|
||||||
|
|
||||||
|
|||||||
@ -128,7 +128,7 @@ class AccountV2Subsystem:
|
|||||||
# Ok; no workspace to worry about; carry on.
|
# Ok; no workspace to worry about; carry on.
|
||||||
if not self._initial_sign_in_completed:
|
if not self._initial_sign_in_completed:
|
||||||
self._initial_sign_in_completed = True
|
self._initial_sign_in_completed = True
|
||||||
_babase.app.on_initial_sign_in_completed()
|
_babase.app.on_initial_sign_in_complete()
|
||||||
|
|
||||||
def on_active_logins_changed(self, logins: dict[LoginType, str]) -> None:
|
def on_active_logins_changed(self, logins: dict[LoginType, str]) -> None:
|
||||||
"""Should be called when logins for the active account change."""
|
"""Should be called when logins for the active account change."""
|
||||||
@ -163,7 +163,7 @@ class AccountV2Subsystem:
|
|||||||
"""
|
"""
|
||||||
if not self._initial_sign_in_completed:
|
if not self._initial_sign_in_completed:
|
||||||
self._initial_sign_in_completed = True
|
self._initial_sign_in_completed = True
|
||||||
_babase.app.on_initial_sign_in_completed()
|
_babase.app.on_initial_sign_in_complete()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _hashstr(val: str) -> str:
|
def _hashstr(val: str) -> str:
|
||||||
@ -409,7 +409,7 @@ class AccountV2Subsystem:
|
|||||||
def _on_set_active_workspace_completed(self) -> None:
|
def _on_set_active_workspace_completed(self) -> None:
|
||||||
if not self._initial_sign_in_completed:
|
if not self._initial_sign_in_completed:
|
||||||
self._initial_sign_in_completed = True
|
self._initial_sign_in_completed = True
|
||||||
_babase.app.on_initial_sign_in_completed()
|
_babase.app.on_initial_sign_in_complete()
|
||||||
|
|
||||||
|
|
||||||
class AccountV2Handle:
|
class AccountV2Handle:
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from enum import Enum
|
|
||||||
import logging
|
import logging
|
||||||
|
from enum import Enum
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
@ -58,31 +58,41 @@ class App:
|
|||||||
|
|
||||||
health_monitor: AppHealthMonitor
|
health_monitor: AppHealthMonitor
|
||||||
|
|
||||||
|
# How long we allow shutdown tasks to run before killing them.
|
||||||
|
# Currently the entire app hard-exits if shutdown takes 10 seconds,
|
||||||
|
# so we need to keep it under that.
|
||||||
|
SHUTDOWN_TASK_TIMEOUT_SECONDS = 5
|
||||||
|
|
||||||
class State(Enum):
|
class State(Enum):
|
||||||
"""High level state the app can be in."""
|
"""High level state the app can be in."""
|
||||||
|
|
||||||
# Waiting on the native layer to finish spinning up; our launch
|
# The app has not yet begun starting and should not be used in
|
||||||
# process here has not yet started.
|
# any way.
|
||||||
BOOTSTRAPPING = 0
|
NOT_RUNNING = 'not_running'
|
||||||
|
|
||||||
# Our app subsystems are being inited but should not yet
|
# The native layer is spinning up its machinery (screens,
|
||||||
# interact.
|
# renderers, etc.). Nothing should happen in the Python layer
|
||||||
LAUNCHING = 1
|
# until this completes.
|
||||||
|
NATIVE_BOOTSTRAPPING = 'native_bootstrapping'
|
||||||
|
|
||||||
# App subsystems are inited and interacting, but the app has not
|
# Python app subsystems are being inited but should not yet
|
||||||
# yet embarked on a high level course of action. It is doing
|
# interact or do any work.
|
||||||
# initial account logins, workspace & asset downloads, etc. in
|
INITING = 'initing'
|
||||||
# order to prepare for this.
|
|
||||||
LOADING = 2
|
# Python app subsystems are inited and interacting, but the app
|
||||||
|
# has not yet embarked on a high level course of action. It is
|
||||||
|
# doing initial account logins, workspace & asset downloads,
|
||||||
|
# etc.
|
||||||
|
LOADING = 'loading'
|
||||||
|
|
||||||
# All pieces are in place and the app is now doing its thing.
|
# All pieces are in place and the app is now doing its thing.
|
||||||
RUNNING = 3
|
RUNNING = 'running'
|
||||||
|
|
||||||
# The app is backgrounded or otherwise suspended.
|
# The app is backgrounded or otherwise suspended.
|
||||||
PAUSED = 4
|
PAUSED = 'paused'
|
||||||
|
|
||||||
# The app is shutting down.
|
# The app is shutting down.
|
||||||
SHUTTING_DOWN = 5
|
SHUTTING_DOWN = 'shutting_down'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def aioloop(self) -> asyncio.AbstractEventLoop:
|
def aioloop(self) -> asyncio.AbstractEventLoop:
|
||||||
@ -236,19 +246,20 @@ class App:
|
|||||||
if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1':
|
if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1':
|
||||||
return
|
return
|
||||||
|
|
||||||
self.state = self.State.BOOTSTRAPPING
|
self.state = self.State.NOT_RUNNING
|
||||||
|
|
||||||
self._subsystems: list[AppSubsystem] = []
|
self._subsystems: list[AppSubsystem] = []
|
||||||
|
|
||||||
self._native_bootstrapped = False
|
self._native_bootstrapping_completed = False
|
||||||
|
self._init_completed = False
|
||||||
|
self._meta_scan_completed = False
|
||||||
|
self._native_start_called = False
|
||||||
self._native_paused = False
|
self._native_paused = False
|
||||||
self._native_shutdown_called = False
|
self._native_shutdown_called = False
|
||||||
self._launch_completed = False
|
|
||||||
self._initial_sign_in_completed = False
|
self._initial_sign_in_completed = False
|
||||||
self._meta_scan_completed = False
|
self._called_on_initing = False
|
||||||
self._called_on_app_launching = False
|
self._called_on_loading = False
|
||||||
self._called_on_app_loading = False
|
self._called_on_running = False
|
||||||
self._called_on_app_running = False
|
|
||||||
self._subsystem_registration_ended = False
|
self._subsystem_registration_ended = False
|
||||||
self._pending_apply_app_config = False
|
self._pending_apply_app_config = False
|
||||||
|
|
||||||
@ -484,13 +495,13 @@ class App:
|
|||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run the app to completion.
|
"""Run the app to completion.
|
||||||
|
|
||||||
Note that this only works on platforms where ballistica
|
Note that this only works on platforms where Ballistica
|
||||||
manages its own event loop.
|
manages its own event loop.
|
||||||
"""
|
"""
|
||||||
_babase.run_app()
|
_babase.run_app()
|
||||||
|
|
||||||
def _on_app_launching(self) -> None:
|
def _on_initing(self) -> None:
|
||||||
"""Called when the app enters the launching state.
|
"""Called when the app enters the initing state.
|
||||||
|
|
||||||
Here we can put together subsystems and other pieces for the
|
Here we can put together subsystems and other pieces for the
|
||||||
app, but most things should not be doing any work yet.
|
app, but most things should not be doing any work yet.
|
||||||
@ -503,7 +514,7 @@ class App:
|
|||||||
|
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
_env.on_app_launching()
|
_env.on_app_state_initing()
|
||||||
|
|
||||||
self._aioloop = _asyncio.setup_asyncio()
|
self._aioloop = _asyncio.setup_asyncio()
|
||||||
self.health_monitor = AppHealthMonitor()
|
self.health_monitor = AppHealthMonitor()
|
||||||
@ -531,28 +542,25 @@ class App:
|
|||||||
|
|
||||||
# __FEATURESET_APP_SUBSYSTEM_CREATE_END__
|
# __FEATURESET_APP_SUBSYSTEM_CREATE_END__
|
||||||
|
|
||||||
self._launch_completed = True
|
# We're a pretty short-lived state. This should flip us to
|
||||||
|
# 'loading'.
|
||||||
|
self._init_completed = True
|
||||||
self._update_state()
|
self._update_state()
|
||||||
|
|
||||||
def _on_app_loading(self) -> None:
|
def _on_loading(self) -> None:
|
||||||
"""Called when the app enters the loading state.
|
"""Called when we enter the loading state.
|
||||||
|
|
||||||
At this point, all built-in pieces of the app should be in place
|
At this point, all built-in pieces of the app should be in place
|
||||||
and can start doing 'work'. Though at a high level, the goal of
|
and can start talking to each other and doing work. Though at a
|
||||||
the app at this point is only to sign in to initial accounts,
|
high level, the goal of the app at this point is only to sign in
|
||||||
download workspaces, and otherwise prepare itself to really
|
to initial accounts, download workspaces, and otherwise prepare
|
||||||
'run'.
|
itself to really 'run'.
|
||||||
"""
|
"""
|
||||||
from babase._apputils import log_dumped_app_state
|
|
||||||
|
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
# Get meta-system scanning built-in stuff in the bg.
|
# Get meta-system scanning built-in stuff in the bg.
|
||||||
self.meta.start_scan(scan_complete_cb=self._on_meta_scan_complete)
|
self.meta.start_scan(scan_complete_cb=self._on_meta_scan_complete)
|
||||||
|
|
||||||
# If any traceback dumps happened last run, log and clear them.
|
|
||||||
log_dumped_app_state()
|
|
||||||
|
|
||||||
# Inform all app subsystems in the same order they were inited.
|
# Inform all app subsystems in the same order they were inited.
|
||||||
# Operate on a copy here because subsystems can still be added
|
# Operate on a copy here because subsystems can still be added
|
||||||
# at this point.
|
# at this point.
|
||||||
@ -568,7 +576,7 @@ class App:
|
|||||||
# is not present, however, we just do it ourself so we can
|
# is not present, however, we just do it ourself so we can
|
||||||
# proceed on to the running state.
|
# proceed on to the running state.
|
||||||
if self.plus is None:
|
if self.plus is None:
|
||||||
_babase.pushcall(self.on_initial_sign_in_completed)
|
_babase.pushcall(self.on_initial_sign_in_complete)
|
||||||
|
|
||||||
def _on_meta_scan_complete(self) -> None:
|
def _on_meta_scan_complete(self) -> None:
|
||||||
"""Called when meta-scan is done doing its thing."""
|
"""Called when meta-scan is done doing its thing."""
|
||||||
@ -581,8 +589,8 @@ class App:
|
|||||||
self._meta_scan_completed = True
|
self._meta_scan_completed = True
|
||||||
self._update_state()
|
self._update_state()
|
||||||
|
|
||||||
def _on_app_running(self) -> None:
|
def _on_running(self) -> None:
|
||||||
"""Called when the app enters the running state.
|
"""Called when we enter the running state.
|
||||||
|
|
||||||
At this point, all workspaces, initial accounts, etc. are in place
|
At this point, all workspaces, initial accounts, etc. are in place
|
||||||
and we can actually get started doing whatever we're gonna do.
|
and we can actually get started doing whatever we're gonna do.
|
||||||
@ -704,51 +712,61 @@ class App:
|
|||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
# Can't shut down until we've got our asyncio machinery spun up.
|
# Shutdown trumps all. Though we can't shut down until init is
|
||||||
if self._native_shutdown_called and self._aioloop is not None:
|
# completed since we need our asyncio stuff to exist for the
|
||||||
|
# shutdown process.
|
||||||
|
if self._native_shutdown_called and self._init_completed:
|
||||||
# Entering shutdown state:
|
# Entering shutdown state:
|
||||||
if self.state is not self.State.SHUTTING_DOWN:
|
if self.state is not self.State.SHUTTING_DOWN:
|
||||||
self.state = self.State.SHUTTING_DOWN
|
self.state = self.State.SHUTTING_DOWN
|
||||||
self._on_app_shutdown()
|
self._on_shutting_down()
|
||||||
|
|
||||||
elif self._native_paused:
|
elif self._native_paused:
|
||||||
# Entering paused state:
|
# Entering paused state:
|
||||||
if self.state is not self.State.PAUSED:
|
if self.state is not self.State.PAUSED:
|
||||||
self.state = self.State.PAUSED
|
self.state = self.State.PAUSED
|
||||||
self._on_app_pause()
|
self._on_pause()
|
||||||
else:
|
else:
|
||||||
# Leaving paused state:
|
# Leaving paused state:
|
||||||
if self.state is self.State.PAUSED:
|
if self.state is self.State.PAUSED:
|
||||||
self._on_app_resume()
|
self._on_resume()
|
||||||
|
|
||||||
# Handle initially entering or returning to other states.
|
# Handle initially entering or returning to other states.
|
||||||
if self._initial_sign_in_completed and self._meta_scan_completed:
|
if self._initial_sign_in_completed and self._meta_scan_completed:
|
||||||
if self.state != self.State.RUNNING:
|
if self.state != self.State.RUNNING:
|
||||||
self.state = self.State.RUNNING
|
self.state = self.State.RUNNING
|
||||||
_babase.lifecyclelog('app state running')
|
_babase.lifecyclelog('app state running')
|
||||||
if not self._called_on_app_running:
|
if not self._called_on_running:
|
||||||
self._called_on_app_running = True
|
self._called_on_running = True
|
||||||
self._on_app_running()
|
self._on_running()
|
||||||
elif self._launch_completed:
|
elif self._init_completed:
|
||||||
if self.state is not self.State.LOADING:
|
if self.state is not self.State.LOADING:
|
||||||
self.state = self.State.LOADING
|
self.state = self.State.LOADING
|
||||||
_babase.lifecyclelog('app state loading')
|
_babase.lifecyclelog('app state loading')
|
||||||
if not self._called_on_app_loading:
|
if not self._called_on_loading:
|
||||||
self._called_on_app_loading = True
|
self._called_on_loading = True
|
||||||
self._on_app_loading()
|
self._on_loading()
|
||||||
|
elif self._native_bootstrapping_completed:
|
||||||
|
if self.state is not self.State.INITING:
|
||||||
|
self.state = self.State.INITING
|
||||||
|
_babase.lifecyclelog('app state initing')
|
||||||
|
if not self._called_on_initing:
|
||||||
|
self._called_on_initing = True
|
||||||
|
self._on_initing()
|
||||||
else:
|
else:
|
||||||
# Only thing left is launching. We shouldn't be getting
|
# Only possibility left is app-start. We shouldn't be
|
||||||
# called before at least that is complete.
|
# getting called before at least that happens.
|
||||||
assert self._native_bootstrapped
|
assert self._native_start_called
|
||||||
if self.state is not self.State.LAUNCHING:
|
assert self.state is self.State.NOT_RUNNING
|
||||||
self.state = self.State.LAUNCHING
|
if bool(True):
|
||||||
_babase.lifecyclelog('app state launching')
|
self.state = self.State.NATIVE_BOOTSTRAPPING
|
||||||
if not self._called_on_app_launching:
|
|
||||||
self._called_on_app_launching = True
|
|
||||||
self._on_app_launching()
|
|
||||||
|
|
||||||
def add_shutdown_task(self, coro: Coroutine[None, None, None]) -> None:
|
def add_shutdown_task(self, coro: Coroutine[None, None, None]) -> None:
|
||||||
"""Add a task to be run on app shutdown."""
|
"""Add a task to be run on app shutdown.
|
||||||
|
|
||||||
|
Note that tasks will be killed after
|
||||||
|
App.SHUTDOWN_TASK_TIMEOUT_SECONDS if they are still running.
|
||||||
|
"""
|
||||||
if self.state is self.State.SHUTTING_DOWN:
|
if self.state is self.State.SHUTTING_DOWN:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'Cannot add shutdown tasks with state SHUTTING_DOWN.'
|
'Cannot add shutdown tasks with state SHUTTING_DOWN.'
|
||||||
@ -780,15 +798,22 @@ class App:
|
|||||||
|
|
||||||
task = asyncio.create_task(coro)
|
task = asyncio.create_task(coro)
|
||||||
try:
|
try:
|
||||||
await asyncio.wait_for(task, 5.0)
|
await asyncio.wait_for(task, self.SHUTDOWN_TASK_TIMEOUT_SECONDS)
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.exception('Error in shutdown task.')
|
logging.exception('Error in shutdown task.')
|
||||||
|
|
||||||
def on_native_bootstrapped(self) -> None:
|
def on_native_start(self) -> None:
|
||||||
|
"""Called by the native layer when the app is being started."""
|
||||||
|
assert _babase.in_logic_thread()
|
||||||
|
assert not self._native_start_called
|
||||||
|
self._native_start_called = True
|
||||||
|
self._update_state()
|
||||||
|
|
||||||
|
def on_native_bootstrapping_complete(self) -> None:
|
||||||
"""Called by the native layer once its ready to rock."""
|
"""Called by the native layer once its ready to rock."""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
assert not self._native_bootstrapped
|
assert not self._native_bootstrapping_completed
|
||||||
self._native_bootstrapped = True
|
self._native_bootstrapping_completed = True
|
||||||
self._update_state()
|
self._update_state()
|
||||||
|
|
||||||
def on_native_pause(self) -> None:
|
def on_native_pause(self) -> None:
|
||||||
@ -811,7 +836,7 @@ class App:
|
|||||||
self._native_shutdown_called = True
|
self._native_shutdown_called = True
|
||||||
self._update_state()
|
self._update_state()
|
||||||
|
|
||||||
def _on_app_pause(self) -> None:
|
def _on_pause(self) -> None:
|
||||||
"""Called when the app goes to a paused state."""
|
"""Called when the app goes to a paused state."""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
@ -824,7 +849,7 @@ class App:
|
|||||||
'Error in on_app_pause for subsystem %s.', subsystem
|
'Error in on_app_pause for subsystem %s.', subsystem
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_app_resume(self) -> None:
|
def _on_resume(self) -> None:
|
||||||
"""Called when resuming."""
|
"""Called when resuming."""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
self.fg_state += 1
|
self.fg_state += 1
|
||||||
@ -838,7 +863,7 @@ class App:
|
|||||||
'Error in on_app_resume for subsystem %s.', subsystem
|
'Error in on_app_resume for subsystem %s.', subsystem
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_app_shutdown(self) -> None:
|
def _on_shutting_down(self) -> None:
|
||||||
"""(internal)"""
|
"""(internal)"""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
@ -882,7 +907,7 @@ class App:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_initial_sign_in_completed(self) -> None:
|
def on_initial_sign_in_complete(self) -> None:
|
||||||
"""Called when initial sign-in (or lack thereof) completes.
|
"""Called when initial sign-in (or lack thereof) completes.
|
||||||
|
|
||||||
This normally gets called by the plus subsystem. The
|
This normally gets called by the plus subsystem. The
|
||||||
|
|||||||
@ -378,6 +378,10 @@ class AppHealthMonitor(AppSubsystem):
|
|||||||
self._response = False
|
self._response = False
|
||||||
self._first_check = True
|
self._first_check = True
|
||||||
|
|
||||||
|
def on_app_loading(self) -> None:
|
||||||
|
# If any traceback dumps happened last run, log and clear them.
|
||||||
|
log_dumped_app_state()
|
||||||
|
|
||||||
def _app_monitor_thread_main(self) -> None:
|
def _app_monitor_thread_main(self) -> None:
|
||||||
try:
|
try:
|
||||||
self._monitor_app()
|
self._monitor_app()
|
||||||
|
|||||||
@ -149,14 +149,15 @@ def on_main_thread_start_app() -> None:
|
|||||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
def on_app_launching() -> None:
|
def on_app_state_initing() -> None:
|
||||||
"""Called when the app reaches the launching state."""
|
"""Called when the app reaches the initing state."""
|
||||||
import _babase
|
import _babase
|
||||||
import baenv
|
import baenv
|
||||||
|
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
# Let the user know if the app Python dir is a 'user' one.
|
# Let the user know if the app Python dir is a 'user' one. This is a
|
||||||
|
# risky thing to be doing so don't let them forget they're doing it.
|
||||||
envconfig = baenv.get_config()
|
envconfig = baenv.get_config()
|
||||||
if envconfig.is_user_app_python_dir:
|
if envconfig.is_user_app_python_dir:
|
||||||
_babase.screenmessage(
|
_babase.screenmessage(
|
||||||
@ -192,12 +193,13 @@ def _feed_logs_to_babase(log_handler: LogHandler) -> None:
|
|||||||
# cache. This will feed the engine any logs that happened between
|
# cache. This will feed the engine any logs that happened between
|
||||||
# baenv.configure() and now.
|
# baenv.configure() and now.
|
||||||
|
|
||||||
# FIXME: while this works for now, the downside is that these
|
# FIXME: while this setup works for now, the downside is that these
|
||||||
# callbacks fire in a bg thread so certain things like android
|
# callbacks fire in a bg thread so certain things like android
|
||||||
# logging will be delayed compared to code that uses native logging
|
# logging will be delayed relative to code that uses native logging
|
||||||
# calls directly. Perhaps we should add some sort of 'immediate'
|
# calls directly. Ideally we should add some sort of 'immediate'
|
||||||
# callback option to better handle such cases (similar to the
|
# callback option to better handle such cases (analogous to the
|
||||||
# immediate echofile stderr print that already occurs).
|
# immediate echofile stderr print that LogHandler already
|
||||||
|
# supports).
|
||||||
log_handler.add_callback(_on_log, feed_existing_logs=True)
|
log_handler.add_callback(_on_log, feed_existing_logs=True)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -81,7 +81,7 @@ class PluginSubsystem(AppSubsystem):
|
|||||||
config_changed = True
|
config_changed = True
|
||||||
found_new = True
|
found_new = True
|
||||||
|
|
||||||
# If we're *not* auto-enabling, just let the user know if we
|
# If we're *not* auto-enabling, simply let the user know if we
|
||||||
# found new ones.
|
# found new ones.
|
||||||
if found_new and not auto_enable_new_plugins:
|
if found_new and not auto_enable_new_plugins:
|
||||||
_babase.screenmessage(
|
_babase.screenmessage(
|
||||||
@ -131,10 +131,10 @@ class PluginSubsystem(AppSubsystem):
|
|||||||
disappeared_plugs.add(class_path)
|
disappeared_plugs.add(class_path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If plugins disappeared, let the user know gently and remove them
|
# If plugins disappeared, let the user know gently and remove
|
||||||
# from the config so we'll again let the user know if they later
|
# them from the config so we'll again let the user know if they
|
||||||
# reappear. This makes it much smoother to switch between users
|
# later reappear. This makes it much smoother to switch between
|
||||||
# or workspaces.
|
# users or workspaces.
|
||||||
if disappeared_plugs:
|
if disappeared_plugs:
|
||||||
_babase.getsimplesound('shieldDown').play()
|
_babase.getsimplesound('shieldDown').play()
|
||||||
_babase.screenmessage(
|
_babase.screenmessage(
|
||||||
@ -217,7 +217,7 @@ class PluginSpec:
|
|||||||
key. Remember to commit the app-config after making any changes.
|
key. Remember to commit the app-config after making any changes.
|
||||||
|
|
||||||
The 'attempted_load' attr will be True if the engine has attempted
|
The 'attempted_load' attr will be True if the engine has attempted
|
||||||
to load the plugin. If 'attempted_load' is True for a plugin-spec
|
to load the plugin. If 'attempted_load' is True for a PluginSpec
|
||||||
but the 'plugin' attr is None, it means there was an error loading
|
but the 'plugin' attr is None, it means there was an error loading
|
||||||
the plugin. If a plugin's api-version does not match the running
|
the plugin. If a plugin's api-version does not match the running
|
||||||
app, if a new plugin is detected with auto-enable-plugins disabled,
|
app, if a new plugin is detected with auto-enable-plugins disabled,
|
||||||
@ -249,7 +249,7 @@ class PluginSpec:
|
|||||||
plugstate['enabled'] = val
|
plugstate['enabled'] = val
|
||||||
|
|
||||||
def attempt_load_if_enabled(self) -> Plugin | None:
|
def attempt_load_if_enabled(self) -> Plugin | None:
|
||||||
"""Possibly load the plugin and report errors."""
|
"""Possibly load the plugin and log any errors."""
|
||||||
from babase._general import getclass
|
from babase._general import getclass
|
||||||
from babase._language import Lstr
|
from babase._language import Lstr
|
||||||
|
|
||||||
@ -308,8 +308,8 @@ class Plugin:
|
|||||||
Category: **App Classes**
|
Category: **App Classes**
|
||||||
|
|
||||||
Plugins are discoverable by the meta-tag system
|
Plugins are discoverable by the meta-tag system
|
||||||
and the user can select which ones they want to activate.
|
and the user can select which ones they want to enable.
|
||||||
Active plugins are then called at specific times as the
|
Enabled plugins are then called at specific times as the
|
||||||
app is running in order to modify its behavior in some way.
|
app is running in order to modify its behavior in some way.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import threading
|
import logging
|
||||||
import weakref
|
import weakref
|
||||||
|
import threading
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
@ -36,7 +37,9 @@ class MasterServerV1CallThread(threading.Thread):
|
|||||||
callback: MasterServerCallback | None,
|
callback: MasterServerCallback | None,
|
||||||
response_type: MasterServerResponseType,
|
response_type: MasterServerResponseType,
|
||||||
):
|
):
|
||||||
super().__init__()
|
# Set daemon=True so long-running requests don't keep us from
|
||||||
|
# quitting the app.
|
||||||
|
super().__init__(daemon=True)
|
||||||
self._request = request
|
self._request = request
|
||||||
self._request_type = request_type
|
self._request_type = request_type
|
||||||
if not isinstance(response_type, MasterServerResponseType):
|
if not isinstance(response_type, MasterServerResponseType):
|
||||||
@ -76,6 +79,16 @@ class MasterServerV1CallThread(threading.Thread):
|
|||||||
|
|
||||||
from efro.error import is_urllib_communication_error
|
from efro.error import is_urllib_communication_error
|
||||||
|
|
||||||
|
# If the app is going down, this is a no-op. Trying to avoid the
|
||||||
|
# rare odd crash I see from (presumably) SSL stuff getting used
|
||||||
|
# while the app is being torn down.
|
||||||
|
if babase.app.state is babase.app.State.SHUTTING_DOWN:
|
||||||
|
logging.warning(
|
||||||
|
'MasterServerV1CallThread.run() during app'
|
||||||
|
' shutdown is a no-op.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
plus = babase.app.plus
|
plus = babase.app.plus
|
||||||
assert plus is not None
|
assert plus is not None
|
||||||
response_data: Any = None
|
response_data: Any = None
|
||||||
|
|||||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
# Build number and version of the ballistica binary we expect to be
|
# Build number and version of the ballistica binary we expect to be
|
||||||
# using.
|
# using.
|
||||||
TARGET_BALLISTICA_BUILD = 21250
|
TARGET_BALLISTICA_BUILD = 21256
|
||||||
TARGET_BALLISTICA_VERSION = '1.7.26'
|
TARGET_BALLISTICA_VERSION = '1.7.26'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -199,7 +199,11 @@ class QuitWindow:
|
|||||||
)
|
)
|
||||||
bui.lock_all_input()
|
bui.lock_all_input()
|
||||||
|
|
||||||
# Unlock and fade back in shortly.. just in case something goes wrong
|
# Unlock and fade back in shortly. Just in case something goes
|
||||||
# (or on android where quit just backs out of our activity and
|
# wrong (or on Android where quit just backs out of our activity
|
||||||
# we may come back)
|
# and we may come back after).
|
||||||
bui.apptimer(0.3, bui.unlock_all_input)
|
def _come_back() -> None:
|
||||||
|
bui.unlock_all_input()
|
||||||
|
bui.fade_screen(True, time=0.1)
|
||||||
|
|
||||||
|
bui.apptimer(0.3, _come_back)
|
||||||
|
|||||||
@ -1406,11 +1406,11 @@ def _check_merch_availability_in_bg_thread() -> None:
|
|||||||
time.sleep(1.1934) # A bit randomized to avoid aliasing.
|
time.sleep(1.1934) # A bit randomized to avoid aliasing.
|
||||||
|
|
||||||
|
|
||||||
# Slight hack; start checking merch availability in the bg
|
# Slight hack; start checking merch availability in the bg (but only if
|
||||||
# (but only if it looks like we're part of a running app; don't want to
|
# it looks like we've been imported for use in a running app; don't want
|
||||||
# do this during docs generation/etc.)
|
# to do this during docs generation/etc.)
|
||||||
if (
|
if (
|
||||||
os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') != '1'
|
os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') != '1'
|
||||||
and bui.app.state is not bui.app.State.BOOTSTRAPPING
|
and bui.app.state is not bui.app.State.NOT_RUNNING
|
||||||
):
|
):
|
||||||
Thread(target=_check_merch_availability_in_bg_thread, daemon=True).start()
|
Thread(target=_check_merch_availability_in_bg_thread, daemon=True).start()
|
||||||
|
|||||||
@ -140,7 +140,6 @@ void AppAdapter::OnAppPause_() {
|
|||||||
g_base->network_reader->OnAppPause();
|
g_base->network_reader->OnAppPause();
|
||||||
}
|
}
|
||||||
g_base->networking->OnAppPause();
|
g_base->networking->OnAppPause();
|
||||||
g_core->platform->OnAppPause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppAdapter::OnAppResume_() {
|
void AppAdapter::OnAppResume_() {
|
||||||
@ -151,7 +150,6 @@ void AppAdapter::OnAppResume_() {
|
|||||||
EventLoop::SetEventLoopsPaused(false);
|
EventLoop::SetEventLoopsPaused(false);
|
||||||
|
|
||||||
// Run resumes that expect to happen in the main thread.
|
// Run resumes that expect to happen in the main thread.
|
||||||
g_core->platform->OnAppResume();
|
|
||||||
g_base->network_reader->OnAppResume();
|
g_base->network_reader->OnAppResume();
|
||||||
g_base->networking->OnAppResume();
|
g_base->networking->OnAppResume();
|
||||||
|
|
||||||
|
|||||||
@ -75,12 +75,12 @@ BaseFeatureSet::BaseFeatureSet()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseFeatureSet::OnModuleExec(PyObject* module) {
|
void BaseFeatureSet::OnModuleExec(PyObject* module) {
|
||||||
// Ok, our feature-set's Python module is getting imported. Like any
|
// Ok, our feature-set's Python module is getting imported. Just like a
|
||||||
// normal Python module, we take this opportunity to import/create the
|
// pure Python module would, we take this opportunity to import/create the
|
||||||
// stuff we use.
|
// stuff we use.
|
||||||
|
|
||||||
// Importing core should always be the first thing we do. Various
|
// Importing core should always be the first thing we do. Various
|
||||||
// ballistica functionality will fail if this has not been done.
|
// Ballistica functionality will fail if this has not been done.
|
||||||
assert(g_core == nullptr);
|
assert(g_core == nullptr);
|
||||||
g_core = core::CoreFeatureSet::Import();
|
g_core = core::CoreFeatureSet::Import();
|
||||||
|
|
||||||
@ -106,17 +106,18 @@ void BaseFeatureSet::OnModuleExec(PyObject* module) {
|
|||||||
g_base->python->AddPythonClasses(module);
|
g_base->python->AddPythonClasses(module);
|
||||||
|
|
||||||
// Store our C++ front-end with our Python module. This is what allows
|
// Store our C++ front-end with our Python module. This is what allows
|
||||||
// others to 'import' our C++ front end.
|
// other C++ code to 'import' our C++ front end and talk to us directly.
|
||||||
g_base->StoreOnPythonModule(module);
|
g_base->StoreOnPythonModule(module);
|
||||||
|
|
||||||
// Import all the Python stuff we use.
|
// Import all the Python stuff we use.
|
||||||
g_base->python->ImportPythonObjs();
|
g_base->python->ImportPythonObjs();
|
||||||
|
|
||||||
// Run some sanity checks, wire up our log handler, etc.
|
// Run some sanity checks, wire up our log handler, etc.
|
||||||
auto result = g_base->python->objs()
|
bool success = g_base->python->objs()
|
||||||
.Get(BasePython::ObjID::kOnNativeModuleImportCall)
|
.Get(BasePython::ObjID::kEnvOnNativeModuleImportCall)
|
||||||
.Call();
|
.Call()
|
||||||
if (!result.Exists()) {
|
.Exists();
|
||||||
|
if (!success) {
|
||||||
FatalError("babase._env.on_native_module_import() call failed.");
|
FatalError("babase._env.on_native_module_import() call failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,7 +62,6 @@ void Logic::OnAppStart() {
|
|||||||
g_base->audio->OnAppStart();
|
g_base->audio->OnAppStart();
|
||||||
g_base->input->OnAppStart();
|
g_base->input->OnAppStart();
|
||||||
g_base->ui->OnAppStart();
|
g_base->ui->OnAppStart();
|
||||||
g_core->platform->OnAppStart();
|
|
||||||
g_base->app_mode()->OnAppStart();
|
g_base->app_mode()->OnAppStart();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->plus()->OnAppStart();
|
g_base->plus()->OnAppStart();
|
||||||
@ -80,7 +79,7 @@ void Logic::OnInitialScreenCreated() {
|
|||||||
// business logic.
|
// business logic.
|
||||||
|
|
||||||
// Let the Python layer know the native layer is now fully functional.
|
// Let the Python layer know the native layer is now fully functional.
|
||||||
// This will probably result in the Python layer flipping to the LAUNCHING
|
// This will probably result in the Python layer flipping to the INITING
|
||||||
// state.
|
// state.
|
||||||
CompleteAppBootstrapping();
|
CompleteAppBootstrapping();
|
||||||
|
|
||||||
@ -109,7 +108,7 @@ void Logic::CompleteAppBootstrapping() {
|
|||||||
assert(!app_bootstrapping_complete_);
|
assert(!app_bootstrapping_complete_);
|
||||||
app_bootstrapping_complete_ = true;
|
app_bootstrapping_complete_ = true;
|
||||||
|
|
||||||
g_core->LifecycleLog("app bootstrapping complete");
|
g_core->LifecycleLog("app native bootstrapping complete");
|
||||||
|
|
||||||
// Let the assets system know it can start loading stuff now that
|
// Let the assets system know it can start loading stuff now that
|
||||||
// we have a screen and thus know texture formats/etc.
|
// we have a screen and thus know texture formats/etc.
|
||||||
@ -143,7 +142,7 @@ void Logic::CompleteAppBootstrapping() {
|
|||||||
// Let Python know we're done bootstrapping so it can flip the app
|
// Let Python know we're done bootstrapping so it can flip the app
|
||||||
// into the 'launching' state.
|
// into the 'launching' state.
|
||||||
g_base->python->objs()
|
g_base->python->objs()
|
||||||
.Get(BasePython::ObjID::kAppOnNativeBootstrappedCall)
|
.Get(BasePython::ObjID::kAppOnNativeBootstrappingCompleteCall)
|
||||||
.Call();
|
.Call();
|
||||||
|
|
||||||
UpdatePendingWorkTimer();
|
UpdatePendingWorkTimer();
|
||||||
@ -181,7 +180,6 @@ void Logic::OnAppPause() {
|
|||||||
g_base->plus()->OnAppPause();
|
g_base->plus()->OnAppPause();
|
||||||
}
|
}
|
||||||
g_base->app_mode()->OnAppPause();
|
g_base->app_mode()->OnAppPause();
|
||||||
g_core->platform->OnAppPause();
|
|
||||||
g_base->ui->OnAppPause();
|
g_base->ui->OnAppPause();
|
||||||
g_base->input->OnAppPause();
|
g_base->input->OnAppPause();
|
||||||
g_base->audio->OnAppPause();
|
g_base->audio->OnAppPause();
|
||||||
@ -197,7 +195,6 @@ void Logic::OnAppResume() {
|
|||||||
g_base->audio->OnAppResume();
|
g_base->audio->OnAppResume();
|
||||||
g_base->input->OnAppResume();
|
g_base->input->OnAppResume();
|
||||||
g_base->ui->OnAppResume();
|
g_base->ui->OnAppResume();
|
||||||
g_core->platform->OnAppResume();
|
|
||||||
g_base->app_mode()->OnAppResume();
|
g_base->app_mode()->OnAppResume();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->plus()->OnAppResume();
|
g_base->plus()->OnAppResume();
|
||||||
@ -234,7 +231,6 @@ void Logic::OnAppShutdown() {
|
|||||||
g_base->plus()->OnAppShutdown();
|
g_base->plus()->OnAppShutdown();
|
||||||
}
|
}
|
||||||
g_base->app_mode()->OnAppShutdown();
|
g_base->app_mode()->OnAppShutdown();
|
||||||
g_core->platform->OnAppShutdown();
|
|
||||||
g_base->ui->OnAppShutdown();
|
g_base->ui->OnAppShutdown();
|
||||||
g_base->input->OnAppShutdown();
|
g_base->input->OnAppShutdown();
|
||||||
g_base->audio->OnAppShutdown();
|
g_base->audio->OnAppShutdown();
|
||||||
@ -269,7 +265,6 @@ void Logic::DoApplyAppConfig() {
|
|||||||
g_base->audio->DoApplyAppConfig();
|
g_base->audio->DoApplyAppConfig();
|
||||||
g_base->input->DoApplyAppConfig();
|
g_base->input->DoApplyAppConfig();
|
||||||
g_base->ui->DoApplyAppConfig();
|
g_base->ui->DoApplyAppConfig();
|
||||||
g_core->platform->DoApplyAppConfig();
|
|
||||||
g_base->app_mode()->DoApplyAppConfig();
|
g_base->app_mode()->DoApplyAppConfig();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->plus()->DoApplyAppConfig();
|
g_base->plus()->DoApplyAppConfig();
|
||||||
@ -585,15 +580,20 @@ void Logic::UpdatePendingWorkTimer() {
|
|||||||
void Logic::HandleInterruptSignal() {
|
void Logic::HandleInterruptSignal() {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
|
|
||||||
|
// Interrupt signals are 'gentle' requests to shut down.
|
||||||
|
|
||||||
// Special case; when running under the server-wrapper, we completely
|
// Special case; when running under the server-wrapper, we completely
|
||||||
// ignore interrupt signals (the wrapper acts on them).
|
// ignore interrupt signals (the wrapper acts on them).
|
||||||
if (g_base->server_wrapper_managed()) {
|
if (g_base->server_wrapper_managed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// Go with a low level process shutdown here. In situations where we're
|
void Logic::HandleTerminateSignal() {
|
||||||
// getting interrupt signals I don't think we'd ever want high level
|
// Interrupt signals are slightly more stern requests to shut down.
|
||||||
// 'soft' quits.
|
// We always respond to these.
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,9 @@ class Logic {
|
|||||||
return app_bootstrapping_complete_;
|
return app_bootstrapping_complete_;
|
||||||
}
|
}
|
||||||
void NotifyOfPendingAssetLoads();
|
void NotifyOfPendingAssetLoads();
|
||||||
|
|
||||||
void HandleInterruptSignal();
|
void HandleInterruptSignal();
|
||||||
|
void HandleTerminateSignal();
|
||||||
|
|
||||||
auto NewAppTimer(millisecs_t length, bool repeat,
|
auto NewAppTimer(millisecs_t length, bool repeat,
|
||||||
const Object::Ref<Runnable>& runnable) -> int;
|
const Object::Ref<Runnable>& runnable) -> int;
|
||||||
|
|||||||
@ -257,11 +257,21 @@ void BasePlatform::DoOpenURL(const std::string& url) {
|
|||||||
|
|
||||||
#if !BA_OSTYPE_WINDOWS
|
#if !BA_OSTYPE_WINDOWS
|
||||||
static void HandleSIGINT(int s) {
|
static void HandleSIGINT(int s) {
|
||||||
if (g_base->logic) {
|
if (g_base && g_base->logic->event_loop()) {
|
||||||
g_base->logic->event_loop()->PushCall(
|
g_base->logic->event_loop()->PushCall(
|
||||||
[] { g_base->logic->HandleInterruptSignal(); });
|
[] { g_base->logic->HandleInterruptSignal(); });
|
||||||
} else {
|
} else {
|
||||||
Log(LogLevel::kError, "SigInt handler called before g_logic exists.");
|
Log(LogLevel::kError,
|
||||||
|
"SigInt handler called before g_base->logic->event_loop exists.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void HandleSIGTERM(int s) {
|
||||||
|
if (g_base && g_base->logic->event_loop()) {
|
||||||
|
g_base->logic->event_loop()->PushCall(
|
||||||
|
[] { g_base->logic->HandleTerminateSignal(); });
|
||||||
|
} else {
|
||||||
|
Log(LogLevel::kError,
|
||||||
|
"SigInt handler called before g_base->logic->event_loop exists.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -271,11 +281,20 @@ void BasePlatform::SetupInterruptHandling() {
|
|||||||
#if BA_OSTYPE_WINDOWS
|
#if BA_OSTYPE_WINDOWS
|
||||||
throw Exception();
|
throw Exception();
|
||||||
#else
|
#else
|
||||||
struct sigaction handler {};
|
{
|
||||||
handler.sa_handler = HandleSIGINT;
|
struct sigaction handler {};
|
||||||
sigemptyset(&handler.sa_mask);
|
handler.sa_handler = HandleSIGINT;
|
||||||
handler.sa_flags = 0;
|
sigemptyset(&handler.sa_mask);
|
||||||
sigaction(SIGINT, &handler, nullptr);
|
handler.sa_flags = 0;
|
||||||
|
sigaction(SIGINT, &handler, nullptr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct sigaction handler {};
|
||||||
|
handler.sa_handler = HandleSIGTERM;
|
||||||
|
sigemptyset(&handler.sa_mask);
|
||||||
|
handler.sa_flags = 0;
|
||||||
|
sigaction(SIGTERM, &handler, nullptr);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -142,7 +142,10 @@ void BasePython::OnMainThreadStartApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePython::OnAppStart() { assert(g_base->InLogicThread()); }
|
void BasePython::OnAppStart() {
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
|
objs().Get(BasePython::ObjID::kAppOnNativeStartCall).Call();
|
||||||
|
}
|
||||||
|
|
||||||
void BasePython::OnAppPause() {
|
void BasePython::OnAppPause() {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class BasePython {
|
|||||||
kCallClass,
|
kCallClass,
|
||||||
kGarbageCollectSessionEndCall,
|
kGarbageCollectSessionEndCall,
|
||||||
kConfig,
|
kConfig,
|
||||||
kAppOnNativeBootstrappedCall,
|
kAppOnNativeBootstrappingCompleteCall,
|
||||||
kResetToMainMenuCall,
|
kResetToMainMenuCall,
|
||||||
kSetConfigFullscreenOnCall,
|
kSetConfigFullscreenOnCall,
|
||||||
kSetConfigFullscreenOffCall,
|
kSetConfigFullscreenOffCall,
|
||||||
@ -69,10 +69,11 @@ class BasePython {
|
|||||||
kAppReadConfigCall,
|
kAppReadConfigCall,
|
||||||
kUIRemotePressCall,
|
kUIRemotePressCall,
|
||||||
kRemoveInGameAdsMessageCall,
|
kRemoveInGameAdsMessageCall,
|
||||||
|
kAppOnNativeStartCall,
|
||||||
kAppOnNativePauseCall,
|
kAppOnNativePauseCall,
|
||||||
kAppOnNativeResumeCall,
|
kAppOnNativeResumeCall,
|
||||||
kQuitCall,
|
|
||||||
kAppOnNativeShutdownCall,
|
kAppOnNativeShutdownCall,
|
||||||
|
kQuitCall,
|
||||||
kShowPostPurchaseMessageCall,
|
kShowPostPurchaseMessageCall,
|
||||||
kContextError,
|
kContextError,
|
||||||
kNotFoundError,
|
kNotFoundError,
|
||||||
@ -98,7 +99,7 @@ class BasePython {
|
|||||||
kLoginAdapterGetSignInTokenResponseCall,
|
kLoginAdapterGetSignInTokenResponseCall,
|
||||||
kPreEnv,
|
kPreEnv,
|
||||||
kOpenURLWithWebBrowserModuleCall,
|
kOpenURLWithWebBrowserModuleCall,
|
||||||
kOnNativeModuleImportCall,
|
kEnvOnNativeModuleImportCall,
|
||||||
kOnMainThreadStartAppCall,
|
kOnMainThreadStartAppCall,
|
||||||
kAppPushApplyAppConfigCall,
|
kAppPushApplyAppConfigCall,
|
||||||
kLast // Sentinel; must be at end.
|
kLast // Sentinel; must be at end.
|
||||||
|
|||||||
@ -516,6 +516,9 @@ static auto PyQuit(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log(LogLevel::kDebug,
|
||||||
|
// "QUIT soft=" + std::to_string(soft) + " back=" + std::to_string(back));
|
||||||
|
|
||||||
// FIXME this should all just go through platform and/or app-adapter.
|
// FIXME this should all just go through platform and/or app-adapter.
|
||||||
|
|
||||||
if (g_buildconfig.ostype_ios_tvos()) {
|
if (g_buildconfig.ostype_ios_tvos()) {
|
||||||
|
|||||||
@ -32,8 +32,8 @@ void ClassicFeatureSet::OnModuleExec(PyObject* module) {
|
|||||||
assert(g_classic == nullptr);
|
assert(g_classic == nullptr);
|
||||||
g_classic = new ClassicFeatureSet();
|
g_classic = new ClassicFeatureSet();
|
||||||
|
|
||||||
// Store our C++ front-end with our Python module.
|
// Store our C++ front-end with our Python module. This is what allows
|
||||||
// This is what allows others to 'import' our C++ front end.
|
// other C++ code to 'import' our C++ front end and talk to us directly.
|
||||||
g_classic->StoreOnPythonModule(module);
|
g_classic->StoreOnPythonModule(module);
|
||||||
|
|
||||||
// Import any Python stuff we use into objs_.
|
// Import any Python stuff we use into objs_.
|
||||||
|
|||||||
@ -644,22 +644,6 @@ auto CorePlatform::GetTextTextureData(void* tex) -> uint8_t* {
|
|||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CorePlatform::OnAppStart() {
|
|
||||||
assert(g_base_soft && g_base_soft->InLogicThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CorePlatform::OnAppPause() {
|
|
||||||
assert(g_base_soft && g_base_soft->InLogicThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CorePlatform::OnAppResume() {
|
|
||||||
assert(g_base_soft && g_base_soft->InLogicThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CorePlatform::OnAppShutdown() {
|
|
||||||
assert(g_base_soft && g_base_soft->InLogicThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CorePlatform::OnScreenSizeChange() {
|
void CorePlatform::OnScreenSizeChange() {
|
||||||
assert(g_base_soft && g_base_soft->InLogicThread());
|
assert(g_base_soft && g_base_soft->InLogicThread());
|
||||||
}
|
}
|
||||||
@ -700,8 +684,6 @@ void CorePlatform::AndroidSetResString(const std::string& res) {
|
|||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CorePlatform::DoApplyAppConfig() {}
|
|
||||||
|
|
||||||
void CorePlatform::AndroidSynthesizeBackPress() {
|
void CorePlatform::AndroidSynthesizeBackPress() {
|
||||||
Log(LogLevel::kError, "AndroidSynthesizeBackPress() unimplemented");
|
Log(LogLevel::kError, "AndroidSynthesizeBackPress() unimplemented");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,11 +51,6 @@ class CorePlatform {
|
|||||||
|
|
||||||
virtual void WillExitMain(bool errored);
|
virtual void WillExitMain(bool errored);
|
||||||
|
|
||||||
virtual void OnAppStart();
|
|
||||||
virtual void OnAppPause();
|
|
||||||
virtual void OnAppResume();
|
|
||||||
virtual void OnAppShutdown();
|
|
||||||
virtual void DoApplyAppConfig();
|
|
||||||
virtual void OnScreenSizeChange();
|
virtual void OnScreenSizeChange();
|
||||||
virtual void StepDisplayTime();
|
virtual void StepDisplayTime();
|
||||||
|
|
||||||
|
|||||||
@ -50,8 +50,8 @@ void SceneV1FeatureSet::OnModuleExec(PyObject* module) {
|
|||||||
assert(g_scene_v1 == nullptr);
|
assert(g_scene_v1 == nullptr);
|
||||||
g_scene_v1 = new SceneV1FeatureSet();
|
g_scene_v1 = new SceneV1FeatureSet();
|
||||||
|
|
||||||
// Store our C++ front-end with our Python module.
|
// Store our C++ front-end with our Python module. This is what allows
|
||||||
// This is what allows others to 'import' our C++ front end.
|
// other C++ code to 'import' our C++ front end and talk to us directly.
|
||||||
g_scene_v1->StoreOnPythonModule(module);
|
g_scene_v1->StoreOnPythonModule(module);
|
||||||
|
|
||||||
// Define our classes.
|
// Define our classes.
|
||||||
|
|||||||
@ -1376,10 +1376,7 @@ void SceneV1AppMode::HandleQuitOnIdle() {
|
|||||||
idle_exiting_ = true;
|
idle_exiting_ = true;
|
||||||
|
|
||||||
Log(LogLevel::kInfo, "Quitting due to reaching idle-exit-minutes.");
|
Log(LogLevel::kInfo, "Quitting due to reaching idle-exit-minutes.");
|
||||||
g_base->logic->event_loop()->PushCall([] {
|
g_base->logic->event_loop()->PushCall([] { g_base->logic->Shutdown(); });
|
||||||
assert(g_base->InLogicThread());
|
|
||||||
g_base->python->objs().Get(base::BasePython::ObjID::kQuitCall).Call();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 = 21250;
|
const int kEngineBuildNumber = 21256;
|
||||||
const char* kEngineVersion = "1.7.26";
|
const char* kEngineVersion = "1.7.26";
|
||||||
|
|
||||||
#if BA_MONOLITHIC_BUILD
|
#if BA_MONOLITHIC_BUILD
|
||||||
|
|||||||
@ -86,16 +86,8 @@ EventLoop::EventLoop(EventLoopID identifier_in, ThreadSource source)
|
|||||||
// Block until the thread is bootstrapped.
|
// Block until the thread is bootstrapped.
|
||||||
// (maybe not necessary, but let's be cautious in case we'd
|
// (maybe not necessary, but let's be cautious in case we'd
|
||||||
// try to use things like thread_id before they're known).
|
// try to use things like thread_id before they're known).
|
||||||
if (identifier_ == EventLoopID::kLogic) {
|
|
||||||
g_core->LifecycleLog("logic thread bootstrap wait begin");
|
|
||||||
}
|
|
||||||
|
|
||||||
client_listener_cv_.wait(lock, [this] { return bootstrapped_; });
|
client_listener_cv_.wait(lock, [this] { return bootstrapped_; });
|
||||||
|
|
||||||
if (identifier_ == EventLoopID::kLogic) {
|
|
||||||
g_core->LifecycleLog("logic thread bootstrap wait end");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ThreadSource::kWrapMain: {
|
case ThreadSource::kWrapMain: {
|
||||||
@ -758,20 +750,12 @@ void EventLoop::PushRunnableSynchronous(Runnable* runnable) {
|
|||||||
PushCrossThreadRunnable_(runnable, &complete);
|
PushCrossThreadRunnable_(runnable, &complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identifier_ == EventLoopID::kLogic) {
|
|
||||||
g_core->LifecycleLog("logic thread sync run push begin");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now listen until our completion flag gets set.
|
// Now listen until our completion flag gets set.
|
||||||
client_listener_cv_.wait(lock, [complete_ptr] {
|
client_listener_cv_.wait(lock, [complete_ptr] {
|
||||||
// Go back to sleep on spurious wakeups
|
// Go back to sleep on spurious wakeups
|
||||||
// (if we're not actually complete yet).
|
// (if we're not actually complete yet).
|
||||||
return *complete_ptr;
|
return *complete_ptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (identifier_ == EventLoopID::kLogic) {
|
|
||||||
g_core->LifecycleLog("logic thread sync run push end");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EventLoop::CheckPushSafety() -> bool {
|
auto EventLoop::CheckPushSafety() -> bool {
|
||||||
|
|||||||
@ -23,8 +23,8 @@ void TemplateFsFeatureSet::OnModuleExec(PyObject* module) {
|
|||||||
// Create our feature-set's C++ front-end.
|
// Create our feature-set's C++ front-end.
|
||||||
g_template_fs = new TemplateFsFeatureSet();
|
g_template_fs = new TemplateFsFeatureSet();
|
||||||
|
|
||||||
// Store our C++ front-end on our Python module.
|
// Store our C++ front-end with our Python module. This is what allows
|
||||||
// This is what allows others to 'import' our C++ front end.
|
// other C++ code to 'import' our C++ front end and talk to us directly.
|
||||||
g_template_fs->StoreOnPythonModule(module);
|
g_template_fs->StoreOnPythonModule(module);
|
||||||
|
|
||||||
// Import any Python stuff we use into objs_.
|
// Import any Python stuff we use into objs_.
|
||||||
|
|||||||
@ -78,6 +78,6 @@ values = [
|
|||||||
_hooks.implicit_sign_out, # kImplicitSignOutCall
|
_hooks.implicit_sign_out, # kImplicitSignOutCall
|
||||||
_hooks.login_adapter_get_sign_in_token_response, # kLoginAdapterGetSignInTokenResponseCall
|
_hooks.login_adapter_get_sign_in_token_response, # kLoginAdapterGetSignInTokenResponseCall
|
||||||
_hooks.open_url_with_webbrowser_module, # kOpenURLWithWebBrowserModuleCall
|
_hooks.open_url_with_webbrowser_module, # kOpenURLWithWebBrowserModuleCall
|
||||||
_env.on_native_module_import, # kOnNativeModuleImportCall
|
_env.on_native_module_import, # kEnvOnNativeModuleImportCall
|
||||||
_env.on_main_thread_start_app, # kOnMainThreadStartAppCall
|
_env.on_main_thread_start_app, # kOnMainThreadStartAppCall
|
||||||
]
|
]
|
||||||
|
|||||||
@ -12,7 +12,8 @@ values = [
|
|||||||
app.lang.get_resource, # kGetResourceCall
|
app.lang.get_resource, # kGetResourceCall
|
||||||
app.lang.translate, # kTranslateCall
|
app.lang.translate, # kTranslateCall
|
||||||
app.push_apply_app_config, # kAppPushApplyAppConfigCall
|
app.push_apply_app_config, # kAppPushApplyAppConfigCall
|
||||||
app.on_native_bootstrapped, # kAppOnNativeBootstrappedCall
|
app.on_native_start, # kAppOnNativeStartCall
|
||||||
|
app.on_native_bootstrapping_complete, # kAppOnNativeBootstrappingCompleteCall
|
||||||
app.on_native_pause, # kAppOnNativePauseCall
|
app.on_native_pause, # kAppOnNativePauseCall
|
||||||
app.on_native_resume, # kAppOnNativeResumeCall
|
app.on_native_resume, # kAppOnNativeResumeCall
|
||||||
app.on_native_shutdown, # kAppOnNativeShutdownCall
|
app.on_native_shutdown, # kAppOnNativeShutdownCall
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user