diff --git a/.efrocachemap b/.efrocachemap
index 7fe6fb5f..3a1cf01f 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4068,50 +4068,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
- "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "6d094a3cd65948896b4c447261e81704",
- "build/prefab/full/linux_arm64_gui/release/ballisticakit": "430032b34e9b9f85dbf78ef48b72d132",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b61d8e726e0019cd4109aa5e9533867c",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "2c293043357d79e665bbbea2e5134cff",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "f793ef2f26fa13dad8d35e90c8c141d8",
- "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "5c301636ebf4f824a69d27a0beb11218",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "8ec42bbe83ca4d0734f6e9697525cd7b",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "a88db549342f7b10820e6028eb25b552",
- "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "d767a9da339452eca123eedc1a1613ab",
- "build/prefab/full/mac_arm64_gui/release/ballisticakit": "fe23ddd3129d3ca1582a51e6ae6bd2f0",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "da61ad34ea9852ee90216b384b9fa810",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "5bcafd99e07f74fb5354d8dc51f9dcd3",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "fbabe1c5a50b4fc288990855109c0f9a",
- "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "1ee18569ef3e9ff79f89d4fe63b1ab48",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "6f5b8dabf7e99183804a325ede1801af",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "85bdeabd281d3b99f3a493e9ea68205f",
- "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "352dee4c52b8f5a41374ba991365f2dd",
- "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "2b4255b6beaeb7792e3e0bb879d1549c",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "b01cff4e97ac0e9abc4552068f6e2816",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "74ee01e9a88eb4ce1acdeef34d30dd49",
- "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "bf4e9fe0c457660b45d2e4546b8e32e4",
- "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "de7dd11c6a017f9f28dd619b56463e95",
- "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "bf4e9fe0c457660b45d2e4546b8e32e4",
- "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "de7dd11c6a017f9f28dd619b56463e95",
- "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "ee204e8f8b8fc35d68166d0491255f87",
- "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "a79f838c7225f4bfb8d572a5caf79b91",
- "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "ee204e8f8b8fc35d68166d0491255f87",
- "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "a79f838c7225f4bfb8d572a5caf79b91",
- "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "c3f22a4373f4179fa694c5de0f68cbb7",
- "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "437ad30ef4a8de4c19da41047ea721df",
- "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "c3f22a4373f4179fa694c5de0f68cbb7",
- "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "437ad30ef4a8de4c19da41047ea721df",
- "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "c1fa4493a7afcc41c77a2ddf0697f030",
- "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "b2f88f60a0efd2fd8e1dea74ca79e925",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "acd5007aba0e74f5d3a3df6e7b3abab6",
- "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "b2f88f60a0efd2fd8e1dea74ca79e925",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "77af3a22db2ea65aa1f7b6203363ff40",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "695204948e2b06fd91e05ee3e6a66e0a",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "723e0bd1d1218d2b84f4647638cbdec7",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "8206655af59a053685329b87046ff58d",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "c3ee54fd24061523dc56e983fef53b60",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "70f23230117e24af61cce73a597851ee",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "322f179c3b4ebe52c4cd9da8206e499c",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "6c17bf39253bb5bb3359786ae6f0246e",
+ "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "242acbe77fb4b4dba000a4f2bfc05628",
+ "build/prefab/full/linux_arm64_gui/release/ballisticakit": "b3b950f7aef84bdcb905bc4862bc46c0",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "5bf6ff933f1202a16e59caab2614e7f5",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "5985564e7dcc9b37819c01f5617e07f5",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "3d490eb1e54ac4813f287c7aae7611cc",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "2cb1bebe253965580beacbc18aab4d19",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "39df8c4bf25de958ba7e0669b24fa851",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "1dd9de26acbf937ded40fdd1e31ba213",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "9b6675625e5d11bfbdb79156533b5e7a",
+ "build/prefab/full/mac_arm64_gui/release/ballisticakit": "c204a8de7b8b28ba0f8669d0b2de0828",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "3f62aa7d31a097a92404c022510f975b",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "724b0e3118a0fae86ab3686efc82a1f0",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "129aa7848d1bb8c5d9e1151185f752d6",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "20b89b0333e5de59becfe21c2092300c",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "5003b2740aed1c69b8296e5179d22d5b",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "d1e14b32cc026901a4e11c9e8c1715f1",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "2adbd526ecb26eba04c5165361c0a397",
+ "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e7a3152446ef0fc03fc80609c25c824d",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "80fac001fbe4c6c3dcd9e64e38712394",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "61db43d2ee6123f4bdbb2a56eec29166",
+ "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "9cb423dc66c25d32365cf579bdb0ad48",
+ "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "dc03331ceb9a0bb57d74e6ab3ce69f16",
+ "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "9cb423dc66c25d32365cf579bdb0ad48",
+ "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "dc03331ceb9a0bb57d74e6ab3ce69f16",
+ "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "0a9803fd6e8750a0bec5036d848216a1",
+ "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "e353417db3536ee90e579b22f4eddb3e",
+ "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "0a9803fd6e8750a0bec5036d848216a1",
+ "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "e353417db3536ee90e579b22f4eddb3e",
+ "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "4cce38fc08e6a9aa47e0c57b23c930b5",
+ "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "5dd00571bd5aa72a4276d1b53cab4b2b",
+ "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "4cce38fc08e6a9aa47e0c57b23c930b5",
+ "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "5dd00571bd5aa72a4276d1b53cab4b2b",
+ "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "faf824b0fd529e4bb24bf633eba3ac0d",
+ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "f3f34fa0cd21bd378fa5711c627a9698",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "1272aaa24cce371db94f38661c8ab4f8",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "f3f34fa0cd21bd378fa5711c627a9698",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "b9ab40b7b1727328dd008b79397cafc4",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "80f77141b09264716c711d4c30190fc1",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "804a5e69223bb06d670ce6796526dee3",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "463170bfd59637e3b85bdbb7efd722ac",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "1acf5026c56619b9b73b32940be377f0",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "f3244a1acf2f49587c28a18852e09121",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "e2faf9da55a00991bfe97d052556b4fa",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "8ee526c52e834f8d29244a0f37e33183",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "eeddad968b176000e31c65be6206a2bc",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d489b07f..1a34bf7f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-### 1.7.26 (build 21232, api 8, 2023-08-22)
+### 1.7.26 (build 21241, api 8, 2023-08-22)
- Various general improvements to the pcommand (project command) system.
- Modules containing pcommand functions are now named with an 's' - so
@@ -11,6 +11,11 @@
that seem to be related to this, you can disable it by setting env var
`BA_PCOMMANDBATCH_DISABLE=1`. See docs in `tools/efrotools/pcommandbatch.py`
for more info.
+- Renamed the various `App` C++ classes to `AppAdapter` which better represents
+ their current intended role. They are not a general interface to app
+ functionality, but rather adapt the app to a particular paradigm or api (VR,
+ Headless, SDL GUI, etc.). Am trying to move any functionality out of those
+ classes that does not fit that definition.
### 1.7.25 (build 21211, api 8, 2023-08-03)
diff --git a/ballisticakit-cmake/CMakeLists.txt b/ballisticakit-cmake/CMakeLists.txt
index 062e8a15..8da237d3 100644
--- a/ballisticakit-cmake/CMakeLists.txt
+++ b/ballisticakit-cmake/CMakeLists.txt
@@ -203,14 +203,14 @@ endif ()
set(BALLISTICA_SOURCES
${BA_SRC_ROOT}/external/qr_code_generator/QrCode.cpp
# AUTOGENERATED_PUBLIC_BEGIN (this section is managed by the "update_project" tool)
- ${BA_SRC_ROOT}/ballistica/base/app/app.cc
- ${BA_SRC_ROOT}/ballistica/base/app/app.h
- ${BA_SRC_ROOT}/ballistica/base/app/app_headless.cc
- ${BA_SRC_ROOT}/ballistica/base/app/app_headless.h
- ${BA_SRC_ROOT}/ballistica/base/app/app_sdl.cc
- ${BA_SRC_ROOT}/ballistica/base/app/app_sdl.h
- ${BA_SRC_ROOT}/ballistica/base/app/app_vr.cc
- ${BA_SRC_ROOT}/ballistica/base/app/app_vr.h
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter.cc
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter.h
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_headless.cc
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_headless.h
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_sdl.cc
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_sdl.h
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_vr.cc
+ ${BA_SRC_ROOT}/ballistica/base/app_adapter/app_adapter_vr.h
${BA_SRC_ROOT}/ballistica/base/app_mode/app_mode.cc
${BA_SRC_ROOT}/ballistica/base/app_mode/app_mode.h
${BA_SRC_ROOT}/ballistica/base/app_mode/app_mode_empty.cc
diff --git a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj
index 4ae1e188..a24dd06b 100644
--- a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj
+++ b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj
@@ -189,14 +189,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters
index 88b7dd89..01de57ed 100644
--- a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters
+++ b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters
@@ -1,29 +1,29 @@
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
ballistica\base\app_mode
@@ -1865,7 +1865,7 @@
-
+
diff --git a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj
index e122c99d..094c7ecb 100644
--- a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj
+++ b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj
@@ -184,14 +184,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters
index 88b7dd89..01de57ed 100644
--- a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters
+++ b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters
@@ -1,29 +1,29 @@
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
-
- ballistica\base\app
+
+ ballistica\base\app_adapter
ballistica\base\app_mode
@@ -1865,7 +1865,7 @@
-
+
diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py
index d9d7eb03..f5402095 100644
--- a/src/assets/ba_data/python/baenv.py
+++ b/src/assets/ba_data/python/baenv.py
@@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
-TARGET_BALLISTICA_BUILD = 21232
+TARGET_BALLISTICA_BUILD = 21241
TARGET_BALLISTICA_VERSION = '1.7.26'
diff --git a/src/ballistica/base/app/app.h b/src/ballistica/base/app/app.h
deleted file mode 100644
index 9b0cff85..00000000
--- a/src/ballistica/base/app/app.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Released under the MIT License. See LICENSE for details.
-
-#ifndef BALLISTICA_BASE_APP_APP_H_
-#define BALLISTICA_BASE_APP_APP_H_
-
-#include
-
-#include "ballistica/base/base.h"
-
-namespace ballistica::base {
-
-/// Defines app behavior for a particular paradigm (regular gui, vr,
-/// headless) and/or top level api (SDL, UIKit, etc.).
-class App {
- public:
- App();
- virtual ~App();
-
- /// Should be run after the instance is created and assigned. Any setup
- /// that may trigger virtual methods or lookups via global should go here.
- void PostInit();
-
- /// Gets called when the app config is being applied. Note that this call
- /// happens in the logic thread, so we should do any reading that needs to
- /// happen in the logic thread and then forward the values to ourself back
- /// in our main thread.
- void DoLogicThreadApplyAppConfig();
-
- /// Return whether this class runs its own event loop.
- auto ManagesEventLoop() const -> bool;
-
- /// Called for non-event-loop apps to give them an opportunity to ensure
- /// they are self-sustaining. For instance, an app relying on frame-draws
- /// for its main thread event processing may need to manually pump events
- /// until frame rendering begins.
- virtual void PrimeMainThreadEventPump();
-
- /// Handle any pending OS events. On normal graphical builds this is
- /// triggered by RunRenderUpkeepCycle(); timer intervals for headless
- /// builds, etc. Should process any pending OS events, etc.
- virtual void RunEvents();
-
- /// Put the app into a paused state. Should be called from the main
- /// thread. Pauses work, closes network sockets, etc.
- /// Corresponds to being backgrounded on mobile, etc.
- /// It is assumed that, as soon as this call returns, all work is
- /// finished and all threads can be suspended by the OS without any
- /// negative side effects.
- void PauseApp();
-
- auto paused() const -> bool { return actually_paused_; }
-
- /// OnAppResume the app; corresponds to returning to foreground on
- /// mobile/etc. Spins threads back up, re-opens network sockets, etc.
- void ResumeApp();
-
- /// The last time the app was resumed (uses GetAppTimeMillisecs() value).
- auto last_app_resume_time() const -> millisecs_t {
- return last_app_resume_time_;
- }
-
- /// Should be called if the platform detects the GL context_ref was lost.
- void RebuildLostGLContext();
-
- /// Attempt to draw a frame.
- void DrawFrame(bool during_resize = false);
-
- /// Run updates in the logic thread. Generally called once per frame
- /// rendered or at some fixed rate for headless builds.
- void LogicThreadStepDisplayTime();
-
- /// Used on platforms where our main thread event processing is driven by
- /// frame-draw commands given to us. This should be called after drawing a
- /// frame in order to bring game state up to date and process OS events.
- void RunRenderUpkeepCycle();
-
- /// Called by the graphics-server when drawing completes for a frame.
- virtual void DidFinishRenderingFrame(FrameDef* frame);
-
- /// Whether we're running under ballisticakit_server.py
- /// (affects some app behavior).
- auto server_wrapper_managed() const -> bool {
- return server_wrapper_managed_;
- }
-
- virtual void OnMainThreadStartApp();
-
- // Deferred calls that can be made from other threads.
-
- void PushPurchaseCall(const std::string& item);
- void PushRestorePurchasesCall();
- void PushResetAchievementsCall();
- void PushPurchaseAckCall(const std::string& purchase,
- const std::string& order_id);
-
- /// Called by the logic thread when all shutdown-related tasks are done.
- void LogicThreadShutdownComplete();
-
- void LogicThreadOnAppRunning();
- void LogicThreadOnInitialAppModeSet();
-
- private:
- void UpdatePauseResume_();
- void OnAppPause_();
- void OnAppResume_();
- bool server_wrapper_managed_{};
- bool sys_paused_app_{};
- bool actually_paused_{};
- millisecs_t last_resize_draw_event_time_{};
- millisecs_t last_app_resume_time_{};
-};
-
-} // namespace ballistica::base
-
-#endif // BALLISTICA_BASE_APP_APP_H_
diff --git a/src/ballistica/base/app/app_headless.h b/src/ballistica/base/app/app_headless.h
deleted file mode 100644
index 77898e90..00000000
--- a/src/ballistica/base/app/app_headless.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Released under the MIT License. See LICENSE for details.
-
-#ifndef BALLISTICA_BASE_APP_APP_HEADLESS_H_
-#define BALLISTICA_BASE_APP_APP_HEADLESS_H_
-#if BA_HEADLESS_BUILD
-
-#include "ballistica/base/app/app.h"
-#include "ballistica/shared/foundation/event_loop.h"
-
-namespace ballistica::base {
-
-class AppHeadless : public App {
- public:
- AppHeadless();
-};
-
-} // namespace ballistica::base
-
-#endif // BA_HEADLESS_BUILD
-#endif // BALLISTICA_BASE_APP_APP_HEADLESS_H_
diff --git a/src/ballistica/base/app/app.cc b/src/ballistica/base/app_adapter/app_adapter.cc
similarity index 53%
rename from src/ballistica/base/app/app.cc
rename to src/ballistica/base/app_adapter/app_adapter.cc
index 4a173f7b..c616b271 100644
--- a/src/ballistica/base/app/app.cc
+++ b/src/ballistica/base/app_adapter/app_adapter.cc
@@ -1,111 +1,65 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/graphics/graphics_server.h"
#include "ballistica/base/graphics/renderer/renderer.h"
-#include "ballistica/base/input/device/touch_input.h"
#include "ballistica/base/input/input.h"
-#include "ballistica/base/logic/logic.h"
#include "ballistica/base/networking/network_reader.h"
#include "ballistica/base/networking/networking.h"
-#include "ballistica/base/platform/base_platform.h"
-#include "ballistica/base/support/stdio_console.h"
#include "ballistica/base/support/stress_test.h"
-#include "ballistica/base/ui/console.h"
#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/python/python.h"
namespace ballistica::base {
-App::App() {
- // We modify some app behavior when run under the server manager.
- auto* envval = getenv("BA_SERVER_WRAPPER_MANAGED");
- server_wrapper_managed_ = (envval && strcmp(envval, "1") == 0);
-}
+AppAdapter::AppAdapter() = default;
-void App::PostInit() {
- // Sanity check: make sure asserts are stripped out of release builds
- // (NDEBUG should do this).
-#if !BA_DEBUG_BUILD
-#ifndef NDEBUG
-#error Expected NDEBUG to be defined for release builds.
-#endif // NDEBUG
- assert(true);
-#endif // !BA_DEBUG_BUILD
+AppAdapter::~AppAdapter() = default;
- g_core->set_legacy_user_agent_string(
- g_core->platform->GetLegacyUserAgentString());
-}
-
-App::~App() = default;
-
-void App::DoLogicThreadApplyAppConfig() {
- // Note: this gets called in the logic thread since that's where
- // config reading happens. We should grab whatever values we need
- // and then forward them to ourself in the main thread.
- // We also can give our other main-thread-based subsystems a chance
- // to do the same.
+void AppAdapter::LogicThreadDoApplyAppConfig() {
assert(g_base->InLogicThread());
-
- g_base->networking->DoApplyAppConfig();
}
-void App::LogicThreadStepDisplayTime() { assert(g_base->InLogicThread()); }
-
-void App::LogicThreadOnAppRunning() {
- assert(g_base && g_base->InLogicThread());
-}
-
-void App::LogicThreadOnInitialAppModeSet() {
- assert(g_core && g_base && g_base->InLogicThread());
-
- // We want any sort of raw Python input to only start accepting commands
- // once we've got an initial app-mode set. Generally said commands will
- // assume we're running in that mode and will fail if run before it is set.
- if (auto* console = g_base->console()) {
- console->EnableInput();
- }
- if (g_base->stdio_console) {
- g_base->stdio_console->Start();
- }
-}
-
-auto App::ManagesEventLoop() const -> bool {
+auto AppAdapter::ManagesEventLoop() const -> bool {
// We have 2 redundant values for essentially the same thing;
// should get rid of IsEventPushMode() once we've created
// App subclasses for our various platforms.
return !g_core->platform->IsEventPushMode();
}
-void App::RunRenderUpkeepCycle() {
- // This should only be used in cases where the OS is handling the event loop.
- assert(!ManagesEventLoop());
- if (ManagesEventLoop()) {
- return;
- }
+void AppAdapter::OnMainThreadStartApp() {
+ assert(g_base);
+ assert(g_core);
+ assert(g_core->InMainThread());
- // Pump thread messages (we're being driven by frame-draw callbacks
- // so this is the only place that it gets done at).
- g_core->main_event_loop()->RunSingleCycle();
+ // Add some common input devices where applicable. More specific ones (SDL
+ // Joysticks, etc.) get added in subclasses.
- // Now do the general app event cycle for whoever needs to process things.
- RunEvents();
-}
+ // If we've got a nice themed hardware cursor, show it. Otherwise we'll
+ // render it manually, which is laggier but gets the job done.
+ g_core->platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor());
-void App::RebuildLostGLContext() {
- assert(g_base->InGraphicsThread());
- assert(g_base->graphics_server);
- if (g_base->graphics_server) {
- g_base->graphics_server->RebuildLostContext();
+ if (!g_core->HeadlessMode()) {
+ // On desktop systems we just assume keyboard input exists and add it
+ // immediately.
+ if (g_core->platform->IsRunningOnDesktop()) {
+ g_base->input->PushCreateKeyboardInputDevices();
+ }
+
+ // On non-tv, non-desktop, non-vr systems, create a touchscreen input.
+ if (!g_core->platform->IsRunningOnTV() && !g_core->IsVRMode()
+ && !g_core->platform->IsRunningOnDesktop()) {
+ g_base->input->CreateTouchInput();
+ }
}
}
-void App::DrawFrame(bool during_resize) {
+void AppAdapter::DrawFrame(bool during_resize) {
assert(g_base->InGraphicsThread());
- // It's possible to receive frames before we're ready to draw.
+ // It's possible to be asked to draw before we're ready.
if (!g_base->graphics_server || !g_base->graphics_server->renderer()) {
return;
}
@@ -115,9 +69,10 @@ void App::DrawFrame(bool during_resize) {
// A resize-draw event means that we're drawing due to a window resize.
// In this case we ignore regular draw events for a short while
// afterwards which makes resizing smoother.
- // FIXME: should figure out the *correct* way to handle this;
- // I believe the underlying cause here is some sort of context contention
- // across threads.
+ //
+ // FIXME: should figure out the *correct* way to handle this; I believe
+ // the underlying cause here is some sort of context contention across
+ // threads.
if (during_resize) {
last_resize_draw_event_time_ = starttime;
} else {
@@ -129,19 +84,21 @@ void App::DrawFrame(bool during_resize) {
RunRenderUpkeepCycle();
}
-void App::LogicThreadShutdownComplete() {
- assert(g_core->InMainThread());
- assert(g_core);
+void AppAdapter::RunRenderUpkeepCycle() {
+ // This should only be firing if the OS is handling the event loop.
+ assert(!ManagesEventLoop());
- // Flag our own event loop to exit (or tell the OS to do so for its own).
- if (ManagesEventLoop()) {
- g_core->main_event_loop()->Quit();
- } else {
- g_core->platform->QuitApp();
- }
+ // Pump the main event loop (when we're being driven by frame-draw
+ // callbacks, this is the only place that gets done).
+ g_core->main_event_loop()->RunSingleCycle();
+
+ // Now do the general app event cycle for whoever needs to process things.
+ // FIXME KILL THIS.
+ RunEvents();
}
-void App::RunEvents() {
+// FIXME KILL THIS.
+void AppAdapter::RunEvents() {
// There's probably a better place for this.
g_base->stress_test()->Update();
@@ -152,29 +109,29 @@ void App::RunEvents() {
g_core->platform->RunEvents();
}
-void App::UpdatePauseResume_() {
- if (actually_paused_) {
+void AppAdapter::UpdatePauseResume_() {
+ if (app_paused_) {
// Unpause if no one wants pause.
- if (!sys_paused_app_) {
+ if (!app_pause_requested_) {
OnAppResume_();
- actually_paused_ = false;
+ app_paused_ = false;
}
} else {
// OnAppPause if anyone wants.
- if (sys_paused_app_) {
+ if (app_pause_requested_) {
OnAppPause_();
- actually_paused_ = true;
+ app_paused_ = true;
}
}
}
-void App::OnAppPause_() {
+void AppAdapter::OnAppPause_() {
assert(g_core->InMainThread());
// IMPORTANT: Any pause related stuff that event-loop-threads need to do
- // should be done from their registered pause-callbacks. If we instead push
- // runnables to them from here they may or may not be called before their
- // event-loop is actually paused.
+ // should be done from their registered pause-callbacks. If we instead
+ // push runnables to them from here they may or may not be called before
+ // their event-loop is actually paused.
// Pause all event loops.
EventLoop::SetThreadsPaused(true);
@@ -186,7 +143,7 @@ void App::OnAppPause_() {
g_core->platform->OnAppPause();
}
-void App::OnAppResume_() {
+void AppAdapter::OnAppResume_() {
assert(g_core->InMainThread());
last_app_resume_time_ = g_core->GetAppTimeMillisecs();
@@ -198,47 +155,47 @@ void App::OnAppResume_() {
g_base->network_reader->OnAppResume();
g_base->networking->OnAppResume();
- // When resuming from a paused state, we may want to
- // pause whatever game was running when we last were active.
- // TODO(efro): we should make this smarter so it doesn't happen if
- // we're in a network game or something that we can't pause;
- // bringing up the menu doesn't really accomplish anything there.
+ // When resuming from a paused state, we may want to pause whatever game
+ // was running when we last were active.
+ //
+ // TODO(efro): we should make this smarter so it doesn't happen if we're
+ // in a network game or something that we can't pause; bringing up the
+ // menu doesn't really accomplish anything there.
if (g_core->should_pause) {
g_core->should_pause = false;
- // If we've been completely backgrounded,
- // send a menu-press command to the game; this will
- // bring up a pause menu if we're in the game/etc.
+ // If we've been completely backgrounded, send a menu-press command to
+ // the game; this will bring up a pause menu if we're in the game/etc.
if (!g_base->ui->MainMenuVisible()) {
g_base->ui->PushMainMenuPressCall(nullptr);
}
}
}
-void App::PauseApp() {
+void AppAdapter::PauseApp() {
assert(g_core);
assert(g_core->InMainThread());
millisecs_t start_time{core::CorePlatform::GetCurrentMillisecs()};
- // Apple mentioned 5 seconds to run stuff once backgrounded or
- // they bring down the hammer. Let's aim to stay under 2.
+ // Apple mentioned 5 seconds to run stuff once backgrounded or they bring
+ // down the hammer. Let's aim to stay under 2.
millisecs_t max_duration{2000};
g_core->platform->DebugLog(
"PauseApp@" + std::to_string(core::CorePlatform::GetCurrentMillisecs()));
- assert(!sys_paused_app_);
- sys_paused_app_ = true;
+ assert(!app_pause_requested_);
+ app_pause_requested_ = true;
UpdatePauseResume_();
- // We assume that the OS will completely suspend our process the moment
- // we return from this call (though this is not technically true on all
- // platforms). So we want to spin and wait for threads to actually
- // process the pause message.
+ // We assume that the OS will completely suspend our process the moment we
+ // return from this call (though this is not technically true on all
+ // platforms). So we want to spin and wait for threads to actually process
+ // the pause message.
size_t running_thread_count{};
while (std::abs(core::CorePlatform::GetCurrentMillisecs() - start_time)
< max_duration) {
- // If/when we get to a point with no threads waiting to be paused,
- // we're good to go.
+ // If/when we get to a point with no threads waiting to be paused, we're
+ // good to go.
auto threads{EventLoop::GetStillPausingThreads()};
running_thread_count = threads.size();
if (running_thread_count == 0) {
@@ -263,13 +220,13 @@ void App::PauseApp() {
+ " ms.");
}
-void App::ResumeApp() {
+void AppAdapter::ResumeApp() {
assert(g_core && g_core->InMainThread());
millisecs_t start_time{core::CorePlatform::GetCurrentMillisecs()};
g_core->platform->DebugLog(
"ResumeApp@" + std::to_string(core::CorePlatform::GetCurrentMillisecs()));
- assert(sys_paused_app_);
- sys_paused_app_ = false;
+ assert(app_pause_requested_);
+ app_pause_requested_ = false;
UpdatePauseResume_();
if (g_buildconfig.debug_build()) {
Log(LogLevel::kDebug,
@@ -280,9 +237,9 @@ void App::ResumeApp() {
}
}
-void App::DidFinishRenderingFrame(FrameDef* frame) {}
+void AppAdapter::DidFinishRenderingFrame(FrameDef* frame) {}
-void App::PrimeMainThreadEventPump() {
+void AppAdapter::PrimeMainThreadEventPump() {
assert(!ManagesEventLoop());
// Need to release the GIL while we're doing this so other thread
@@ -297,58 +254,4 @@ void App::PrimeMainThreadEventPump() {
}
}
-#pragma mark Push-Calls
-
-void App::PushPurchaseAckCall(const std::string& purchase,
- const std::string& order_id) {
- g_core->main_event_loop()->PushCall([purchase, order_id] {
- g_base->platform->PurchaseAck(purchase, order_id);
- });
-}
-
-void App::PushPurchaseCall(const std::string& item) {
- g_core->main_event_loop()->PushCall([item] {
- assert(g_core->InMainThread());
- g_base->platform->Purchase(item);
- });
-}
-
-void App::PushRestorePurchasesCall() {
- g_core->main_event_loop()->PushCall([] {
- assert(g_core->InMainThread());
- g_base->platform->RestorePurchases();
- });
-}
-
-void App::PushResetAchievementsCall() {
- g_core->main_event_loop()->PushCall(
- [] { g_core->platform->ResetAchievements(); });
-}
-
-void App::OnMainThreadStartApp() {
- assert(g_base);
- assert(g_core);
- assert(g_core->InMainThread());
-
- // If we've got a nice themed hardware cursor, show it.
- // Otherwise, hide the hardware cursor; we'll draw it in software.
- // (need to run this in postinit because SDL/etc. may not be inited yet
- // as of App::App()).
- g_core->platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor());
-
- if (!g_core->HeadlessMode()) {
- // On desktop systems we just assume keyboard input exists and add it
- // immediately.
- if (g_core->platform->IsRunningOnDesktop()) {
- g_base->input->PushCreateKeyboardInputDevices();
- }
-
- // On non-tv, non-desktop, non-vr systems, create a touchscreen input.
- if (!g_core->platform->IsRunningOnTV() && !g_core->IsVRMode()
- && !g_core->platform->IsRunningOnDesktop()) {
- g_base->input->CreateTouchInput();
- }
- }
-}
-
} // namespace ballistica::base
diff --git a/src/ballistica/base/app_adapter/app_adapter.h b/src/ballistica/base/app_adapter/app_adapter.h
new file mode 100644
index 00000000..a7b0e7af
--- /dev/null
+++ b/src/ballistica/base/app_adapter/app_adapter.h
@@ -0,0 +1,88 @@
+// Released under the MIT License. See LICENSE for details.
+
+#ifndef BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_H_
+#define BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_H_
+
+#include
+
+#include "ballistica/base/base.h"
+
+namespace ballistica::base {
+
+/// Adapts app behavior specific to a particular paradigm and/or api
+/// environment. For example, 'Headless', 'VROculus', 'SDL', etc. Multiple
+/// of these may be supported on a single platform, unlike the Platform
+/// classes where generally there is a single one for the whole platform.
+/// For example, on Windows, we might have GUI, VR, and Headless
+/// AppAdapters, but they all might share the same CorePlatform and
+/// BasePlatform classes.
+class AppAdapter {
+ public:
+ AppAdapter();
+ virtual ~AppAdapter();
+
+ virtual void OnMainThreadStartApp();
+
+ /// Return whether this class runs its own event loop.
+ auto ManagesEventLoop() const -> bool;
+
+ /// Called for non-event-loop-managing apps to give them an opportunity to
+ /// ensure they are self-sustaining. For instance, an app relying on
+ /// frame-draws for its main thread event processing may need to manually
+ /// pump events until a screen-creation event goes through which should
+ /// keep things running thereafter.
+ virtual void PrimeMainThreadEventPump();
+
+ /// Handle any pending OS events. On normal graphical builds this is
+ /// triggered by RunRenderUpkeepCycle(); timer intervals for headless
+ /// builds, etc. Should process any pending OS events, etc.
+ virtual void RunEvents();
+
+ /// Put the app into a paused state. Should be called from the main
+ /// thread. Pauses work, closes network sockets, etc. May correspond to
+ /// being backgrounded on mobile, being minimized on desktop, etc. It is
+ /// assumed that, as soon as this call returns, all work is finished and
+ /// all threads can be suspended by the OS without any negative side
+ /// effects.
+ void PauseApp();
+
+ /// Resume the app; can correspond to foregrounding on mobile,
+ /// unminimizing on desktop, etc. Spins threads back up, re-opens network
+ /// sockets, etc.
+ void ResumeApp();
+
+ auto app_paused() const { return app_paused_; }
+
+ /// The last time the app was resumed (uses GetAppTimeMillisecs() value).
+ auto last_app_resume_time() const { return last_app_resume_time_; }
+
+ /// Attempt to draw a frame.
+ void DrawFrame(bool during_resize = false);
+
+ /// Gets called when the app config is being applied. Note that this call
+ /// happens in the logic thread, so we should do any reading that needs to
+ /// happen in the logic thread and then forward the values to ourself back
+ /// in our main thread.
+ virtual void LogicThreadDoApplyAppConfig();
+
+ /// Used on platforms where our main thread event processing is driven by
+ /// frame-draw commands given to us. This should be called after drawing a
+ /// frame in order to bring game state up to date and process OS events.
+ void RunRenderUpkeepCycle();
+
+ /// Called by the graphics-server when drawing completes for a frame.
+ virtual void DidFinishRenderingFrame(FrameDef* frame);
+
+ private:
+ void UpdatePauseResume_();
+ void OnAppPause_();
+ void OnAppResume_();
+ bool app_pause_requested_{};
+ bool app_paused_{};
+ millisecs_t last_resize_draw_event_time_{};
+ millisecs_t last_app_resume_time_{};
+};
+
+} // namespace ballistica::base
+
+#endif // BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_H_
diff --git a/src/ballistica/base/app/app_headless.cc b/src/ballistica/base/app_adapter/app_adapter_headless.cc
similarity index 70%
rename from src/ballistica/base/app/app_headless.cc
rename to src/ballistica/base/app_adapter/app_adapter_headless.cc
index faf3f1ac..90dc63a5 100644
--- a/src/ballistica/base/app/app_headless.cc
+++ b/src/ballistica/base/app_adapter/app_adapter_headless.cc
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
#if BA_HEADLESS_BUILD
-#include "ballistica/base/app/app_headless.h"
+#include "ballistica/base/app_adapter/app_adapter_headless.h"
#include "ballistica/shared/ballistica.h"
@@ -9,13 +9,13 @@ namespace ballistica::base {
// We could technically use the vanilla App class here since we're not
// changing anything.
-AppHeadless::AppHeadless() {
+AppAdapterHeadless::AppAdapterHeadless() {
// Handle a few misc things like stress-test updates.
// (SDL builds set up a similar timer so we need to also).
// This can probably go away at some point.
g_core->main_event_loop()->NewTimer(10, true, NewLambdaRunnable([this] {
- assert(g_base->app);
- g_base->app->RunEvents();
+ assert(g_base->app_adapter);
+ g_base->app_adapter->RunEvents();
}));
}
diff --git a/src/ballistica/base/app_adapter/app_adapter_headless.h b/src/ballistica/base/app_adapter/app_adapter_headless.h
new file mode 100644
index 00000000..a45cbe3b
--- /dev/null
+++ b/src/ballistica/base/app_adapter/app_adapter_headless.h
@@ -0,0 +1,20 @@
+// Released under the MIT License. See LICENSE for details.
+
+#ifndef BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_HEADLESS_H_
+#define BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_HEADLESS_H_
+#if BA_HEADLESS_BUILD
+
+#include "ballistica/base/app_adapter/app_adapter.h"
+#include "ballistica/shared/foundation/event_loop.h"
+
+namespace ballistica::base {
+
+class AppAdapterHeadless : public AppAdapter {
+ public:
+ AppAdapterHeadless();
+};
+
+} // namespace ballistica::base
+
+#endif // BA_HEADLESS_BUILD
+#endif // BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_HEADLESS_H_
diff --git a/src/ballistica/base/app/app_sdl.cc b/src/ballistica/base/app_adapter/app_adapter_sdl.cc
similarity index 91%
rename from src/ballistica/base/app/app_sdl.cc
rename to src/ballistica/base/app_adapter/app_adapter_sdl.cc
index c9a14e63..abe47748 100644
--- a/src/ballistica/base/app/app_sdl.cc
+++ b/src/ballistica/base/app_adapter/app_adapter_sdl.cc
@@ -2,7 +2,7 @@
#if BA_SDL_BUILD
-#include "ballistica/base/app/app_sdl.h"
+#include "ballistica/base/app_adapter/app_adapter_sdl.h"
#include "ballistica/base/dynamics/bg/bg_dynamics.h"
#include "ballistica/base/graphics/gl/gl_sys.h"
@@ -18,9 +18,7 @@
namespace ballistica::base {
-// NOTE TO SELF: slowly try to phase everything out from here and into
-// non-sdl event/call pushes.
-void AppSDL::HandleSDLEvent(const SDL_Event& event) {
+void AppAdapterSDL::HandleSDLEvent(const SDL_Event& event) {
assert(g_core->InMainThread());
switch (event.type) {
@@ -135,8 +133,8 @@ void AppSDL::HandleSDLEvent(const SDL_Event& event) {
}
#endif
- // Currently used in our some of our heavily customized builds.
- // Should replace this with some sort of PushDrawEvent() thing.
+ // Currently used in our some of our heavily customized builds. Should
+ // replace this with some sort of PushDrawEvent() thing.
#if BA_XCODE_BUILD
case SDL_RESIZEDRAWEVENT:
case SDL_DRAWEVENT: {
@@ -242,7 +240,7 @@ auto FilterSDLEvent(const SDL_Event* event) -> int {
try {
// If this event is coming from this thread, handle it immediately.
if (std::this_thread::get_id() == g_core->main_thread_id) {
- auto app = static_cast_check_type(g_base->app);
+ auto app = static_cast_check_type(g_base->app_adapter);
assert(app);
if (app) {
app->HandleSDLEvent(*event);
@@ -266,9 +264,9 @@ inline auto FilterSDL2Event(void* user_data, SDL_Event* event) -> int {
}
#endif
-// Note: can move this to AppSDL::AppSDL() once it is no longer needed by
-// the legacy mac build.
-void AppSDL::InitSDL() {
+// Note: can move this to AppAdapterSDL::AppAdapterSDL() once it is no longer
+// needed by the legacy mac build.
+void AppAdapterSDL::InitSDL() {
assert(g_core);
if (g_buildconfig.ostype_macos()) {
@@ -293,14 +291,14 @@ void AppSDL::InitSDL() {
// KILL THIS ONCE MAC SDL1.2 BUILD IS DEAD.
// Register our hotplug callbacks in our funky custom mac build.
#if BA_OSTYPE_MACOS && BA_XCODE_BUILD && !BA_HEADLESS_BUILD
- SDL_JoystickSetHotPlugCallbacks(AppSDL::SDLJoystickConnected_,
- AppSDL::SDLJoystickDisconnected_);
+ SDL_JoystickSetHotPlugCallbacks(AppAdapterSDL::SDLJoystickConnected_,
+ AppAdapterSDL::SDLJoystickDisconnected_);
#endif
}
}
- // Whatever fancy-pants stuff SDL is trying to do with catching signals/etc,
- // we don't want it.
+ // Whatever fancy-pants stuff SDL is trying to do with catching
+ // signals/etc, we don't want it.
sdl_flags |= SDL_INIT_NOPARACHUTE;
// We may or may not want xinput on windows.
@@ -328,7 +326,7 @@ void AppSDL::InitSDL() {
#endif
}
-AppSDL::AppSDL() {
+AppAdapterSDL::AppAdapterSDL() {
InitSDL();
// If we're not running our own even loop, we set up a filter to intercept
@@ -352,14 +350,14 @@ AppSDL::AppSDL() {
// much doing that same thing, except that we're free to handle other
// matters concurrently instead of being locked in a delay call.
g_core->main_event_loop()->NewTimer(10, true, NewLambdaRunnable([this] {
- assert(g_base->app);
- g_base->app->RunEvents();
+ assert(g_base->app_adapter);
+ g_base->app_adapter->RunEvents();
}));
}
}
-void AppSDL::OnMainThreadStartApp() {
- App::OnMainThreadStartApp();
+void AppAdapterSDL::OnMainThreadStartApp() {
+ AppAdapter::OnMainThreadStartApp();
if (!g_core->HeadlessMode() && g_buildconfig.enable_sdl_joysticks()) {
// Add initial sdl joysticks. any added/removed after this will be
@@ -369,7 +367,7 @@ void AppSDL::OnMainThreadStartApp() {
if (explicit_bool(true)) {
int joystick_count = SDL_NumJoysticks();
for (int i = 0; i < joystick_count; i++) {
- AppSDL::SDLJoystickConnected_(i);
+ AppAdapterSDL::SDLJoystickConnected_(i);
}
// We want events from joysticks.
@@ -378,8 +376,8 @@ void AppSDL::OnMainThreadStartApp() {
}
}
-void AppSDL::RunEvents() {
- App::RunEvents();
+void AppAdapterSDL::RunEvents() {
+ AppAdapter::RunEvents();
// Now run all pending SDL events until we run out or we're told to quit.
SDL_Event event;
@@ -388,12 +386,12 @@ void AppSDL::RunEvents() {
}
}
-void AppSDL::DidFinishRenderingFrame(FrameDef* frame) {
- App::DidFinishRenderingFrame(frame);
+void AppAdapterSDL::DidFinishRenderingFrame(FrameDef* frame) {
+ AppAdapter::DidFinishRenderingFrame(frame);
SwapBuffers_();
}
-void AppSDL::DoSwap_() {
+void AppAdapterSDL::DoSwap_() {
assert(g_base->InGraphicsThread());
if (g_buildconfig.debug_build()) {
@@ -440,7 +438,7 @@ void AppSDL::DoSwap_() {
last_swap_time_ = cur_time;
}
-void AppSDL::SwapBuffers_() {
+void AppAdapterSDL::SwapBuffers_() {
swap_start_time_ = g_core->GetAppTimeMillisecs();
assert(g_core->main_event_loop()->ThreadIsCurrent());
DoSwap_();
@@ -457,7 +455,7 @@ void AppSDL::SwapBuffers_() {
}
}
-void AppSDL::UpdateAutoVSync_(int diff) {
+void AppAdapterSDL::UpdateAutoVSync_(int diff) {
assert(auto_vsync_);
// If we're currently vsyncing, watch for slow frames.
@@ -525,7 +523,7 @@ void AppSDL::UpdateAutoVSync_(int diff) {
}
}
-void AppSDL::SetAutoVSync(bool enable) {
+void AppAdapterSDL::SetAutoVSync(bool enable) {
auto_vsync_ = enable;
// If we're doing auto, start with vsync on.
if (enable) {
@@ -536,7 +534,7 @@ void AppSDL::SetAutoVSync(bool enable) {
}
}
-void AppSDL::SDLJoystickConnected_(int device_index) {
+void AppAdapterSDL::SDLJoystickConnected_(int device_index) {
assert(g_core && g_core->InMainThread());
// We add all existing inputs when bootstrapping is complete; we should
@@ -562,17 +560,17 @@ void AppSDL::SDLJoystickConnected_(int device_index) {
}
}
-void AppSDL::SDLJoystickDisconnected_(int index) {
+void AppAdapterSDL::SDLJoystickDisconnected_(int index) {
assert(g_core->InMainThread());
assert(index >= 0);
Get()->RemoveSDLInputDevice_(index);
}
-void AppSDL::SetInitialScreenDimensions(const Vector2f& dimensions) {
+void AppAdapterSDL::SetInitialScreenDimensions(const Vector2f& dimensions) {
screen_dimensions_ = dimensions;
}
-void AppSDL::AddSDLInputDevice_(JoystickInput* input, int index) {
+void AppAdapterSDL::AddSDLInputDevice_(JoystickInput* input, int index) {
assert(g_base && g_base->input != nullptr);
assert(input != nullptr);
assert(g_core->InMainThread());
@@ -587,7 +585,7 @@ void AppSDL::AddSDLInputDevice_(JoystickInput* input, int index) {
g_base->input->PushAddInputDeviceCall(input, true);
}
-void AppSDL::RemoveSDLInputDevice_(int index) {
+void AppAdapterSDL::RemoveSDLInputDevice_(int index) {
assert(g_core->InMainThread());
assert(index >= 0);
JoystickInput* j = GetSDLJoystickInput_(index);
@@ -602,7 +600,8 @@ void AppSDL::RemoveSDLInputDevice_(int index) {
g_base->input->PushRemoveInputDeviceCall(j, true);
}
-auto AppSDL::GetSDLJoystickInput_(const SDL_Event* e) const -> JoystickInput* {
+auto AppAdapterSDL::GetSDLJoystickInput_(const SDL_Event* e) const
+ -> JoystickInput* {
assert(g_core->InMainThread());
int joy_id;
@@ -627,7 +626,8 @@ auto AppSDL::GetSDLJoystickInput_(const SDL_Event* e) const -> JoystickInput* {
return GetSDLJoystickInput_(joy_id);
}
-auto AppSDL::GetSDLJoystickInput_(int sdl_joystick_id) const -> JoystickInput* {
+auto AppAdapterSDL::GetSDLJoystickInput_(int sdl_joystick_id) const
+ -> JoystickInput* {
assert(g_core->InMainThread());
for (auto sdl_joystick : sdl_joysticks_) {
if ((sdl_joystick != nullptr) && (*sdl_joystick).sdl_joystick_id() >= 0
diff --git a/src/ballistica/base/app/app_sdl.h b/src/ballistica/base/app_adapter/app_adapter_sdl.h
similarity index 66%
rename from src/ballistica/base/app/app_sdl.h
rename to src/ballistica/base/app_adapter/app_adapter_sdl.h
index b2c6249c..7d2f567f 100644
--- a/src/ballistica/base/app/app_sdl.h
+++ b/src/ballistica/base/app_adapter/app_adapter_sdl.h
@@ -1,43 +1,44 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_BASE_APP_APP_SDL_H_
-#define BALLISTICA_BASE_APP_APP_SDL_H_
+#ifndef BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_SDL_H_
+#define BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_SDL_H_
#if BA_SDL_BUILD
#include
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/shared/math/vector2f.h"
namespace ballistica::base {
-class AppSDL : public App {
+class AppAdapterSDL : public AppAdapter {
public:
static void InitSDL();
- AppSDL();
+ AppAdapterSDL();
void HandleSDLEvent(const SDL_Event& event);
void RunEvents() override;
void DidFinishRenderingFrame(FrameDef* frame) override;
void SetAutoVSync(bool enable);
void OnMainThreadStartApp() override;
- /// Return g_base->app as an AppSDL. (assumes it actually is one).
- static AppSDL* Get() {
- assert(g_base && g_base->app != nullptr);
- assert(dynamic_cast(g_base->app)
- == static_cast(g_base->app));
- return static_cast(g_base->app);
+ /// Return g_base->app_adapter as an AppAdapterSDL. (assumes it actually is
+ /// one).
+ static AppAdapterSDL* Get() {
+ assert(g_base && g_base->app_adapter != nullptr);
+ assert(dynamic_cast(g_base->app_adapter)
+ == static_cast(g_base->app_adapter));
+ return static_cast(g_base->app_adapter);
}
void SetInitialScreenDimensions(const Vector2f& dimensions);
private:
- // Given an sdl joystick ID, returns our Ballistica input for it.
+ static void SDLJoystickConnected_(int index);
+ static void SDLJoystickDisconnected_(int index);
+ // Given an SDL joystick ID, returns our Ballistica input for it.
auto GetSDLJoystickInput_(int sdl_joystick_id) const -> JoystickInput*;
// The same but using sdl events.
auto GetSDLJoystickInput_(const SDL_Event* e) const -> JoystickInput*;
- static void SDLJoystickConnected_(int index);
- static void SDLJoystickDisconnected_(int index);
void DoSwap_();
void SwapBuffers_();
void UpdateAutoVSync_(int diff);
@@ -60,4 +61,4 @@ class AppSDL : public App {
#endif // BA_SDL_BUILD
-#endif // BALLISTICA_BASE_APP_APP_SDL_H_
+#endif // BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_SDL_H_
diff --git a/src/ballistica/base/app/app_vr.cc b/src/ballistica/base/app_adapter/app_adapter_vr.cc
similarity index 81%
rename from src/ballistica/base/app/app_vr.cc
rename to src/ballistica/base/app_adapter/app_adapter_vr.cc
index e8556c79..af0b74da 100644
--- a/src/ballistica/base/app/app_vr.cc
+++ b/src/ballistica/base/app_adapter/app_adapter_vr.cc
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
#if BA_VR_BUILD
-#include "ballistica/base/app/app_vr.h"
+#include "ballistica/base/app_adapter/app_adapter_vr.h"
#include "ballistica/base/graphics/graphics_server.h"
#include "ballistica/base/graphics/graphics_vr.h"
@@ -11,9 +11,10 @@
namespace ballistica::base {
-AppVR::AppVR() {}
+AppAdapterVR::AppAdapterVR() {}
-void AppVR::PushVRSimpleRemoteStateCall(const VRSimpleRemoteState& state) {
+void AppAdapterVR::PushVRSimpleRemoteStateCall(
+ const VRSimpleRemoteState& state) {
g_core->main_event_loop()->PushCall([this, state] {
// Convert this to a full hands state, adding in some simple elbow
// positioning of our own and left/right.
@@ -36,11 +37,11 @@ void AppVR::PushVRSimpleRemoteStateCall(const VRSimpleRemoteState& state) {
});
}
-void AppVR::VRSetDrawDimensions(int w, int h) {
+void AppAdapterVR::VRSetDrawDimensions(int w, int h) {
g_base->graphics_server->SetScreenResolution(w, h);
}
-void AppVR::VRPreDraw() {
+void AppAdapterVR::VRPreDraw() {
if (!g_base || !g_base->graphics_server
|| !g_base->graphics_server->renderer()) {
return;
@@ -58,7 +59,7 @@ void AppVR::VRPreDraw() {
}
}
-void AppVR::VRPostDraw() {
+void AppAdapterVR::VRPostDraw() {
assert(g_base->InGraphicsThread());
if (!g_base || !g_base->graphics_server
|| !g_base->graphics_server->renderer()) {
@@ -71,15 +72,15 @@ void AppVR::VRPostDraw() {
RunRenderUpkeepCycle();
}
-void AppVR::VRSetHead(float tx, float ty, float tz, float yaw, float pitch,
- float roll) {
+void AppAdapterVR::VRSetHead(float tx, float ty, float tz, float yaw,
+ float pitch, float roll) {
assert(g_base->InGraphicsThread());
Renderer* renderer = g_base->graphics_server->renderer();
if (renderer == nullptr) return;
renderer->VRSetHead(tx, ty, tz, yaw, pitch, roll);
}
-void AppVR::VRSetHands(const VRHandsState& state) {
+void AppAdapterVR::VRSetHands(const VRHandsState& state) {
assert(g_base->InGraphicsThread());
// Pass this along to the renderer (in this same thread) for drawing (so
@@ -99,10 +100,10 @@ void AppVR::VRSetHands(const VRHandsState& state) {
[state] { GraphicsVR::get()->set_vr_hands_state(state); });
}
-void AppVR::VRDrawEye(int eye, float yaw, float pitch, float roll, float tan_l,
- float tan_r, float tan_b, float tan_t, float eye_x,
- float eye_y, float eye_z, int viewport_x,
- int viewport_y) {
+void AppAdapterVR::VRDrawEye(int eye, float yaw, float pitch, float roll,
+ float tan_l, float tan_r, float tan_b, float tan_t,
+ float eye_x, float eye_y, float eye_z,
+ int viewport_x, int viewport_y) {
if (!g_base || !g_base->graphics_server
|| !g_base->graphics_server->renderer()) {
return;
diff --git a/src/ballistica/base/app/app_vr.h b/src/ballistica/base/app_adapter/app_adapter_vr.h
similarity index 60%
rename from src/ballistica/base/app/app_vr.h
rename to src/ballistica/base/app_adapter/app_adapter_vr.h
index c1551abe..4a62dbe3 100644
--- a/src/ballistica/base/app/app_vr.h
+++ b/src/ballistica/base/app_adapter/app_adapter_vr.h
@@ -1,15 +1,15 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_BASE_APP_APP_VR_H_
-#define BALLISTICA_BASE_APP_APP_VR_H_
+#ifndef BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_VR_H_
+#define BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_VR_H_
#if BA_VR_BUILD
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
namespace ballistica::base {
-class AppVR : public App {
+class AppAdapterVR : public AppAdapter {
public:
/// For passing in state of Daydream remote (and maybe gear vr?..).
struct VRSimpleRemoteState {
@@ -19,15 +19,15 @@ class AppVR : public App {
float r2 = 0.0f;
};
- /// Return g_app as a AppVR. (assumes it actually is one).
- static auto get() -> AppVR* {
- assert(g_base != nullptr && g_base->app != nullptr);
- assert(dynamic_cast(g_base->app)
- == static_cast(g_base->app));
- return static_cast(g_base->app);
+ /// Return g_app as a AppAdapterVR. (assumes it actually is one).
+ static auto get() -> AppAdapterVR* {
+ assert(g_base != nullptr && g_base->app_adapter != nullptr);
+ assert(dynamic_cast(g_base->app_adapter)
+ == static_cast(g_base->app_adapter));
+ return static_cast(g_base->app_adapter);
}
- AppVR();
+ AppAdapterVR();
void PushVRSimpleRemoteStateCall(const VRSimpleRemoteState& state);
void VRSetDrawDimensions(int w, int h);
void VRPreDraw();
@@ -46,4 +46,4 @@ class AppVR : public App {
} // namespace ballistica::base
#endif // BA_VR_BUILD
-#endif // BALLISTICA_BASE_APP_APP_VR_H_
+#endif // BALLISTICA_BASE_APP_ADAPTER_APP_ADAPTER_VR_H_
diff --git a/src/ballistica/base/app_mode/app_mode.h b/src/ballistica/base/app_mode/app_mode.h
index 178f5fcf..d1f6ca60 100644
--- a/src/ballistica/base/app_mode/app_mode.h
+++ b/src/ballistica/base/app_mode/app_mode.h
@@ -19,9 +19,9 @@ const microsecs_t kAppModeMaxHeadlessDisplayStep{500000};
const microsecs_t kAppModeMinHeadlessDisplayStep{1000};
/// Represents 'what the app is doing'. The global app-mode can be switched
-/// as the app is running. Be aware that, unlike the App classes which
-/// primarily operate in the main thread, most functionality here is based
-/// in the logic thread.
+/// as the app is running. Be aware that, unlike the AppAdapter classes
+/// which primarily deal with the main thread, most functionality here is
+/// based in the logic thread.
class AppMode {
public:
AppMode();
diff --git a/src/ballistica/base/app_mode/app_mode_empty.cc b/src/ballistica/base/app_mode/app_mode_empty.cc
index 9e65b2c7..6ac648b2 100644
--- a/src/ballistica/base/app_mode/app_mode_empty.cc
+++ b/src/ballistica/base/app_mode/app_mode_empty.cc
@@ -3,9 +3,6 @@
#include "ballistica/base/app_mode/app_mode_empty.h"
#include "ballistica/base/graphics/component/simple_component.h"
-#include "ballistica/base/graphics/graphics.h"
-#include "ballistica/base/graphics/support/frame_def.h"
-#include "ballistica/base/graphics/text/text_group.h"
namespace ballistica::base {
diff --git a/src/ballistica/base/assets/assets_server.cc b/src/ballistica/base/assets/assets_server.cc
index 6efb78c9..d918dd9d 100644
--- a/src/ballistica/base/assets/assets_server.cc
+++ b/src/ballistica/base/assets/assets_server.cc
@@ -7,7 +7,6 @@
#include "ballistica/base/graphics/graphics_server.h"
#include "ballistica/base/support/huffman.h"
#include "ballistica/shared/foundation/event_loop.h"
-#include "ballistica/shared/generic/utils.h"
namespace ballistica::base {
diff --git a/src/ballistica/base/base.cc b/src/ballistica/base/base.cc
index 5c6a4c68..d1b86fb0 100644
--- a/src/ballistica/base/base.cc
+++ b/src/ballistica/base/base.cc
@@ -2,14 +2,12 @@
#include "ballistica/base/base.h"
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/app_mode/app_mode_empty.h"
-#include "ballistica/base/assets/assets.h"
#include "ballistica/base/assets/assets_server.h"
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/audio/audio_server.h"
#include "ballistica/base/dynamics/bg/bg_dynamics_server.h"
-#include "ballistica/base/graphics/graphics.h"
#include "ballistica/base/graphics/graphics_server.h"
#include "ballistica/base/graphics/text/text_graphics.h"
#include "ballistica/base/input/input.h"
@@ -28,12 +26,10 @@
#include "ballistica/base/support/stress_test.h"
#include "ballistica/base/ui/console.h"
#include "ballistica/base/ui/ui.h"
-#include "ballistica/core/platform/core_platform.h"
#include "ballistica/core/python/core_python.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/foundation/logging.h"
#include "ballistica/shared/generic/utils.h"
-#include "ballistica/shared/python/python.h"
#include "ballistica/shared/python/python_command.h"
namespace ballistica::base {
@@ -42,36 +38,40 @@ core::CoreFeatureSet* g_core{};
BaseFeatureSet* g_base{};
BaseFeatureSet::BaseFeatureSet()
- : python{new BasePython()},
- platform{BasePlatform::CreatePlatform()},
- audio{new Audio()},
- utils{new Utils()},
- logic{new Logic()},
- huffman{new Huffman()},
- stress_test_{new StressTest()},
- ui{new UI()},
- networking{new Networking()},
- app{BasePlatform::CreateApp()},
- context_ref{new ContextRef(nullptr)},
- network_reader{new NetworkReader()},
- network_writer{new NetworkWriter()},
+ : app_adapter{BasePlatform::CreateAppAdapter()},
+ app_config{new AppConfig()},
+ app_mode_{AppModeEmpty::GetSingleton()},
+ assets{new Assets()},
assets_server{new AssetsServer()},
+ audio{new Audio()},
+ audio_server{new AudioServer()},
+ basn_log_behavior_{g_core->platform->GetEnv("BASNLOG") == "1"},
bg_dynamics{g_core->HeadlessMode() ? nullptr : new BGDynamics},
bg_dynamics_server{g_core->HeadlessMode() ? nullptr
: new BGDynamicsServer},
- app_config{new AppConfig()},
+ context_ref{new ContextRef(nullptr)},
graphics{BasePlatform::CreateGraphics()},
graphics_server{new GraphicsServer()},
+ huffman{new Huffman()},
input{new Input()},
- text_graphics{new TextGraphics()},
- audio_server{new AudioServer()},
- assets{new Assets()},
- app_mode_{AppModeEmpty::GetSingleton()},
- basn_log_behavior_{g_core->platform->GetEnv("BASNLOG") == "1"},
+ logic{new Logic()},
+ network_reader{new NetworkReader()},
+ network_writer{new NetworkWriter()},
+ networking{new Networking()},
+ platform{BasePlatform::CreatePlatform()},
+ python{new BasePython()},
stdio_console{g_buildconfig.enable_stdio_console() ? new StdioConsole()
- : nullptr} {
+ : nullptr},
+ stress_test_{new StressTest()},
+ text_graphics{new TextGraphics()},
+ ui{new UI()},
+ utils{new Utils()} {
// We're a singleton. If there's already one of us, something's wrong.
assert(g_base == nullptr);
+
+ // We modify some app behavior when run under the server manager.
+ auto* envval = getenv("BA_SERVER_WRAPPER_MANAGED");
+ server_wrapper_managed_ = (envval && strcmp(envval, "1") == 0);
}
void BaseFeatureSet::OnModuleExec(PyObject* module) {
@@ -203,7 +203,7 @@ void BaseFeatureSet::StartApp() {
network_writer->OnMainThreadStartApp();
audio_server->OnMainThreadStartApp();
assets_server->OnMainThreadStartApp();
- app->OnMainThreadStartApp();
+ app_adapter->OnMainThreadStartApp();
// Take note that we're now 'running'. Various code such as anything that
// pushes messages to threads can watch for this state to avoid crashing
@@ -224,6 +224,19 @@ void BaseFeatureSet::StartApp() {
g_core->LifecycleLog("start-app end (main thread)");
}
+void BaseFeatureSet::OnAppShutdownComplete() {
+ assert(g_core->InMainThread());
+ assert(g_core);
+ assert(g_base);
+
+ // Flag our own event loop to exit (or ask the OS to if they're managing).
+ if (app_adapter->ManagesEventLoop()) {
+ g_core->main_event_loop()->Quit();
+ } else {
+ g_core->platform->QuitApp();
+ }
+}
+
void BaseFeatureSet::LogVersionInfo_() {
char buffer[256];
if (g_buildconfig.headless_build()) {
@@ -271,13 +284,13 @@ void BaseFeatureSet::set_app_mode(AppMode* mode) {
}
auto BaseFeatureSet::AppManagesEventLoop() -> bool {
- return app->ManagesEventLoop();
+ return app_adapter->ManagesEventLoop();
}
void BaseFeatureSet::RunAppToCompletion() {
BA_PRECONDITION(g_core->InMainThread());
BA_PRECONDITION(g_base);
- BA_PRECONDITION(g_base->app->ManagesEventLoop());
+ BA_PRECONDITION(g_base->app_adapter->ManagesEventLoop());
BA_PRECONDITION(!called_run_app_to_completion_);
called_run_app_to_completion_ = true;
@@ -292,7 +305,7 @@ void BaseFeatureSet::RunAppToCompletion() {
}
void BaseFeatureSet::PrimeAppMainThreadEventPump() {
- app->PrimeMainThreadEventPump();
+ app_adapter->PrimeMainThreadEventPump();
}
auto BaseFeatureSet::HavePlus() -> bool {
diff --git a/src/ballistica/base/base.h b/src/ballistica/base/base.h
index efebb56c..b8211f92 100644
--- a/src/ballistica/base/base.h
+++ b/src/ballistica/base/base.h
@@ -21,9 +21,9 @@ class CoreFeatureSet;
namespace ballistica::base {
-// Predeclare types we use throughout our FeatureSet so most
-// headers can get away with just including this header.
-class App;
+// Predeclare types we use throughout our FeatureSet so most headers can get
+// away with just including this header.
+class AppAdapter;
class AppConfig;
class AppTimer;
class AppMode;
@@ -99,7 +99,7 @@ class RenderTarget;
class RemoteAppServer;
class RemoteControlInput;
class ScoreToBeat;
-class AppSDL;
+class AppAdapterSDL;
class SDLContext;
class SoundAsset;
class SpriteMesh;
@@ -117,7 +117,7 @@ class TextureAssetRendererData;
class TouchInput;
class UI;
class UIV1SoftInterface;
-class AppVR;
+class AppAdapterVR;
class GraphicsVR;
enum class AssetType {
@@ -600,6 +600,9 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
/// Start app systems in motion.
void StartApp() override;
+ /// Called when app shutdown process completes. Sets app to exit.
+ void OnAppShutdownComplete();
+
auto AppManagesEventLoop() -> bool override;
/// Run app event loop to completion (only applies to flavors which manage
@@ -693,7 +696,7 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
void OnAssetsAvailable();
// Const subsystems.
- App* const app;
+ AppAdapter* const app_adapter;
AppConfig* const app_config;
Assets* const assets;
AssetsServer* const assets_server;
@@ -717,11 +720,16 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
UI* const ui;
Utils* const utils;
+ // Variable subsystems.
auto* console() const { return console_; }
auto* app_mode() const { return app_mode_; }
auto* stress_test() const { return stress_test_; }
void set_app_mode(AppMode* mode);
+ /// Whether we're running under ballisticakit_server.py
+ /// (affects some app behavior).
+ auto server_wrapper_managed() { return server_wrapper_managed_; }
+
// Non-const bits (fixme: clean up access to these).
TouchInput* touch_input{};
@@ -749,6 +757,7 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
bool base_import_completed_{};
bool base_native_import_completed_{};
bool basn_log_behavior_{};
+ bool server_wrapper_managed_{};
};
} // namespace ballistica::base
diff --git a/src/ballistica/base/graphics/gl/gl_sys.cc b/src/ballistica/base/graphics/gl/gl_sys.cc
index 9d311dbe..9073e671 100644
--- a/src/ballistica/base/graphics/gl/gl_sys.cc
+++ b/src/ballistica/base/graphics/gl/gl_sys.cc
@@ -3,7 +3,7 @@
#if BA_ENABLE_OPENGL
#include "ballistica/base/graphics/gl/gl_sys.h"
-#include "ballistica/base/app/app_sdl.h"
+#include "ballistica/base/app_adapter/app_adapter_sdl.h"
#include "ballistica/base/base.h"
#include "ballistica/core/core.h"
@@ -149,7 +149,7 @@ GLContext::GLContext(int target_res_x, int target_res_y, bool fullscreen)
// devices.
int win_size_x, win_size_y;
SDL_GetWindowSize(sdl_window_, &win_size_x, &win_size_y);
- AppSDL::Get()->SetInitialScreenDimensions(Vector2f(
+ AppAdapterSDL::Get()->SetInitialScreenDimensions(Vector2f(
static_cast(win_size_x), static_cast(win_size_y)));
#if BA_OSTYPE_IOS_TVOS || BA_OSTYPE_ANDROID
res_x_ = win_size_x;
@@ -188,7 +188,7 @@ GLContext::GLContext(int target_res_x, int target_res_y, bool fullscreen)
}
res_x_ = surface_->w;
res_y_ = surface_->h;
- AppSDL::Get()->SetInitialScreenDimensions(Vector2f(res_x_, res_y_));
+ AppAdapterSDL::Get()->SetInitialScreenDimensions(Vector2f(res_x_, res_y_));
SDL_WM_SetCaption("BallisticaKit", "BallisticaKit");
#elif BA_OSTYPE_ANDROID
// On Android the Java layer creates a GL setup before even calling us.
diff --git a/src/ballistica/base/graphics/graphics.cc b/src/ballistica/base/graphics/graphics.cc
index b71c8024..08914000 100644
--- a/src/ballistica/base/graphics/graphics.cc
+++ b/src/ballistica/base/graphics/graphics.cc
@@ -2,7 +2,7 @@
#include "ballistica/base/graphics/graphics.h"
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/dynamics/bg/bg_dynamics.h"
#include "ballistica/base/graphics/component/empty_component.h"
diff --git a/src/ballistica/base/graphics/graphics_server.cc b/src/ballistica/base/graphics/graphics_server.cc
index 8ca89292..64f9f6d1 100644
--- a/src/ballistica/base/graphics/graphics_server.cc
+++ b/src/ballistica/base/graphics/graphics_server.cc
@@ -8,9 +8,9 @@
// FIXME: clear out this conditional stuff.
#if BA_SDL_BUILD
-#include "ballistica/base/app/app_sdl.h"
+#include "ballistica/base/app_adapter/app_adapter_sdl.h"
#else
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/assets/assets.h"
#include "ballistica/base/graphics/mesh/mesh_data.h"
#include "ballistica/base/graphics/renderer/renderer.h"
@@ -71,7 +71,7 @@ auto GraphicsServer::GetRenderFrameDef() -> FrameDef* {
// If the app says it's minimized, don't do anything.
// (on iOS we'll get shut down if we make GL calls in this state, etc)
- if (g_base->app->paused()) {
+ if (g_base->app_adapter->app_paused()) {
return nullptr;
}
@@ -162,7 +162,7 @@ void GraphicsServer::FinishRenderFrameDef(FrameDef* frame_def) {
// Let the app know a frame render is complete (it may need to do a
// swap/etc).
- g_base->app->DidFinishRenderingFrame(frame_def);
+ g_base->app_adapter->DidFinishRenderingFrame(frame_def);
}
}
@@ -799,12 +799,12 @@ void GraphicsServer::PushSetVSyncCall(bool sync, bool auto_sync) {
#if BA_SDL_BUILD
- // Currently only supported for AppSDL.
+ // Currently only supported for AppAdapterSDL.
// May want to revisit this later.
if (g_buildconfig.sdl_build()) {
// Even if we were built with SDL, we may not be running in sdl-app-mode
// (for instance, Rift in VR mode). Only do this if we're an sdl app.
- if (auto app = dynamic_cast(g_base->app)) {
+ if (auto app = dynamic_cast(g_base->app_adapter)) {
v_sync_ = sync;
auto_vsync_ = auto_sync;
if (gl_context_) {
diff --git a/src/ballistica/base/input/device/joystick_input.cc b/src/ballistica/base/input/device/joystick_input.cc
index 08e46c8b..531e72a5 100644
--- a/src/ballistica/base/input/device/joystick_input.cc
+++ b/src/ballistica/base/input/device/joystick_input.cc
@@ -2,7 +2,7 @@
#include "ballistica/base/input/device/joystick_input.h"
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/graphics/renderer/renderer.h"
@@ -305,7 +305,7 @@ JoystickInput::~JoystickInput() {
// here in the logic thread..
if (sdl_joystick_) {
#if BA_ENABLE_SDL_JOYSTICKS
- assert(g_base->app);
+ assert(g_base->app_adapter);
auto joystick = sdl_joystick_;
g_core->main_event_loop()->PushCall(
[joystick] { SDL_JoystickClose(joystick); });
diff --git a/src/ballistica/base/input/input.cc b/src/ballistica/base/input/input.cc
index 8d536254..5847f3af 100644
--- a/src/ballistica/base/input/input.cc
+++ b/src/ballistica/base/input/input.cc
@@ -22,7 +22,7 @@ namespace ballistica::base {
Input::Input() = default;
template
-void SafePushCall(const char* desc, const F& lambda) {
+void SafePushLogicCall(const char* desc, const F& lambda) {
// Note: originally this call was created to silently ignore early events
// coming in before app stuff was up and running, but that was a bad idea,
// as it caused us to ignore device-create messages sometimes which lead
@@ -41,7 +41,7 @@ void SafePushCall(const char* desc, const F& lambda) {
}
void Input::PushCreateKeyboardInputDevices() {
- SafePushCall(__func__, [this] { CreateKeyboardInputDevices(); });
+ SafePushLogicCall(__func__, [this] { CreateKeyboardInputDevices(); });
}
void Input::CreateKeyboardInputDevices() {
@@ -58,7 +58,7 @@ void Input::CreateKeyboardInputDevices() {
}
void Input::PushDestroyKeyboardInputDevices() {
- SafePushCall(__func__, [this] { DestroyKeyboardInputDevices(); });
+ SafePushLogicCall(__func__, [this] { DestroyKeyboardInputDevices(); });
}
void Input::DestroyKeyboardInputDevices() {
@@ -275,7 +275,7 @@ void Input::ShowStandardInputDeviceDisconnectedMessage(InputDevice* j) {
void Input::PushAddInputDeviceCall(InputDevice* input_device,
bool standard_message) {
- SafePushCall(__func__, [this, input_device, standard_message] {
+ SafePushLogicCall(__func__, [this, input_device, standard_message] {
AddInputDevice(input_device, standard_message);
});
}
@@ -301,8 +301,8 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) {
device->set_delegate(delegate);
delegate->set_input_device(device);
- // Lets go through and find the first unused input-device id and use that
- // (might as well keep our list small if we can).
+ // Find the first unused input-device id and use that (might as well keep
+ // our list small if we can).
int index = 0;
bool found_slot = false;
for (auto& input_device : input_devices_) {
@@ -361,7 +361,7 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) {
void Input::PushRemoveInputDeviceCall(InputDevice* input_device,
bool standard_message) {
- SafePushCall(__func__, [this, input_device, standard_message] {
+ SafePushLogicCall(__func__, [this, input_device, standard_message] {
RemoveInputDevice(input_device, standard_message);
});
}
@@ -818,7 +818,7 @@ void Input::ProcessStressTesting(int player_count) {
}
void Input::PushTextInputEvent(const std::string& text) {
- SafePushCall(__func__, [this, text] {
+ SafePushLogicCall(__func__, [this, text] {
MarkInputActive();
// Ignore if input is locked.
@@ -836,7 +836,7 @@ void Input::PushTextInputEvent(const std::string& text) {
void Input::PushJoystickEvent(const SDL_Event& event,
InputDevice* input_device) {
- SafePushCall(__func__, [this, event, input_device] {
+ SafePushLogicCall(__func__, [this, event, input_device] {
HandleJoystickEvent(event, input_device);
});
}
@@ -870,11 +870,11 @@ void Input::HandleJoystickEvent(const SDL_Event& event,
}
void Input::PushKeyPressEvent(const SDL_Keysym& keysym) {
- SafePushCall(__func__, [this, keysym] { HandleKeyPress(&keysym); });
+ SafePushLogicCall(__func__, [this, keysym] { HandleKeyPress(&keysym); });
}
void Input::PushKeyReleaseEvent(const SDL_Keysym& keysym) {
- SafePushCall(__func__, [this, keysym] { HandleKeyRelease(&keysym); });
+ SafePushLogicCall(__func__, [this, keysym] { HandleKeyRelease(&keysym); });
}
void Input::CaptureKeyboardInput(HandleKeyPressCall* press_call,
@@ -1026,13 +1026,14 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) {
}
case SDLK_F7:
- SafePushCall(__func__, [] { g_base->graphics->ToggleManualCamera(); });
+ SafePushLogicCall(__func__,
+ [] { g_base->graphics->ToggleManualCamera(); });
handled = true;
break;
case SDLK_F8:
- SafePushCall(__func__,
- [] { g_base->graphics->ToggleNetworkDebugDisplay(); });
+ SafePushLogicCall(
+ __func__, [] { g_base->graphics->ToggleNetworkDebugDisplay(); });
handled = true;
break;
@@ -1043,7 +1044,8 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) {
break;
case SDLK_F10:
- SafePushCall(__func__, [] { g_base->graphics->ToggleDebugDraw(); });
+ SafePushLogicCall(__func__,
+ [] { g_base->graphics->ToggleDebugDraw(); });
handled = true;
break;
@@ -1152,7 +1154,7 @@ void Input::UpdateModKeyStates(const SDL_Keysym* keysym, bool press) {
}
void Input::PushMouseScrollEvent(const Vector2f& amount) {
- SafePushCall(__func__, [this, amount] { HandleMouseScroll(amount); });
+ SafePushLogicCall(__func__, [this, amount] { HandleMouseScroll(amount); });
}
void Input::HandleMouseScroll(const Vector2f& amount) {
@@ -1184,7 +1186,7 @@ void Input::HandleMouseScroll(const Vector2f& amount) {
void Input::PushSmoothMouseScrollEvent(const Vector2f& velocity,
bool momentum) {
- SafePushCall(__func__, [this, velocity, momentum] {
+ SafePushLogicCall(__func__, [this, velocity, momentum] {
HandleSmoothMouseScroll(velocity, momentum);
});
}
@@ -1216,7 +1218,8 @@ void Input::HandleSmoothMouseScroll(const Vector2f& velocity, bool momentum) {
}
void Input::PushMouseMotionEvent(const Vector2f& position) {
- SafePushCall(__func__, [this, position] { HandleMouseMotion(position); });
+ SafePushLogicCall(__func__,
+ [this, position] { HandleMouseMotion(position); });
}
void Input::HandleMouseMotion(const Vector2f& position) {
@@ -1268,8 +1271,9 @@ void Input::HandleMouseMotion(const Vector2f& position) {
}
void Input::PushMouseDownEvent(int button, const Vector2f& position) {
- SafePushCall(__func__,
- [this, button, position] { HandleMouseDown(button, position); });
+ SafePushLogicCall(__func__, [this, button, position] {
+ HandleMouseDown(button, position);
+ });
}
void Input::HandleMouseDown(int button, const Vector2f& position) {
@@ -1344,8 +1348,8 @@ void Input::HandleMouseDown(int button, const Vector2f& position) {
}
void Input::PushMouseUpEvent(int button, const Vector2f& position) {
- SafePushCall(__func__,
- [this, button, position] { HandleMouseUp(button, position); });
+ SafePushLogicCall(
+ __func__, [this, button, position] { HandleMouseUp(button, position); });
}
void Input::HandleMouseUp(int button, const Vector2f& position) {
@@ -1396,7 +1400,7 @@ void Input::HandleMouseUp(int button, const Vector2f& position) {
}
void Input::PushTouchEvent(const TouchEvent& e) {
- SafePushCall(__func__, [e, this] { HandleTouchEvent(e); });
+ SafePushLogicCall(__func__, [e, this] { HandleTouchEvent(e); });
}
void Input::HandleTouchEvent(const TouchEvent& e) {
diff --git a/src/ballistica/base/logic/logic.cc b/src/ballistica/base/logic/logic.cc
index e1f065a4..2086c262 100644
--- a/src/ballistica/base/logic/logic.cc
+++ b/src/ballistica/base/logic/logic.cc
@@ -2,16 +2,17 @@
#include "ballistica/base/logic/logic.h"
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/input/input.h"
+#include "ballistica/base/networking/networking.h"
#include "ballistica/base/python/base_python.h"
#include "ballistica/base/support/plus_soft.h"
+#include "ballistica/base/support/stdio_console.h"
#include "ballistica/base/ui/console.h"
#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/foundation/event_loop.h"
-#include "ballistica/shared/python/python_command.h"
#include "ballistica/shared/python/python_sys.h"
namespace ballistica::base {
@@ -25,65 +26,76 @@ Logic::Logic() : display_timers_(new TimerList()) {
}
void Logic::OnMainThreadStartApp() {
+ // Spin up our logic thread and sit and wait for it to init.
event_loop_ = new EventLoop(EventLoopID::kLogic);
g_core->pausable_event_loops.push_back(event_loop_);
-
- // Sit and wait for our logic thread to run its startup stuff.
event_loop_->PushCallSynchronous([this] { OnAppStart(); });
}
void Logic::OnAppStart() {
assert(g_base->InLogicThread());
g_core->LifecycleLog("on-app-start begin (logic thread)");
- try {
- // Our thread should not be holding the GIL here at the start (and
- // probably not have any Python state at all). So here we set both
- // of those up.
- assert(!PyGILState_Check());
- PyGILState_Ensure();
- // Code running in the logic thread holds the GIL by default.
- event_loop_->SetAcquiresPythonGIL();
+ // Our thread should not be holding the GIL here at the start (and
+ // probably will not have any Python state at all). So here we set both
+ // of those up.
+ assert(!PyGILState_Check());
+ PyGILState_Ensure();
- // Keep informed when our thread's event loop is pausing/unpausing.
- event_loop_->AddPauseCallback(
- NewLambdaRunnableUnmanaged([this] { OnAppPause(); }));
- event_loop_->AddResumeCallback(
- NewLambdaRunnableUnmanaged([this] { OnAppResume(); }));
+ // Code running in the logic thread holds the GIL by default.
+ event_loop_->SetAcquiresPythonGIL();
- // Running in a specific order here and should try to stick to it in
- // other OnAppXXX callbacks so any subsystem interdependencies behave
- // consistently. When pausing or shutting-down we use the opposite order for
- // the same reason. Let's do Python last (or first when pausing, etc) since
- // it will be the most variable; that way it will interact with other
- // subsystems in their normal states which is less likely to lead to
- // problems.
- g_base->graphics->OnAppStart();
- g_base->audio->OnAppStart();
- g_base->input->OnAppStart();
- g_base->ui->OnAppStart();
- g_core->platform->OnAppStart();
- g_base->app_mode()->OnAppStart();
- if (g_base->HavePlus()) {
- g_base->plus()->OnAppStart();
- }
- g_base->python->OnAppStart();
- } catch (const std::exception& e) {
- // If anything went wrong, trigger a deferred error.
- // This way it is more likely we can show a fatal error dialog
- // since the main thread won't be blocking waiting for us to init.
- std::string what = e.what();
- this->event_loop()->PushCall([what] {
- // Just throw a std exception since our 'what' probably already
- // contains a stack trace; if we throw a ballistica Exception we
- // wind up with a useless second one.
- throw std::logic_error(what.c_str());
- });
+ // Stay informed when our event loop is pausing/unpausing.
+ event_loop_->AddPauseCallback(
+ NewLambdaRunnableUnmanaged([this] { OnAppPause(); }));
+ event_loop_->AddResumeCallback(
+ NewLambdaRunnableUnmanaged([this] { OnAppResume(); }));
+
+ // Running in a specific order here and should try to stick to it in
+ // other OnAppXXX callbacks so any subsystem interdependencies behave
+ // consistently. When pausing or shutting-down we use the opposite order for
+ // the same reason. Let's do Python last (or first when pausing, etc) since
+ // it will be the most variable; that way it will interact with other
+ // subsystems in their normal states which is less likely to lead to
+ // problems.
+ g_base->graphics->OnAppStart();
+ g_base->audio->OnAppStart();
+ g_base->input->OnAppStart();
+ g_base->ui->OnAppStart();
+ g_core->platform->OnAppStart();
+ g_base->app_mode()->OnAppStart();
+ if (g_base->HavePlus()) {
+ g_base->plus()->OnAppStart();
}
+ g_base->python->OnAppStart();
+
g_core->LifecycleLog("on-app-start end (logic thread)");
}
+void Logic::OnAppRunning() {
+ assert(g_base->InLogicThread());
+ assert(g_base->CurrentContext().IsEmpty());
+
+ // Currently don't do anything here.
+}
+
+void Logic::OnInitialAppModeSet() {
+ assert(g_base->InLogicThread());
+ assert(g_base->CurrentContext().IsEmpty());
+
+ // We want any sort of raw Python input to only start accepting commands
+ // once we've got an initial app-mode set. Generally said commands will
+ // assume we're running in that mode and will fail if run before it is set.
+ if (auto* console = g_base->console()) {
+ console->EnableInput();
+ }
+ if (g_base->stdio_console) {
+ g_base->stdio_console->Start();
+ }
+}
+
void Logic::OnAppPause() {
+ assert(g_base->InLogicThread());
assert(g_base->CurrentContext().IsEmpty());
// Note: keep these in opposite order of OnAppStart.
@@ -100,6 +112,7 @@ void Logic::OnAppPause() {
}
void Logic::OnAppResume() {
+ assert(g_base->InLogicThread());
assert(g_base->CurrentContext().IsEmpty());
// Note: keep these in the same order as OnAppStart.
@@ -137,8 +150,7 @@ void Logic::OnAppShutdown() {
// FIXME: Should add a mechanism where we give the above subsystems
// a short bit of time to complete shutdown if they need it.
// For now just completing instantly.
- g_core->main_event_loop()->PushCall(
- [] { g_base->app->LogicThreadShutdownComplete(); });
+ g_core->main_event_loop()->PushCall([] { g_base->OnAppShutdownComplete(); });
}
void Logic::DoApplyAppConfig() {
@@ -157,10 +169,10 @@ void Logic::DoApplyAppConfig() {
}
g_base->python->DoApplyAppConfig();
- // Give the app subsystem a chance too even though its main-thread based.
- // We call it here in the logic thread, allowing it to read whatever
- // it needs and pass it to itself in the main thread.
- g_base->app->DoLogicThreadApplyAppConfig();
+ // Inform some other subsystems even though they're not our standard
+ // set of logic-thread-based ones.
+ g_base->app_adapter->LogicThreadDoApplyAppConfig();
+ g_base->networking->DoApplyAppConfig();
applied_app_config_ = true;
}
@@ -223,7 +235,7 @@ void Logic::CompleteAppBootstrapping() {
asset_prune_timer_ = event_loop()->NewTimer(
2345, true, NewLambdaRunnable([] { g_base->assets->Prune(); }));
- // Let our initial app-mode know it has become active.
+ // Let our initial dummy app-mode know it has become active.
g_base->app_mode()->OnActivate();
// Reset our various subsystems to a default state.
@@ -291,7 +303,6 @@ void Logic::StepDisplayTime() {
g_base->plus()->StepDisplayTime();
}
g_base->python->StepDisplayTime();
- g_base->app->LogicThreadStepDisplayTime();
// Let's run display-timers *after* we step everything else so most things
// they interact with will be in an up-to-date state.
@@ -546,7 +557,7 @@ void Logic::HandleInterruptSignal() {
// Special case; when running under the server-wrapper, we completely
// ignore interrupt signals (the wrapper acts on them).
- if (g_base->app->server_wrapper_managed()) {
+ if (g_base->server_wrapper_managed()) {
return;
}
diff --git a/src/ballistica/base/logic/logic.h b/src/ballistica/base/logic/logic.h
index 631085aa..93d33a8f 100644
--- a/src/ballistica/base/logic/logic.h
+++ b/src/ballistica/base/logic/logic.h
@@ -13,22 +13,36 @@ namespace ballistica::base {
const int kDisplayTimeSampleCount{15};
-/// The logic subsystem of the app. This runs on a dedicated thread
-/// and is where most high level app logic happens. Much app functionality
+/// The logic subsystem of the app. This runs on a dedicated thread and is
+/// where most high level app logic happens. Much app functionality
/// including UI calls must be run on the logic thread.
class Logic {
public:
Logic();
- /// Where our stuff runs. Be aware this will return nullptr
- /// if the app has not started running yet.
+ /// Where our stuff runs. Be aware this will return nullptr if the app has
+ /// not started running yet.
auto event_loop() const -> EventLoop* { return event_loop_; }
void OnMainThreadStartApp();
void OnInitialScreenCreated();
void OnAppStart();
+
+ /// Called by Python when the app reaches the RUNNING state.
+ void OnAppRunning();
+
+ /// Called by Python after the first app-mode has been set. At this point
+ /// it is safe to start using functionality that interacts with app-modes.
+ void OnInitialAppModeSet();
+
+ /// Called when our event-loop pauses. Informs Python and other
+ /// subsystems.
void OnAppPause();
+
+ /// Called when our event-loop resumes. Informs Python and other
+ /// subsystems.
void OnAppResume();
+
void OnAppShutdown();
void OnAppModeChanged();
@@ -37,16 +51,16 @@ class Logic {
void OnScreenSizeChange(float virtual_width, float virtual_height,
float pixel_width, float pixel_height);
- /// Called when we should ship a new frame-def to the graphics server.
- /// In graphical builds we also use this opportunity to step our logic.
+ /// Called when we should ship a new frame-def to the graphics server. In
+ /// graphical builds we also use this opportunity to step our logic.
void Draw();
/// Kick off a low level app shutdown which will result in the process
- /// exiting. Platform-agnostic code should generally not call this directly
- /// and should instead use high level calls like babase.quit(). This allows
- /// platforms such as mobile to take alternate actions which may involve
- /// leaving the underlying process running.
- /// FIXME: I feel like this should be in one of the App classes.
+ /// exiting. Platform-agnostic code should generally not call this
+ /// directly and should instead use high level calls like babase.quit().
+ /// This allows platforms such as mobile to take alternate actions which
+ /// may involve leaving the underlying process running. FIXME: I feel like
+ /// this should be in one of the App classes.
void Shutdown();
/// Has CompleteAppBootstrapping been called?
diff --git a/src/ballistica/base/networking/network_reader.cc b/src/ballistica/base/networking/network_reader.cc
index 661499f9..e6609221 100644
--- a/src/ballistica/base/networking/network_reader.cc
+++ b/src/ballistica/base/networking/network_reader.cc
@@ -5,7 +5,6 @@
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/input/support/remote_app_server.h"
#include "ballistica/base/logic/logic.h"
-#include "ballistica/base/python/base_python.h"
#include "ballistica/core/platform/core_platform.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/generic/json.h"
diff --git a/src/ballistica/base/networking/networking.cc b/src/ballistica/base/networking/networking.cc
index 58e24fad..0171867d 100644
--- a/src/ballistica/base/networking/networking.cc
+++ b/src/ballistica/base/networking/networking.cc
@@ -2,7 +2,6 @@
#include "ballistica/base/networking/networking.h"
-#include "ballistica/base/app/app.h"
#include "ballistica/base/networking/network_reader.h"
#include "ballistica/base/support/app_config.h"
#include "ballistica/shared/foundation/event_loop.h"
diff --git a/src/ballistica/base/platform/base_platform.cc b/src/ballistica/base/platform/base_platform.cc
index dfcb8499..79d360b7 100644
--- a/src/ballistica/base/platform/base_platform.cc
+++ b/src/ballistica/base/platform/base_platform.cc
@@ -17,15 +17,15 @@
#include "ballistica/shared/python/python_sys.h"
#if BA_VR_BUILD
-#include "ballistica/base/app/app_vr.h"
+#include "ballistica/base/app_adapter/app_adapter_vr.h"
#endif
#if BA_HEADLESS_BUILD
-#include "ballistica/base/app/app_headless.h"
+#include "ballistica/base/app_adapter/app_adapter_headless.h"
#endif
-#include "ballistica/base/app/app.h"
-#include "ballistica/base/app/app_sdl.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
+#include "ballistica/base/app_adapter/app_adapter_sdl.h"
#include "ballistica/base/graphics/graphics.h"
#include "ballistica/base/graphics/graphics_vr.h"
@@ -105,39 +105,36 @@ void BasePlatform::PostInit() {
BasePlatform::~BasePlatform() = default;
-auto BasePlatform::CreateApp() -> App* {
+auto BasePlatform::CreateAppAdapter() -> AppAdapter* {
assert(g_core);
- // assert(InMainThread());
- // assert(g_main_thread);
// TEMP - need to init sdl on our legacy mac build even though its not
// technically an SDL app. Kill this once the old mac build is gone.
#if BA_LEGACY_MACOS_BUILD
- AppSDL::InitSDL();
+ AppAdapterSDL::InitSDL();
#endif
- App* app{};
+ AppAdapter* app_adapter{};
#if BA_HEADLESS_BUILD
- app = new AppHeadless();
+ app_adapter = new AppAdapterHeadless();
#elif BA_RIFT_BUILD
// Rift build can spin up in either VR or regular mode.
if (g_core->vr_mode) {
- app = new AppVR();
+ app_adapter = new AppAdapterVR();
} else {
- app = new AppSDL();
+ app_adapter = new AppAdapterSDL();
}
#elif BA_CARDBOARD_BUILD
- app = new AppVR();
+ app_adapter = new AppAdapterVR();
#elif BA_SDL_BUILD
- app = new AppSDL();
+ app_adapter = new AppAdapterSDL();
#else
- app = new App();
+ app_adapter = new AppAdapter();
#endif
- assert(app);
- app->PostInit();
- return app;
+ assert(app_adapter);
+ return app_adapter;
}
auto BasePlatform::CreateGraphics() -> Graphics* {
diff --git a/src/ballistica/base/platform/base_platform.h b/src/ballistica/base/platform/base_platform.h
index 9b02a056..f9270d38 100644
--- a/src/ballistica/base/platform/base_platform.h
+++ b/src/ballistica/base/platform/base_platform.h
@@ -3,8 +3,6 @@
#ifndef BALLISTICA_BASE_PLATFORM_BASE_PLATFORM_H_
#define BALLISTICA_BASE_PLATFORM_BASE_PLATFORM_H_
-#include
-
#include "ballistica/base/base.h"
namespace ballistica::base {
@@ -16,9 +14,10 @@ class BasePlatform {
static auto CreatePlatform() -> BasePlatform*;
/// Instantiate the appropriate App subclass for the current environment.
- static auto CreateApp() -> App*;
+ static auto CreateAppAdapter() -> AppAdapter*;
- /// Instantiate the appropriate Graphics subclass for the current environment.
+ /// Instantiate the appropriate Graphics subsystem for the current
+ /// environment.
static auto CreateGraphics() -> Graphics*;
#pragma mark APP LIFECYCLE -----------------------------------------------------
diff --git a/src/ballistica/base/python/base_python.cc b/src/ballistica/base/python/base_python.cc
index 2386ce41..005243a4 100644
--- a/src/ballistica/base/python/base_python.cc
+++ b/src/ballistica/base/python/base_python.cc
@@ -13,7 +13,6 @@
#include "ballistica/base/python/methods/python_methods_app.h"
#include "ballistica/base/python/methods/python_methods_graphics.h"
#include "ballistica/base/python/methods/python_methods_misc.h"
-#include "ballistica/core/python/core_python.h"
#include "ballistica/shared/python/python_command.h"
#include "ballistica/shared/python/python_module_builder.h"
diff --git a/src/ballistica/base/python/methods/python_methods_app.cc b/src/ballistica/base/python/methods/python_methods_app.cc
index d05342e5..9c397a65 100644
--- a/src/ballistica/base/python/methods/python_methods_app.cc
+++ b/src/ballistica/base/python/methods/python_methods_app.cc
@@ -2,8 +2,6 @@
#include "ballistica/base/python/methods/python_methods_app.h"
-#include "ballistica/base/app/app.h"
-#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/app_mode/app_mode_empty.h"
#include "ballistica/base/graphics/graphics_server.h"
#include "ballistica/base/logic/logic.h"
@@ -1275,7 +1273,7 @@ static PyMethodDef PyExecArgDef = {
static auto PyOnAppRunning(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base && g_base->InLogicThread());
- g_base->app->LogicThreadOnAppRunning();
+ g_base->logic->OnAppRunning();
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
@@ -1295,7 +1293,7 @@ static PyMethodDef PyOnAppRunningDef = {
static auto PyOnInitialAppModeSet(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base && g_base->InLogicThread());
- g_base->app->LogicThreadOnInitialAppModeSet();
+ g_base->logic->OnInitialAppModeSet();
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
diff --git a/src/ballistica/base/support/stdio_console.cc b/src/ballistica/base/support/stdio_console.cc
index 6e1c830f..50cc91e0 100644
--- a/src/ballistica/base/support/stdio_console.cc
+++ b/src/ballistica/base/support/stdio_console.cc
@@ -4,7 +4,6 @@
#include
-#include "ballistica/base/app/app.h"
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/base/support/context.h"
@@ -129,7 +128,7 @@ void StdioConsole::PushCommand(const std::string& command) {
// Print the value if we're running directly from a terminal
// (or being run under the server-manager)
if ((g_core->platform->is_stdin_a_terminal()
- || g_base->app->server_wrapper_managed())
+ || g_base->server_wrapper_managed())
&& obj.Get() != Py_None) {
printf("%s\n", obj.Repr().c_str());
fflush(stdout);
diff --git a/src/ballistica/base/ui/ui.cc b/src/ballistica/base/ui/ui.cc
index daf674fe..fb3fe804 100644
--- a/src/ballistica/base/ui/ui.cc
+++ b/src/ballistica/base/ui/ui.cc
@@ -7,7 +7,6 @@
#include "ballistica/base/input/input.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/base/python/base_python.h"
-#include "ballistica/base/support/app_config.h"
#include "ballistica/base/support/ui_v1_soft.h"
#include "ballistica/base/ui/console.h"
#include "ballistica/shared/foundation/event_loop.h"
diff --git a/src/ballistica/classic/classic.cc b/src/ballistica/classic/classic.cc
index dd833f46..b98d4570 100644
--- a/src/ballistica/classic/classic.cc
+++ b/src/ballistica/classic/classic.cc
@@ -6,7 +6,6 @@
#include "ballistica/classic/support/v1_account.h"
#include "ballistica/core/platform/core_platform.h"
#include "ballistica/scene_v1/python/scene_v1_python.h"
-#include "ballistica/scene_v1/scene_v1.h"
#include "ballistica/scene_v1/support/player_spec.h"
#include "ballistica/shared/generic/utils.h"
diff --git a/src/ballistica/classic/python/classic_python.cc b/src/ballistica/classic/python/classic_python.cc
index 655102e4..4c3a7f9e 100644
--- a/src/ballistica/classic/python/classic_python.cc
+++ b/src/ballistica/classic/python/classic_python.cc
@@ -2,7 +2,6 @@
#include "ballistica/classic/python/classic_python.h"
-#include "ballistica/base/input/device/input_device.h"
#include "ballistica/classic/python/methods/python_methods_classic.h"
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
#include "ballistica/shared/python/python_command.h"
diff --git a/src/ballistica/core/core.cc b/src/ballistica/core/core.cc
index 45ee45cb..7b09ca64 100644
--- a/src/ballistica/core/core.cc
+++ b/src/ballistica/core/core.cc
@@ -54,7 +54,8 @@ auto CoreFeatureSet::Import(const CoreConfig* config) -> CoreFeatureSet* {
// between monolithic and modular.
std::vector argbuffer;
std::vector argv = CorePython::FetchPythonArgs(&argbuffer);
- DoImport(CoreConfig::ForArgsAndEnvVars(argv.size(), argv.data()));
+ DoImport(CoreConfig::ForArgsAndEnvVars(static_cast(argv.size()),
+ argv.data()));
} else {
DoImport(CoreConfig::ForEnvVars());
}
@@ -95,6 +96,9 @@ void CoreFeatureSet::PostInit() {
// Some of this stuff might access g_core so we run most of our init
// *after* assigning our singleton to be safe.
+ // Should migrate this to classic.
+ set_legacy_user_agent_string(platform->GetLegacyUserAgentString());
+
RunSanityChecks();
build_src_dir_ = CalcBuildSrcDir();
@@ -218,6 +222,16 @@ auto CoreFeatureSet::CalcBuildSrcDir() -> std::string {
}
void CoreFeatureSet::RunSanityChecks() {
+ // Sanity check: make sure asserts are stripped out of release builds
+ // (NDEBUG should do this).
+#if !BA_DEBUG_BUILD
+#ifndef NDEBUG
+#error Expected NDEBUG to be defined for release builds.
+#endif
+ // If this kills the app, something's wrong.
+ assert(false);
+#endif // !BA_DEBUG_BUILD
+
// Test our static-type-name functionality. This code runs at compile time
// and extracts human readable type names using __PRETTY_FUNCTION__ type
// functionality. However, it is dependent on specific compiler output and
diff --git a/src/ballistica/core/core.h b/src/ballistica/core/core.h
index e1715e14..a17b01a0 100644
--- a/src/ballistica/core/core.h
+++ b/src/ballistica/core/core.h
@@ -15,8 +15,8 @@
namespace ballistica::core {
-// Predeclare types we use throughout our FeatureSet so most
-// headers can get away with just including this header.
+// Predeclare types we use throughout our FeatureSet so most headers can get
+// away with just including this header.
class CoreConfig;
class CorePython;
class CorePlatform;
diff --git a/src/ballistica/core/support/core_config.cc b/src/ballistica/core/support/core_config.cc
index e73935f5..f18b08e4 100644
--- a/src/ballistica/core/support/core_config.cc
+++ b/src/ballistica/core/support/core_config.cc
@@ -178,7 +178,7 @@ auto CoreConfig::ForEnvVars() -> CoreConfig {
return cfg;
}
-auto CoreConfig::ForArgsAndEnvVars(size_t argc, char** argv) -> CoreConfig {
+auto CoreConfig::ForArgsAndEnvVars(int argc, char** argv) -> CoreConfig {
CoreConfig cfg{};
// Apply env-vars first. We want explicit args to override these.
diff --git a/src/ballistica/core/support/core_config.h b/src/ballistica/core/support/core_config.h
index 3c6f00bb..ddcd5450 100644
--- a/src/ballistica/core/support/core_config.h
+++ b/src/ballistica/core/support/core_config.h
@@ -14,7 +14,7 @@ namespace ballistica::core {
/// when initing the core feature-set.
class CoreConfig {
public:
- static auto ForArgsAndEnvVars(size_t argc, char** argv) -> CoreConfig;
+ static auto ForArgsAndEnvVars(int argc, char** argv) -> CoreConfig;
static auto ForEnvVars() -> CoreConfig;
diff --git a/src/ballistica/scene_v1/connection/connection_to_client.cc b/src/ballistica/scene_v1/connection/connection_to_client.cc
index 8e3cdc9c..876e50e7 100644
--- a/src/ballistica/scene_v1/connection/connection_to_client.cc
+++ b/src/ballistica/scene_v1/connection/connection_to_client.cc
@@ -17,7 +17,6 @@
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
#include "ballistica/shared/generic/json.h"
#include "ballistica/shared/generic/utils.h"
-#include "ballistica/shared/python/python.h"
#include "ballistica/shared/python/python_sys.h"
namespace ballistica::scene_v1 {
diff --git a/src/ballistica/scene_v1/scene_v1.cc b/src/ballistica/scene_v1/scene_v1.cc
index 06787c2a..a6a29551 100644
--- a/src/ballistica/scene_v1/scene_v1.cc
+++ b/src/ballistica/scene_v1/scene_v1.cc
@@ -26,7 +26,6 @@
#include "ballistica/scene_v1/node/texture_sequence_node.h"
#include "ballistica/scene_v1/node/time_display_node.h"
#include "ballistica/scene_v1/python/scene_v1_python.h"
-#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
#include "ballistica/shared/generic/utils.h"
namespace ballistica::scene_v1 {
diff --git a/src/ballistica/scene_v1/scene_v1.h b/src/ballistica/scene_v1/scene_v1.h
index 8f16eb44..53211a32 100644
--- a/src/ballistica/scene_v1/scene_v1.h
+++ b/src/ballistica/scene_v1/scene_v1.h
@@ -32,7 +32,8 @@ const int kGameStepMilliseconds = 8;
const float kGameStepSeconds =
(static_cast(kGameStepMilliseconds) / 1000.0f);
-// Predeclared types our feature-set provides.
+// Predeclare types we use throughout our FeatureSet so most headers can get
+// away with just including this header.
class ClientControllerInterface;
class ClientInputDevice;
class ClientSession;
diff --git a/src/ballistica/scene_v1/support/client_session_replay.cc b/src/ballistica/scene_v1/support/client_session_replay.cc
index 2e6de6f5..c57d76ac 100644
--- a/src/ballistica/scene_v1/support/client_session_replay.cc
+++ b/src/ballistica/scene_v1/support/client_session_replay.cc
@@ -10,7 +10,6 @@
#include "ballistica/scene_v1/connection/connection_to_client.h"
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
#include "ballistica/scene_v1/support/session_stream.h"
-#include "ballistica/shared/generic/utils.h"
#include "ballistica/shared/math/vector3f.h"
namespace ballistica::scene_v1 {
diff --git a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
index 750c1e24..47f5c3dd 100644
--- a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
+++ b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
@@ -12,7 +12,6 @@
#include "ballistica/base/support/app_config.h"
#include "ballistica/base/support/plus_soft.h"
#include "ballistica/base/ui/ui.h"
-#include "ballistica/core/platform/core_platform.h"
#include "ballistica/scene_v1/connection/connection_set.h"
#include "ballistica/scene_v1/connection/connection_to_client_udp.h"
#include "ballistica/scene_v1/connection/connection_to_host.h"
diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc
index 09e3f1a2..2a9a89e1 100644
--- a/src/ballistica/shared/ballistica.cc
+++ b/src/ballistica/shared/ballistica.cc
@@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
-const int kEngineBuildNumber = 21232;
+const int kEngineBuildNumber = 21241;
const char* kEngineVersion = "1.7.26";
#if BA_MONOLITHIC_BUILD
diff --git a/src/ballistica/shared/foundation/types.h b/src/ballistica/shared/foundation/types.h
index fc76099b..da38a58e 100644
--- a/src/ballistica/shared/foundation/types.h
+++ b/src/ballistica/shared/foundation/types.h
@@ -59,7 +59,7 @@ class Vector4f;
// FIXME: remove this - a few base things we need.
namespace base {
-class App;
+class AppAdapter;
class Graphics;
} // namespace base
diff --git a/src/ballistica/shared/python/python.cc b/src/ballistica/shared/python/python.cc
index 58a24262..1b5e689a 100644
--- a/src/ballistica/shared/python/python.cc
+++ b/src/ballistica/shared/python/python.cc
@@ -3,7 +3,6 @@
#include "ballistica/shared/python/python.h"
#include "ballistica/core/support/base_soft.h"
-#include "ballistica/shared/python/python_command.h"
#include "ballistica/shared/python/python_sys.h"
// Sanity test: our XCode, Android, and Windows builds should be
diff --git a/src/ballistica/shared/python/python_object_set.cc b/src/ballistica/shared/python/python_object_set.cc
index ea723bbf..77f29e6e 100644
--- a/src/ballistica/shared/python/python_object_set.cc
+++ b/src/ballistica/shared/python/python_object_set.cc
@@ -5,7 +5,6 @@
#include
#include "ballistica/core/support/base_soft.h"
-#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/python/python_command.h"
#include "ballistica/shared/python/python_sys.h"
diff --git a/src/ballistica/shared/python/python_ref.cc b/src/ballistica/shared/python/python_ref.cc
index 660a3ea4..91d4b70a 100644
--- a/src/ballistica/shared/python/python_ref.cc
+++ b/src/ballistica/shared/python/python_ref.cc
@@ -2,9 +2,7 @@
#include "ballistica/shared/python/python_ref.h"
-#include "ballistica/core/python/core_python.h"
#include "ballistica/core/support/base_soft.h"
-#include "ballistica/shared/foundation/types.h"
#include "ballistica/shared/math/vector2f.h"
#include "ballistica/shared/python/python.h"
#include "ballistica/shared/python/python_sys.h"
diff --git a/src/ballistica/template_fs/template_fs.h b/src/ballistica/template_fs/template_fs.h
index afca6fc5..aa2d1b89 100644
--- a/src/ballistica/template_fs/template_fs.h
+++ b/src/ballistica/template_fs/template_fs.h
@@ -17,18 +17,20 @@ namespace ballistica::base {
class BaseFeatureSet;
}
-// Feature-sets have their own unique namespace under the ballistica namespace.
+// Feature-sets have their own unique namespace under the ballistica
+// namespace.
namespace ballistica::template_fs {
-// Predeclared types our feature-set provides.
+// Predeclare types we use throughout our FeatureSet so most headers can get
+// away with just including this header.
class TemplateFsFeatureSet;
class TemplateFsPython;
-// Our feature-set's globals.
-// Feature-sets should NEVER directly access globals in another feature-set's
-// namespace. All functionality we need from other feature-sets should be
-// imported into globals in our own namespace. Generally we do this when we
-// are initially imported (just as regular Python modules do).
+// Our feature-set's globals. Feature-sets should NEVER directly access
+// globals in another feature-set's namespace. All functionality we need
+// from other feature-sets should be imported into globals in our own
+// namespace. Generally we do this when we are initially imported (just as
+// regular Python modules do).
extern core::CoreFeatureSet* g_core;
extern base::BaseFeatureSet* g_base;
extern TemplateFsFeatureSet* g_template_fs;
@@ -38,8 +40,8 @@ extern TemplateFsFeatureSet* g_template_fs;
/// exposing functionality though a Python api.
class TemplateFsFeatureSet : public FeatureSetNativeComponent {
public:
- /// Instantiate and return our singleton instance.
- /// Basically a Python import statement.
+ /// Instantiate and return our singleton instance. Basically a Python
+ /// import statement.
static auto Import() -> TemplateFsFeatureSet*;
/// Called when our binary Python module first gets imported.
diff --git a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
index 53c1b2b6..e667ffd5 100644
--- a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
+++ b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
@@ -2,15 +2,12 @@
#include "ballistica/ui_v1/python/methods/python_methods_ui_v1.h"
-#include "ballistica/base/app/app.h"
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/assets/sound_asset.h"
#include "ballistica/base/input/input.h"
#include "ballistica/base/platform/base_platform.h"
#include "ballistica/base/python/base_python.h"
#include "ballistica/base/support/plus_soft.h"
-#include "ballistica/base/ui/console.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/ui_v1/python/class/python_class_ui_mesh.h"
#include "ballistica/ui_v1/python/class/python_class_ui_sound.h"
@@ -2727,7 +2724,7 @@ static auto PyOpenURL(PyObject* self, PyObject* args, PyObject* keywds)
&force_internal)) {
return nullptr;
}
- assert(g_base->app);
+ assert(g_base->app_adapter);
if (force_internal) {
g_base->ui->ShowURL(address);
} else {
diff --git a/src/ballistica/ui_v1/python/ui_v1_python.cc b/src/ballistica/ui_v1/python/ui_v1_python.cc
index f87ed5e3..415124a8 100644
--- a/src/ballistica/ui_v1/python/ui_v1_python.cc
+++ b/src/ballistica/ui_v1/python/ui_v1_python.cc
@@ -4,7 +4,6 @@
#include "ballistica/base/assets/assets.h"
#include "ballistica/base/audio/audio.h"
-#include "ballistica/base/input/device/input_device.h"
#include "ballistica/base/input/input.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/base/python/support/python_context_call.h"
diff --git a/src/ballistica/ui_v1/support/root_ui.cc b/src/ballistica/ui_v1/support/root_ui.cc
index e6952aba..55ebb382 100644
--- a/src/ballistica/ui_v1/support/root_ui.cc
+++ b/src/ballistica/ui_v1/support/root_ui.cc
@@ -7,7 +7,6 @@
#include "ballistica/base/input/device/keyboard_input.h"
#include "ballistica/base/input/device/touch_input.h"
#include "ballistica/base/input/input.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/ui_v1/python/ui_v1_python.h"
#include "ballistica/ui_v1/widget/container_widget.h"
diff --git a/src/ballistica/ui_v1/ui_v1.cc b/src/ballistica/ui_v1/ui_v1.cc
index c5d40412..f38e0aae 100644
--- a/src/ballistica/ui_v1/ui_v1.cc
+++ b/src/ballistica/ui_v1/ui_v1.cc
@@ -4,13 +4,10 @@
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/graphics/component/empty_component.h"
-#include "ballistica/base/graphics/graphics.h"
#include "ballistica/base/input/input.h"
#include "ballistica/base/support/app_config.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/ui_v1/python/ui_v1_python.h"
#include "ballistica/ui_v1/support/root_ui.h"
-#include "ballistica/ui_v1/widget/container_widget.h"
#include "ballistica/ui_v1/widget/root_widget.h"
#include "ballistica/ui_v1/widget/stack_widget.h"
#include "ballistica/ui_v1/widget/text_widget.h"
diff --git a/src/ballistica/ui_v1/ui_v1.h b/src/ballistica/ui_v1/ui_v1.h
index 30fc3edc..448fd3fb 100644
--- a/src/ballistica/ui_v1/ui_v1.h
+++ b/src/ballistica/ui_v1/ui_v1.h
@@ -23,7 +23,8 @@ struct WidgetMessage;
namespace ballistica::ui_v1 {
-// Predeclared types our feature-set provides.
+// Predeclare types we use throughout our FeatureSet so most headers can get
+// away with just including this header.
class UIV1FeatureSet;
class UIV1Python;
class Widget;
@@ -35,11 +36,11 @@ class RootWidget;
class StackWidget;
class TextWidget;
-// Our feature-set's globals.
-// Feature-sets should NEVER directly access globals in another feature-set's
-// namespace. All functionality we need from other feature-sets should be
-// imported into globals in our own namespace. Generally we do this when we
-// are initially imported (just as regular Python modules do).
+// Our feature-set's globals. Feature-sets should NEVER directly access
+// globals in another feature-set's namespace. All functionality we need
+// from other feature-sets should be imported into globals in our own
+// namespace. Generally we do this when we are initially imported (just as
+// regular Python modules do).
extern core::CoreFeatureSet* g_core;
extern base::BaseFeatureSet* g_base;
extern UIV1FeatureSet* g_ui_v1;
@@ -49,8 +50,8 @@ extern UIV1FeatureSet* g_ui_v1;
class UIV1FeatureSet : public FeatureSetNativeComponent,
public base::UIV1SoftInterface {
public:
- /// Instantiate our FeatureSet if needed and return the single
- /// instance of it. Basically a Python import statement.
+ /// Instantiate our FeatureSet if needed and return the single instance of
+ /// it. Basically a Python import statement.
static auto Import() -> UIV1FeatureSet*;
/// Called when our associated Python module is instantiated.
@@ -76,8 +77,8 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
void OnAppStart() override;
auto PartyWindowOpen() -> bool override;
- // Return the root widget containing all windows & dialogs
- // Whenever this contains children, the UI is considered to be in focus
+ // Return the root widget containing all windows & dialogs. Whenever this
+ // contains children, the UI is considered to be in focus
auto screen_root_widget() -> ui_v1::ContainerWidget* {
return screen_root_widget_.Get();
}
@@ -86,14 +87,13 @@ class UIV1FeatureSet : public FeatureSetNativeComponent,
return overlay_root_widget_.Get();
}
- // Return the absolute root widget; this includes persistent UI
- // bits such as the top/bottom bars
+ // Return the absolute root widget; this includes persistent UI bits such
+ // as the top/bottom bars
auto root_widget() -> ui_v1::RootWidget* { return root_widget_.Get(); }
void Reset() override;
- // Add a widget to a container.
- // If a parent is provided, the widget is added to it; otherwise it is added
- // to the root widget.
+ // Add a widget to a container. If a parent is provided, the widget is
+ // added to it; otherwise it is added to the root widget.
void AddWidget(Widget* w, ContainerWidget* to);
void DeleteWidget(Widget* widget);
diff --git a/src/ballistica/ui_v1/widget/button_widget.cc b/src/ballistica/ui_v1/widget/button_widget.cc
index ab89e000..e0401bb9 100644
--- a/src/ballistica/ui_v1/widget/button_widget.cc
+++ b/src/ballistica/ui_v1/widget/button_widget.cc
@@ -5,10 +5,8 @@
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
-#include "ballistica/base/input/device/input_device.h"
#include "ballistica/base/python/support/python_context_call.h"
#include "ballistica/base/support/app_timer.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/generic/utils.h"
namespace ballistica::ui_v1 {
diff --git a/src/ballistica/ui_v1/widget/check_box_widget.cc b/src/ballistica/ui_v1/widget/check_box_widget.cc
index 3366a1df..c8372679 100644
--- a/src/ballistica/ui_v1/widget/check_box_widget.cc
+++ b/src/ballistica/ui_v1/widget/check_box_widget.cc
@@ -6,7 +6,6 @@
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/python/support/python_context_call.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/python/python_sys.h"
namespace ballistica::ui_v1 {
diff --git a/src/ballistica/ui_v1/widget/column_widget.cc b/src/ballistica/ui_v1/widget/column_widget.cc
index 627fa4d2..5fb6663e 100644
--- a/src/ballistica/ui_v1/widget/column_widget.cc
+++ b/src/ballistica/ui_v1/widget/column_widget.cc
@@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/column_widget.h"
-#include "ballistica/base/ui/ui.h"
-
namespace ballistica::ui_v1 {
ColumnWidget::ColumnWidget() {
diff --git a/src/ballistica/ui_v1/widget/container_widget.cc b/src/ballistica/ui_v1/widget/container_widget.cc
index b9e7bef5..6046b8e9 100644
--- a/src/ballistica/ui_v1/widget/container_widget.cc
+++ b/src/ballistica/ui_v1/widget/container_widget.cc
@@ -7,7 +7,6 @@
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/logic/logic.h"
#include "ballistica/base/python/support/python_context_call.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/generic/utils.h"
#include "ballistica/shared/math/random.h"
diff --git a/src/ballistica/ui_v1/widget/h_scroll_widget.cc b/src/ballistica/ui_v1/widget/h_scroll_widget.cc
index 58394e55..f65d372c 100644
--- a/src/ballistica/ui_v1/widget/h_scroll_widget.cc
+++ b/src/ballistica/ui_v1/widget/h_scroll_widget.cc
@@ -5,7 +5,6 @@
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/support/app_timer.h"
-#include "ballistica/base/ui/ui.h"
namespace ballistica::ui_v1 {
diff --git a/src/ballistica/ui_v1/widget/root_widget.cc b/src/ballistica/ui_v1/widget/root_widget.cc
index 1fcbdd15..92722782 100644
--- a/src/ballistica/ui_v1/widget/root_widget.cc
+++ b/src/ballistica/ui_v1/widget/root_widget.cc
@@ -4,7 +4,6 @@
#include "ballistica/base/app_mode/app_mode.h"
#include "ballistica/base/graphics/renderer/renderer.h"
-#include "ballistica/base/ui/ui.h"
#include "ballistica/ui_v1/python/ui_v1_python.h"
#include "ballistica/ui_v1/widget/button_widget.h"
#include "ballistica/ui_v1/widget/stack_widget.h"
diff --git a/src/ballistica/ui_v1/widget/row_widget.cc b/src/ballistica/ui_v1/widget/row_widget.cc
index cc985438..7896de2a 100644
--- a/src/ballistica/ui_v1/widget/row_widget.cc
+++ b/src/ballistica/ui_v1/widget/row_widget.cc
@@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/row_widget.h"
-#include "ballistica/base/ui/ui.h"
-
namespace ballistica::ui_v1 {
RowWidget::RowWidget() {
diff --git a/src/ballistica/ui_v1/widget/scroll_widget.cc b/src/ballistica/ui_v1/widget/scroll_widget.cc
index c2079974..11876bb5 100644
--- a/src/ballistica/ui_v1/widget/scroll_widget.cc
+++ b/src/ballistica/ui_v1/widget/scroll_widget.cc
@@ -5,7 +5,6 @@
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
#include "ballistica/base/support/app_timer.h"
-#include "ballistica/base/ui/ui.h"
namespace ballistica::ui_v1 {
diff --git a/src/ballistica/ui_v1/widget/stack_widget.cc b/src/ballistica/ui_v1/widget/stack_widget.cc
index 8e27cdd0..5d5cc444 100644
--- a/src/ballistica/ui_v1/widget/stack_widget.cc
+++ b/src/ballistica/ui_v1/widget/stack_widget.cc
@@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/stack_widget.h"
-#include "ballistica/base/ui/ui.h"
-
namespace ballistica::ui_v1 {
StackWidget::StackWidget() {
diff --git a/src/ballistica/ui_v1/widget/text_widget.cc b/src/ballistica/ui_v1/widget/text_widget.cc
index 2421dbfe..0f7ab87e 100644
--- a/src/ballistica/ui_v1/widget/text_widget.cc
+++ b/src/ballistica/ui_v1/widget/text_widget.cc
@@ -2,7 +2,7 @@
#include "ballistica/ui_v1/widget/text_widget.h"
-#include "ballistica/base/app/app.h"
+#include "ballistica/base/app_adapter/app_adapter.h"
#include "ballistica/base/audio/audio.h"
#include "ballistica/base/graphics/component/empty_component.h"
#include "ballistica/base/graphics/component/simple_component.h"
diff --git a/tools/batools/pcommands.py b/tools/batools/pcommands.py
index c7f1e267..adc59626 100644
--- a/tools/batools/pcommands.py
+++ b/tools/batools/pcommands.py
@@ -11,7 +11,10 @@ from efrotools import pcommand
def prune_includes() -> None:
- """Check for unnecessary includes in C++ files."""
+ """Check for unnecessary includes in C++ files.
+
+ Pass --commit to actually modify files.
+ """
from batools.pruneincludes import Pruner
pcommand.disallow_in_batch()