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()