cleaning up app-adapter

This commit is contained in:
Eric 2023-08-22 15:01:27 -07:00
parent bf94886aed
commit 26d5295b59
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
71 changed files with 642 additions and 734 deletions

88
.efrocachemap generated
View File

@ -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",

View File

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

View File

@ -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

View File

@ -189,14 +189,14 @@
<None Include="BallisticaKit.ico" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\ballistica\base\app\app.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_headless.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_headless.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_sdl.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_sdl.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_vr.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_vr.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.h" />
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_mode\app_mode.h" />
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode_empty.cc" />

View File

@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\src\ballistica\base\app\app.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_headless.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_headless.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_sdl.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_sdl.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_vr.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_vr.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode.cc">
<Filter>ballistica\base\app_mode</Filter>
@ -1865,7 +1865,7 @@
<ItemGroup>
<Filter Include="ballistica" />
<Filter Include="ballistica\base" />
<Filter Include="ballistica\base\app" />
<Filter Include="ballistica\base\app_adapter" />
<Filter Include="ballistica\base\app_mode" />
<Filter Include="ballistica\base\assets" />
<Filter Include="ballistica\base\audio" />

View File

@ -184,14 +184,14 @@
<Library Include="..\..\build\prefab\lib\windows\$(Configuration)_$(Platform)\$(MSBuildProjectName)Plus.lib" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\ballistica\base\app\app.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_headless.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_headless.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_sdl.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_sdl.h" />
<ClCompile Include="..\..\src\ballistica\base\app\app_vr.cc" />
<ClInclude Include="..\..\src\ballistica\base\app\app_vr.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.h" />
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.h" />
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode.cc" />
<ClInclude Include="..\..\src\ballistica\base\app_mode\app_mode.h" />
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode_empty.cc" />

View File

@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\src\ballistica\base\app\app.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_headless.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_headless.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_headless.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_sdl.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_sdl.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_sdl.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app\app_vr.cc">
<Filter>ballistica\base\app</Filter>
<ClCompile Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.cc">
<Filter>ballistica\base\app_adapter</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ballistica\base\app\app_vr.h">
<Filter>ballistica\base\app</Filter>
<ClInclude Include="..\..\src\ballistica\base\app_adapter\app_adapter_vr.h">
<Filter>ballistica\base\app_adapter</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ballistica\base\app_mode\app_mode.cc">
<Filter>ballistica\base\app_mode</Filter>
@ -1865,7 +1865,7 @@
<ItemGroup>
<Filter Include="ballistica" />
<Filter Include="ballistica\base" />
<Filter Include="ballistica\base\app" />
<Filter Include="ballistica\base\app_adapter" />
<Filter Include="ballistica\base\app_mode" />
<Filter Include="ballistica\base\assets" />
<Filter Include="ballistica\base\audio" />

View File

@ -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'

View File

@ -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 <string>
#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_

View File

@ -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_

View File

@ -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

View File

@ -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 <string>
#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_

View File

@ -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();
}));
}

View File

@ -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_

View File

@ -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<AppSDL*>(g_base->app);
auto app = static_cast_check_type<AppAdapterSDL*>(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

View File

@ -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 <vector>
#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<AppSDL*>(g_base->app)
== static_cast<AppSDL*>(g_base->app));
return static_cast<AppSDL*>(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<AppAdapterSDL*>(g_base->app_adapter)
== static_cast<AppAdapterSDL*>(g_base->app_adapter));
return static_cast<AppAdapterSDL*>(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_

View File

@ -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;

View File

@ -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<AppVR*>(g_base->app)
== static_cast<AppVR*>(g_base->app));
return static_cast<AppVR*>(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<AppAdapterVR*>(g_base->app_adapter)
== static_cast<AppAdapterVR*>(g_base->app_adapter));
return static_cast<AppAdapterVR*>(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_

View File

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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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<float>(win_size_x), static_cast<float>(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.

View File

@ -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"

View File

@ -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<AppSDL*>(g_base->app)) {
if (auto app = dynamic_cast<AppAdapterSDL*>(g_base->app_adapter)) {
v_sync_ = sync;
auto_vsync_ = auto_sync;
if (gl_context_) {

View File

@ -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); });

View File

@ -22,7 +22,7 @@ namespace ballistica::base {
Input::Input() = default;
template <typename F>
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) {

View File

@ -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;
}

View File

@ -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?

View File

@ -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"

View File

@ -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"

View File

@ -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* {

View File

@ -3,8 +3,6 @@
#ifndef BALLISTICA_BASE_PLATFORM_BASE_PLATFORM_H_
#define BALLISTICA_BASE_PLATFORM_BASE_PLATFORM_H_
#include <list>
#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 -----------------------------------------------------

View File

@ -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"

View File

@ -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;
}

View File

@ -4,7 +4,6 @@
#include <cstring>
#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);

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -54,7 +54,8 @@ auto CoreFeatureSet::Import(const CoreConfig* config) -> CoreFeatureSet* {
// between monolithic and modular.
std::vector<std::string> argbuffer;
std::vector<char*> argv = CorePython::FetchPythonArgs(&argbuffer);
DoImport(CoreConfig::ForArgsAndEnvVars(argv.size(), argv.data()));
DoImport(CoreConfig::ForArgsAndEnvVars(static_cast<int>(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

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -32,7 +32,8 @@ const int kGameStepMilliseconds = 8;
const float kGameStepSeconds =
(static_cast<float>(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;

View File

@ -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 {

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -5,7 +5,6 @@
#include <string>
#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"

View File

@ -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"

View File

@ -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.

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/column_widget.h"
#include "ballistica/base/ui/ui.h"
namespace ballistica::ui_v1 {
ColumnWidget::ColumnWidget() {

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/row_widget.h"
#include "ballistica/base/ui/ui.h"
namespace ballistica::ui_v1 {
RowWidget::RowWidget() {

View File

@ -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 {

View File

@ -2,8 +2,6 @@
#include "ballistica/ui_v1/widget/stack_widget.h"
#include "ballistica/base/ui/ui.h"
namespace ballistica::ui_v1 {
StackWidget::StackWidget() {

View File

@ -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"

View File

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