diff --git a/.efrocachemap b/.efrocachemap
index 972446c2..f74d9a0a 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -420,7 +420,7 @@
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681",
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10",
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505",
- "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/72/77/139e39fe51a3f8fec9443600b61e",
+ "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/d2/88/6b51163789d96e3a6d0341680d6b",
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/92/43/36b34307575f6d6219bdf4898e18",
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503",
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/f5/32/293ca14171b8e7e7d38f377e87fb",
@@ -449,7 +449,7 @@
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/01/97/624b3ee62979002d2385ed58abda",
"assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/4e/91/6f2a9a3ce733908e91377a6ddb9a",
"assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/20/a9/163d189884edf802636bf291e432",
- "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/86/77/743b37dbd06ea8d29bc3315848db",
+ "assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/a6/84/20a8d97b55785f6f995dadd88f4c",
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/3b/9f/d40c1423d260784970fd7364ca30",
"assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/3d/83/e1bb0a664d1c14c41b1a083acf0d",
"assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/d6/16/523c643358880b03b233ed88e557",
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 50c7601b..a1be411a 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -103,6 +103,7 @@
appath
appathout
appcfg
+ appcomponent
appconfig
appdelegate
appengine
diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py
index 83388231..ddc18131 100644
--- a/assets/src/ba_data/python/ba/_app.py
+++ b/assets/src/ba_data/python/ba/_app.py
@@ -59,20 +59,26 @@ class App:
class State(Enum):
"""High level state the app can be in."""
- # Python-level systems being inited but should not interact.
- LAUNCHING = 0
+ # The launch process has not yet begun.
+ INITIAL = 0
- # Initial account logins, workspace & asset downloads, etc.
- LOADING = 1
+ # Our app subsystems are being inited but should not yet interact.
+ LAUNCHING = 1
- # Normal running state.
- RUNNING = 2
+ # 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. in order to
+ # prepare for this.
+ LOADING = 2
- # App is backgrounded or otherwise suspended.
- PAUSED = 3
+ # All pieces are in place and the app is now doing its thing.
+ RUNNING = 3
- # App is shutting down.
- SHUTTING_DOWN = 4
+ # The app is backgrounded or otherwise suspended.
+ PAUSED = 4
+
+ # The app is shutting down.
+ SHUTTING_DOWN = 5
@property
def aioloop(self) -> asyncio.AbstractEventLoop:
@@ -233,11 +239,14 @@ class App:
"""
# pylint: disable=too-many-statements
- self.state = self.State.LAUNCHING
+ self.state = self.State.INITIAL
+ self._bootstrapping_completed = False
+ self._called_on_app_launching = False
self._launch_completed = False
self._initial_sign_in_completed = False
self._meta_scan_completed = False
+ self._called_on_app_loading = False
self._called_on_app_running = False
self._app_paused = False
@@ -344,10 +353,8 @@ class App:
self.delegate: ba.AppDelegate | None = None
self._asyncio_timer: ba.Timer | None = None
- def on_app_launch(self) -> None:
- """Runs after the app finishes low level bootstrapping.
-
- (internal)"""
+ def on_app_launching(self) -> None:
+ """Called when the app is first entering the launching state."""
# pylint: disable=cyclic-import
# pylint: disable=too-many-locals
from ba import _asyncio
@@ -475,6 +482,9 @@ class App:
self._launch_completed = True
self._update_state()
+ def on_app_loading(self) -> None:
+ """Called when initially entering the loading state."""
+
def on_app_running(self) -> None:
"""Called when initially entering the running state."""
@@ -483,6 +493,13 @@ class App:
# from ba._dependency import test_depset
# test_depset()
+ def on_bootstrapping_completed(self) -> None:
+ """Called by the C++ layer once its ready to rock."""
+ assert _ba.in_logic_thread()
+ assert not self._bootstrapping_completed
+ self._bootstrapping_completed = True
+ self._update_state()
+
def on_meta_scan_complete(self) -> None:
"""Called by meta-scan when it is done doing its thing."""
assert _ba.in_logic_thread()
@@ -513,6 +530,7 @@ class App:
self.plugins.on_app_resume()
self.health_monitor.on_app_resume()
+ # Handle initially entering or returning to other states.
if self._initial_sign_in_completed and self._meta_scan_completed:
self.state = self.State.RUNNING
if not self._called_on_app_running:
@@ -520,8 +538,17 @@ class App:
self.on_app_running()
elif self._launch_completed:
self.state = self.State.LOADING
+ if not self._called_on_app_loading:
+ self._called_on_app_loading = True
+ self.on_app_loading()
else:
+ # Only thing left is launching. We shouldn't be getting
+ # called before at least that is complete.
+ assert self._bootstrapping_completed
self.state = self.State.LAUNCHING
+ if not self._called_on_app_launching:
+ self._called_on_app_launching = True
+ self.on_app_launching()
def on_app_pause(self) -> None:
"""Called when the app goes to a suspended state."""
diff --git a/assets/src/ba_data/python/ba/_hooks.py b/assets/src/ba_data/python/ba/_hooks.py
index f7d0e471..67749df3 100644
--- a/assets/src/ba_data/python/ba/_hooks.py
+++ b/assets/src/ba_data/python/ba/_hooks.py
@@ -27,12 +27,8 @@ def finish_bootstrapping() -> None:
"""Do final bootstrapping related bits."""
assert _ba.in_logic_thread()
- # Kick off our asyncio event handling, allowing us to use coroutines
- # in our logic thread alongside our internal event handling.
- # setup_asyncio()
-
- # Ok, bootstrapping is done; time to get the show started.
- _ba.app.on_app_launch()
+ # Ok, low level bootstrapping is done; time to get Python stuff started.
+ _ba.app.on_bootstrapping_completed()
def reset_to_main_menu() -> None:
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index 46426ce9..09ffe94b 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -69,6 +69,7 @@
apientry
apiversion
apost
+ appcomponent
appconfig
appname
appnameupper