mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-06 07:23:37 +08:00
work on app-modes and app-intents
This commit is contained in:
parent
4e21714961
commit
28da551aa2
@ -4072,26 +4072,26 @@
|
|||||||
"build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/c5/09/4f10b8a21ba87aa5509cff7a164b",
|
"build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/c5/09/4f10b8a21ba87aa5509cff7a164b",
|
||||||
"build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/ff/0a/a354984f9c074dab0676ac7e4877",
|
"build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/ff/0a/a354984f9c074dab0676ac7e4877",
|
||||||
"build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/2a/1c/9ee5db6d1bceca7fa6638fb8abde",
|
"build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/2a/1c/9ee5db6d1bceca7fa6638fb8abde",
|
||||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/7b/fc/40202144638c394e88af0424ac38",
|
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/08/e3/a0b9223475c7706681fad7968ba7",
|
||||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/bd/fb/9a2813b5a23b727b1b246d5b1a31",
|
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/6d/ef/b6d1a6b9754d3036f71ad3fa77e2",
|
||||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/6f/99/9e5c25105d2bc8fd1db0402cdb0f",
|
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2b/b1/6f30bc9be42939f9399d4a3f2b3a",
|
||||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/8b/4e/f6496d2ccd7a869e4e9d2eb57ee4",
|
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/0e/ef/1ce03a67174a21bb153ea7e8e27b",
|
||||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/f6/ec/dab1171b1c99587a80e959dddaa5",
|
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/d0/26/46d5ff486b95aedaa3caf3c299c9",
|
||||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/2f/23/0d5dd4dd3dd190a3f81eca6d11f0",
|
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/10/ea/b9aa9951192cbc45cccb4c3c2289",
|
||||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/f3/ec/b238f5118def4ecac3ba4363f389",
|
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e0/a0/32c52b4e83da434e22544bdda893",
|
||||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b2/d2/307b223ce8182e3c14a982dad7d4",
|
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/0b/09/2986300ce8c70c4e301da76a0533",
|
||||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/08/67/672c0b7edb83bd06f3f08d25c1d1",
|
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/b1/79/ba61f157a98f4ceab818d99edab9",
|
||||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/5e/34/7189db32e52d599755bf59587671",
|
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/09/78/0a5975081c617f7a52c6ddd3d7c0",
|
||||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ce/44/dec692802d8023cd48f5f29fa40d",
|
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/36/91/561ed25a53dd05a321418ef95527",
|
||||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/8d/52/084e0817f587f035017bc2595a8d",
|
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/8d/27/ee747a3e85a28e124c21ac2b380d",
|
||||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/46/33/1975fe658fc9ffc96b95c0071ecd",
|
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/a7/b8/ad830a02ee58f2e87466f011fb27",
|
||||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/66/ea/4e901a9ad2ad965bdc773ee3b127",
|
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/ca/71/6fd4afebc57e78d5986a2f657a3f",
|
||||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2f/54/565f3150df759bffea9dcad21685",
|
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/56/16/efa353be8adca6c233db12102463",
|
||||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/52/a5/594f6db4b4f0d8d9937bb67d80f6",
|
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/85/98/0aa74afa4bfa7f12b4bb54fe76a3",
|
||||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/0f/86/5228cc1d4a8d2317585028e115f3",
|
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/e6/bb/308f33d3c4b549b8b701a6e94db1",
|
||||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/73/b0/83918095162a68c12bffdb7a4d97",
|
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/68/c5/ad76162d865a7a14f2f2677300d1",
|
||||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/12/55/5d5b5a467a1c2ec10c2551465682",
|
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/c6/39/21bdc2e4e59855558bbc7d606f28",
|
||||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/48/95/a35e7407f5f813cea477dd75130f",
|
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/f9/eb/e2be79806312a8615a1e6da93078",
|
||||||
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/f4/e7/32cfbd534ac61e626f6c6fbe2b01",
|
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/f4/e7/32cfbd534ac61e626f6c6fbe2b01",
|
||||||
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/f3/f8/52577356f2ff5229ed4e5a6764cf",
|
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/f3/f8/52577356f2ff5229ed4e5a6764cf",
|
||||||
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/60/2b/35acb337afc2d997ffc94d2da757",
|
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/60/2b/35acb337afc2d997ffc94d2da757",
|
||||||
@ -4108,14 +4108,14 @@
|
|||||||
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/30/4a/aa281e0eb46722098ec29d7da4f8",
|
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/30/4a/aa281e0eb46722098ec29d7da4f8",
|
||||||
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/0b/e4/a9d278c1bc9a5d731f865ac91a0b",
|
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/0b/e4/a9d278c1bc9a5d731f865ac91a0b",
|
||||||
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/92/f7/8898478ab4ef0a342c727dd64195",
|
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/92/f7/8898478ab4ef0a342c727dd64195",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/df/9f/960a5370e02cae685ae3452066f9",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/14/3f/8bffa39ee2e862bfd61886f8dd20",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/7d/f7/ba5e3f57b5c6fe96542f61ae21f1",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/de/69/ff2d73feab522f0be693900c534b",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/34/b3/83428e86252522a10d0c097fc3eb",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/2a/ac/8e4a2b322079d57a65cf5ec686eb",
|
||||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/1d/31/12a6e62fc12477b4ed1eb3735b08",
|
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/9b/d8/f5dbc2b76e5d6992e6e0f957699d",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/65/ca/8bd967cebd1836e03117c2b10f5d",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/68/f9/0e55e33d9782d596d65770e943d8",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/8c/41/4689d7ca391e92fed73b81e5064c",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/b4/49/32ebdaa15a795c84e90c3d16fdee",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/7b/a9/f53d5f009e6cc89a265c076bbb51",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/e9/3c/b86de4797400df2a7bbba4e957f7",
|
||||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/d1/ed/acae7564f9d534d7f78a3a9373ee",
|
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/93/88/176702f3743aa143dcd2ee651c4a",
|
||||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa",
|
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa",
|
||||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1",
|
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1",
|
||||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/b4/3d/e352190a0e5673d101c0f3ee3ad2",
|
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/b4/3d/e352190a0e5673d101c0f3ee3ad2",
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
### 1.7.20 (build 21022, api 8, 2023-05-24)
|
### 1.7.20 (build 21023, api 8, 2023-05-26)
|
||||||
|
|
||||||
- This seems like a good time for a `refactoring` release in anticipation of
|
- This seems like a good time for a `refactoring` release in anticipation of
|
||||||
changes coming in 1.8. Basically this means that a lot of things will be
|
changes coming in 1.8. Basically this means that a lot of things will be
|
||||||
|
|||||||
@ -408,6 +408,7 @@ add_executable(ballisticakit
|
|||||||
${BA_SRC_ROOT}/ballistica/base/python/support/python_context_call.h
|
${BA_SRC_ROOT}/ballistica/base/python/support/python_context_call.h
|
||||||
${BA_SRC_ROOT}/ballistica/base/python/support/python_context_call_runnable.h
|
${BA_SRC_ROOT}/ballistica/base/python/support/python_context_call_runnable.h
|
||||||
${BA_SRC_ROOT}/ballistica/base/support/app_timer.h
|
${BA_SRC_ROOT}/ballistica/base/support/app_timer.h
|
||||||
|
${BA_SRC_ROOT}/ballistica/base/support/classic_soft.h
|
||||||
${BA_SRC_ROOT}/ballistica/base/support/context.cc
|
${BA_SRC_ROOT}/ballistica/base/support/context.cc
|
||||||
${BA_SRC_ROOT}/ballistica/base/support/context.h
|
${BA_SRC_ROOT}/ballistica/base/support/context.h
|
||||||
${BA_SRC_ROOT}/ballistica/base/support/huffman.cc
|
${BA_SRC_ROOT}/ballistica/base/support/huffman.cc
|
||||||
|
|||||||
@ -399,6 +399,7 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call.h" />
|
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call.h" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call_runnable.h" />
|
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call_runnable.h" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h" />
|
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h" />
|
||||||
|
<ClInclude Include="..\..\src\ballistica\base\support\classic_soft.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\context.cc" />
|
<ClCompile Include="..\..\src\ballistica\base\support\context.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\support\context.h" />
|
<ClInclude Include="..\..\src\ballistica\base\support\context.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\huffman.cc" />
|
<ClCompile Include="..\..\src\ballistica\base\support\huffman.cc" />
|
||||||
|
|||||||
@ -631,6 +631,9 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h">
|
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h">
|
||||||
<Filter>ballistica\base\support</Filter>
|
<Filter>ballistica\base\support</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ballistica\base\support\classic_soft.h">
|
||||||
|
<Filter>ballistica\base\support</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\context.cc">
|
<ClCompile Include="..\..\src\ballistica\base\support\context.cc">
|
||||||
<Filter>ballistica\base\support</Filter>
|
<Filter>ballistica\base\support</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -394,6 +394,7 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call.h" />
|
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call.h" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call_runnable.h" />
|
<ClInclude Include="..\..\src\ballistica\base\python\support\python_context_call_runnable.h" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h" />
|
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h" />
|
||||||
|
<ClInclude Include="..\..\src\ballistica\base\support\classic_soft.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\context.cc" />
|
<ClCompile Include="..\..\src\ballistica\base\support\context.cc" />
|
||||||
<ClInclude Include="..\..\src\ballistica\base\support\context.h" />
|
<ClInclude Include="..\..\src\ballistica\base\support\context.h" />
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\huffman.cc" />
|
<ClCompile Include="..\..\src\ballistica\base\support\huffman.cc" />
|
||||||
|
|||||||
@ -631,6 +631,9 @@
|
|||||||
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h">
|
<ClInclude Include="..\..\src\ballistica\base\support\app_timer.h">
|
||||||
<Filter>ballistica\base\support</Filter>
|
<Filter>ballistica\base\support</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ballistica\base\support\classic_soft.h">
|
||||||
|
<Filter>ballistica\base\support</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ballistica\base\support\context.cc">
|
<ClCompile Include="..\..\src\ballistica\base\support\context.cc">
|
||||||
<Filter>ballistica\base\support</Filter>
|
<Filter>ballistica\base\support</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
"ba_data/python/babase/__pycache__/_app.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_app.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_appcomponent.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_appcomponent.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_appconfig.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_appconfig.cpython-311.opt-1.pyc",
|
||||||
|
"ba_data/python/babase/__pycache__/_appintent.cpython-311.opt-1.pyc",
|
||||||
|
"ba_data/python/babase/__pycache__/_appmode.cpython-311.opt-1.pyc",
|
||||||
|
"ba_data/python/babase/__pycache__/_appmodeselector.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
|
"ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc",
|
||||||
@ -27,6 +30,9 @@
|
|||||||
"ba_data/python/babase/_app.py",
|
"ba_data/python/babase/_app.py",
|
||||||
"ba_data/python/babase/_appcomponent.py",
|
"ba_data/python/babase/_appcomponent.py",
|
||||||
"ba_data/python/babase/_appconfig.py",
|
"ba_data/python/babase/_appconfig.py",
|
||||||
|
"ba_data/python/babase/_appintent.py",
|
||||||
|
"ba_data/python/babase/_appmode.py",
|
||||||
|
"ba_data/python/babase/_appmodeselector.py",
|
||||||
"ba_data/python/babase/_apputils.py",
|
"ba_data/python/babase/_apputils.py",
|
||||||
"ba_data/python/babase/_assetmanager.py",
|
"ba_data/python/babase/_assetmanager.py",
|
||||||
"ba_data/python/babase/_asyncio.py",
|
"ba_data/python/babase/_asyncio.py",
|
||||||
@ -122,6 +128,7 @@
|
|||||||
"ba_data/python/bascenev1/__pycache__/_activity.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_activity.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/bascenev1/__pycache__/_activitytypes.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_activitytypes.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/bascenev1/__pycache__/_actor.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_actor.cpython-311.opt-1.pyc",
|
||||||
|
"ba_data/python/bascenev1/__pycache__/_appmode.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/bascenev1/__pycache__/_collision.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_collision.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/bascenev1/__pycache__/_coopgame.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_coopgame.cpython-311.opt-1.pyc",
|
||||||
"ba_data/python/bascenev1/__pycache__/_coopsession.cpython-311.opt-1.pyc",
|
"ba_data/python/bascenev1/__pycache__/_coopsession.cpython-311.opt-1.pyc",
|
||||||
@ -152,6 +159,7 @@
|
|||||||
"ba_data/python/bascenev1/_activity.py",
|
"ba_data/python/bascenev1/_activity.py",
|
||||||
"ba_data/python/bascenev1/_activitytypes.py",
|
"ba_data/python/bascenev1/_activitytypes.py",
|
||||||
"ba_data/python/bascenev1/_actor.py",
|
"ba_data/python/bascenev1/_actor.py",
|
||||||
|
"ba_data/python/bascenev1/_appmode.py",
|
||||||
"ba_data/python/bascenev1/_collision.py",
|
"ba_data/python/bascenev1/_collision.py",
|
||||||
"ba_data/python/bascenev1/_coopgame.py",
|
"ba_data/python/bascenev1/_coopgame.py",
|
||||||
"ba_data/python/bascenev1/_coopsession.py",
|
"ba_data/python/bascenev1/_coopsession.py",
|
||||||
|
|||||||
@ -139,6 +139,9 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/babase/_app.py \
|
$(BUILD_DIR)/ba_data/python/babase/_app.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_appcomponent.py \
|
$(BUILD_DIR)/ba_data/python/babase/_appcomponent.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_appconfig.py \
|
$(BUILD_DIR)/ba_data/python/babase/_appconfig.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/_appintent.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/_appmode.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/_appmodeselector.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_apputils.py \
|
$(BUILD_DIR)/ba_data/python/babase/_apputils.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
|
$(BUILD_DIR)/ba_data/python/babase/_assetmanager.py \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
|
$(BUILD_DIR)/ba_data/python/babase/_asyncio.py \
|
||||||
@ -188,6 +191,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_activity.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_activity.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_activitytypes.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_activitytypes.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_actor.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_actor.py \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bascenev1/_appmode.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_collision.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_collision.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_coopgame.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_coopgame.py \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/_coopsession.py \
|
$(BUILD_DIR)/ba_data/python/bascenev1/_coopsession.py \
|
||||||
@ -405,6 +409,9 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_app.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_app.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appcomponent.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appcomponent.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appconfig.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appconfig.cpython-311.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appintent.cpython-311.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appmode.cpython-311.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_appmodeselector.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_apputils.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_assetmanager.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_asyncio.cpython-311.opt-1.pyc \
|
||||||
@ -454,6 +461,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
|||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_activity.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_activity.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_activitytypes.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_activitytypes.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_actor.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_actor.cpython-311.opt-1.pyc \
|
||||||
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_appmode.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_collision.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_collision.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_coopgame.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_coopgame.cpython-311.opt-1.pyc \
|
||||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_coopsession.cpython-311.opt-1.pyc \
|
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_coopsession.cpython-311.opt-1.pyc \
|
||||||
|
|||||||
@ -33,6 +33,8 @@ from _babase import (
|
|||||||
in_logic_thread,
|
in_logic_thread,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from babase._appintent import AppIntent, AppIntentDefault, AppIntentExec
|
||||||
|
from babase._appmode import AppMode
|
||||||
from babase._accountv2 import AccountV2Handle
|
from babase._accountv2 import AccountV2Handle
|
||||||
from babase._plugin import PotentialPlugin, Plugin, PluginSubsystem
|
from babase._plugin import PotentialPlugin, Plugin, PluginSubsystem
|
||||||
from babase._app import App
|
from babase._app import App
|
||||||
@ -155,6 +157,10 @@ __all__ = [
|
|||||||
'displaytimer',
|
'displaytimer',
|
||||||
'displaytime',
|
'displaytime',
|
||||||
'DisplayTimer',
|
'DisplayTimer',
|
||||||
|
'AppIntent',
|
||||||
|
'AppIntentDefault',
|
||||||
|
'AppIntentExec',
|
||||||
|
'AppMode',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ from typing import TYPE_CHECKING
|
|||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
|
||||||
|
from efro.call import tpartial
|
||||||
import _babase
|
import _babase
|
||||||
from babase._language import LanguageSubsystem
|
from babase._language import LanguageSubsystem
|
||||||
from babase._plugin import PluginSubsystem
|
from babase._plugin import PluginSubsystem
|
||||||
@ -16,22 +17,28 @@ from babase._meta import MetadataSubsystem
|
|||||||
from babase._net import NetworkSubsystem
|
from babase._net import NetworkSubsystem
|
||||||
from babase._workspace import WorkspaceSubsystem
|
from babase._workspace import WorkspaceSubsystem
|
||||||
from babase._appcomponent import AppComponentSubsystem
|
from babase._appcomponent import AppComponentSubsystem
|
||||||
|
from babase._appmodeselector import AppModeSelector
|
||||||
|
from babase._appintent import AppIntentDefault, AppIntentExec
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from typing import Any, Callable
|
||||||
|
from concurrent.futures import Future
|
||||||
|
|
||||||
from efro.log import LogHandler
|
from efro.log import LogHandler
|
||||||
import babase
|
import babase
|
||||||
from babase._cloud import CloudSubsystem
|
from babase._cloud import CloudSubsystem
|
||||||
from babase._accountv2 import AccountV2Subsystem
|
from babase._accountv2 import AccountV2Subsystem
|
||||||
from babase._apputils import AppHealthMonitor
|
from babase._apputils import AppHealthMonitor
|
||||||
|
from babase._appintent import AppIntent
|
||||||
|
from babase._appmode import AppMode
|
||||||
|
|
||||||
|
# WOULD-AUTOGEN-BEGIN
|
||||||
|
|
||||||
# Would autogen this begin
|
|
||||||
from baclassic import ClassicSubsystem
|
from baclassic import ClassicSubsystem
|
||||||
from baplus import PlusSubsystem
|
from baplus import PlusSubsystem
|
||||||
|
|
||||||
# Would autogen this end
|
# WOULD-AUTOGEN-END
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
@ -275,7 +282,15 @@ class App:
|
|||||||
self.lang = LanguageSubsystem()
|
self.lang = LanguageSubsystem()
|
||||||
self.net = NetworkSubsystem()
|
self.net = NetworkSubsystem()
|
||||||
self.workspaces = WorkspaceSubsystem()
|
self.workspaces = WorkspaceSubsystem()
|
||||||
# self._classic: ClassicSubsystem | None = None
|
self._pending_intent: AppIntent | None = None
|
||||||
|
self._intent: AppIntent | None = None
|
||||||
|
self._mode: AppMode | None = None
|
||||||
|
|
||||||
|
# Controls which app-modes we use for handling given app-intents.
|
||||||
|
# Plugins can override this to change high level app behavior and
|
||||||
|
# spinoff projects can change the default implementation for the
|
||||||
|
# same effect.
|
||||||
|
self.mode_selector: AppModeSelector | None = None
|
||||||
|
|
||||||
self._asyncio_timer: babase.AppTimer | None = None
|
self._asyncio_timer: babase.AppTimer | None = None
|
||||||
|
|
||||||
@ -298,11 +313,28 @@ class App:
|
|||||||
# if classic_subsystem_type is not None:
|
# if classic_subsystem_type is not None:
|
||||||
# self._classic = classic_subsystem_type()
|
# self._classic = classic_subsystem_type()
|
||||||
|
|
||||||
# Would autogen this begin
|
def _threadpool_no_wait_done(self, fut: Future) -> None:
|
||||||
|
try:
|
||||||
|
fut.result()
|
||||||
|
except Exception:
|
||||||
|
logging.exception(
|
||||||
|
'Error in work submitted via threadpool_submit_no_wait()'
|
||||||
|
)
|
||||||
|
|
||||||
|
def threadpool_submit_no_wait(self, call: Callable[[], Any]) -> None:
|
||||||
|
"""Submit work to our threadpool and log any errors.
|
||||||
|
|
||||||
|
Use this when you want to run something asynchronously but don't
|
||||||
|
intend to call result() on it to handle errors/etc.
|
||||||
|
"""
|
||||||
|
fut = self.threadpool.submit(call)
|
||||||
|
fut.add_done_callback(self._threadpool_no_wait_done)
|
||||||
|
|
||||||
|
# WOULD-AUTOGEN-BEGIN
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def classic(self) -> ClassicSubsystem | None:
|
def classic(self) -> ClassicSubsystem | None:
|
||||||
"""Our classic subsystem."""
|
"""Our classic subsystem (if available)."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from baclassic import ClassicSubsystem
|
from baclassic import ClassicSubsystem
|
||||||
@ -316,7 +348,7 @@ class App:
|
|||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def plus(self) -> PlusSubsystem | None:
|
def plus(self) -> PlusSubsystem | None:
|
||||||
"""Our plus subsystem."""
|
"""Our plus subsystem (if available)."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from baplus import PlusSubsystem
|
from baplus import PlusSubsystem
|
||||||
@ -328,7 +360,96 @@ class App:
|
|||||||
logging.exception('Error importing baplus')
|
logging.exception('Error importing baplus')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Would autogen this begin
|
# WOULD-AUTOGEN-END
|
||||||
|
|
||||||
|
def set_intent(self, intent: AppIntent) -> None:
|
||||||
|
"""Set the intent for the app.
|
||||||
|
|
||||||
|
Intent defines what the app is trying to do at a given time.
|
||||||
|
This call is asynchronous; the intent switch will happen in the
|
||||||
|
logic thread in the near future. If set_intent is
|
||||||
|
called repeatedly before the change takes place, the last intent
|
||||||
|
set will be used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Mark this one as pending. We do this synchronously so that the
|
||||||
|
# last one marked actually takes effect if there is overlap
|
||||||
|
# (doing this in the bg thread could result in race conditions).
|
||||||
|
self._pending_intent = intent
|
||||||
|
|
||||||
|
# Do the actual work of calcing our app-mode/etc. in a bg thread
|
||||||
|
# since it may block for a moment to load modules/etc.
|
||||||
|
self.threadpool_submit_no_wait(tpartial(self._set_intent, intent))
|
||||||
|
|
||||||
|
def _set_intent(self, intent: AppIntent) -> None:
|
||||||
|
# This should be running in a bg thread.
|
||||||
|
assert not _babase.in_logic_thread()
|
||||||
|
try:
|
||||||
|
# Ask the selector what app-mode to use for this intent.
|
||||||
|
if self.mode_selector is None:
|
||||||
|
raise RuntimeError('No AppModeSelector set.')
|
||||||
|
modetype = self.mode_selector.app_mode_for_intent(intent)
|
||||||
|
|
||||||
|
# Make sure the app-mode they return *actually* supports the
|
||||||
|
# intent.
|
||||||
|
if not modetype.supports_intent(intent):
|
||||||
|
raise RuntimeError(
|
||||||
|
f'Intent {intent} is not supported by AppMode class'
|
||||||
|
f' {modetype}'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Kick back to the logic thread to apply.
|
||||||
|
mode = modetype()
|
||||||
|
_babase.pushcall(
|
||||||
|
tpartial(self._apply_intent, intent, mode),
|
||||||
|
from_other_thread=True,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
logging.exception('Error setting app intent to %s.', intent)
|
||||||
|
_babase.pushcall(
|
||||||
|
tpartial(self._apply_intent_error, intent),
|
||||||
|
from_other_thread=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _apply_intent(self, intent: AppIntent, mode: AppMode) -> None:
|
||||||
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
|
# ONLY apply this intent if it is still the most recent one
|
||||||
|
# submitted.
|
||||||
|
if intent is not self._pending_intent:
|
||||||
|
return
|
||||||
|
|
||||||
|
# If the app-mode for this intent is different than the active
|
||||||
|
# one, switch.
|
||||||
|
# pylint: disable=unidiomatic-typecheck
|
||||||
|
if type(mode) is not type(self._mode):
|
||||||
|
if self._mode is not None:
|
||||||
|
try:
|
||||||
|
self._mode.on_deactivate()
|
||||||
|
except Exception:
|
||||||
|
logging.exception(
|
||||||
|
'Error deactivating app-mode %s.', self._mode
|
||||||
|
)
|
||||||
|
self._mode = mode
|
||||||
|
try:
|
||||||
|
mode.on_activate()
|
||||||
|
except Exception:
|
||||||
|
# Hmm; what should we do in this case?...
|
||||||
|
logging.exception('Error activating app-mode %s.', mode)
|
||||||
|
|
||||||
|
try:
|
||||||
|
mode.handle_intent(intent)
|
||||||
|
except Exception:
|
||||||
|
logging.exception(
|
||||||
|
'Error handling intent %s in app-mode %s.', intent, mode
|
||||||
|
)
|
||||||
|
|
||||||
|
def _apply_intent_error(self, intent: AppIntent) -> None:
|
||||||
|
from babase._language import Lstr
|
||||||
|
|
||||||
|
del intent # Unused.
|
||||||
|
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
|
||||||
|
_babase.getsimplesound('error').play()
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run the app to completion.
|
"""Run the app to completion.
|
||||||
@ -381,12 +502,40 @@ class App:
|
|||||||
|
|
||||||
def on_app_loading(self) -> None:
|
def on_app_loading(self) -> None:
|
||||||
"""Called when initially entering the loading state."""
|
"""Called when initially entering the loading state."""
|
||||||
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
|
class DefaultAppModeSelector(AppModeSelector):
|
||||||
|
"""Decides which app modes to use to handle intents."""
|
||||||
|
|
||||||
|
def app_mode_for_intent(self, intent: AppIntent) -> type[AppMode]:
|
||||||
|
# WOULD-AUTOGEN-BEGIN
|
||||||
|
|
||||||
|
import bascenev1
|
||||||
|
|
||||||
|
return bascenev1.SceneV1AppMode
|
||||||
|
|
||||||
|
# WOULD-AUTOGEN-END
|
||||||
|
|
||||||
def on_app_running(self) -> None:
|
def on_app_running(self) -> None:
|
||||||
"""Called when initially entering the running state."""
|
"""Called when initially entering the running state."""
|
||||||
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
|
# Set a default app-mode-selector. Plugins can then override
|
||||||
|
# this if they want.
|
||||||
|
self.mode_selector = self.DefaultAppModeSelector()
|
||||||
|
|
||||||
self.plugins.on_app_running()
|
self.plugins.on_app_running()
|
||||||
|
|
||||||
|
# If 'exec' code was provided to the app, always kick that off
|
||||||
|
# here.
|
||||||
|
exec_cmd = _babase.exec_arg()
|
||||||
|
if exec_cmd is not None:
|
||||||
|
self.set_intent(AppIntentExec(exec_cmd))
|
||||||
|
elif self._pending_intent is None:
|
||||||
|
# Otherwise tell the app to do its default thing *only* if a
|
||||||
|
# plugin hasn't already told it to do something.
|
||||||
|
self.set_intent(AppIntentDefault())
|
||||||
|
|
||||||
def on_app_bootstrapping_complete(self) -> None:
|
def on_app_bootstrapping_complete(self) -> None:
|
||||||
"""Called by the C++ layer once its ready to rock."""
|
"""Called by the C++ layer once its ready to rock."""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|||||||
@ -19,19 +19,21 @@ class AppComponentSubsystem:
|
|||||||
Category: **App Classes**
|
Category: **App Classes**
|
||||||
|
|
||||||
This subsystem acts as a registry for classes providing particular
|
This subsystem acts as a registry for classes providing particular
|
||||||
functionality for the app, and allows plugins or other custom code to
|
functionality for the app, and allows plugins or other custom code
|
||||||
easily override said functionality.
|
to easily override said functionality.
|
||||||
|
|
||||||
Use babase.app.components to get the single shared instance of this class.
|
Access the single shared instance of this class at
|
||||||
|
babase.app.components.
|
||||||
|
|
||||||
The general idea with this setup is that a base-class is defined to
|
The general idea with this setup is that a base-class Foo is defined
|
||||||
provide some functionality and then anyone wanting that functionality
|
to provide some functionality and then anyone wanting that
|
||||||
uses the getclass() method with that base class to return the current
|
functionality calls getclass(Foo) to return the current registered
|
||||||
registered implementation. The user should not know or care whether
|
implementation. The user should not know or care whether they are
|
||||||
they are getting the base class itself or some other implementation.
|
getting Foo itself or some subclass of it.
|
||||||
|
|
||||||
Change-callbacks can also be requested for base classes which will
|
Change-callbacks can also be requested for base classes which will
|
||||||
fire in a deferred manner when particular base-classes are overridden.
|
fire in a deferred manner when particular base-classes are
|
||||||
|
overridden.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -45,8 +47,9 @@ class AppComponentSubsystem:
|
|||||||
|
|
||||||
The provided implementation class must be a subclass of baseclass.
|
The provided implementation class must be a subclass of baseclass.
|
||||||
"""
|
"""
|
||||||
# Currently limiting this to logic-thread use; can revisit if needed
|
# Currently limiting this to logic-thread use; can revisit if
|
||||||
# (would need to guard access to our implementations dict).
|
# needed (would need to guard access to our implementations
|
||||||
|
# dict).
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
if not issubclass(implementation, baseclass):
|
if not issubclass(implementation, baseclass):
|
||||||
@ -58,16 +61,17 @@ class AppComponentSubsystem:
|
|||||||
self._implementations[baseclass] = implementation
|
self._implementations[baseclass] = implementation
|
||||||
|
|
||||||
# If we're the first thing getting dirtied, set up a callback to
|
# If we're the first thing getting dirtied, set up a callback to
|
||||||
# clean everything. And add ourself to the dirty list regardless.
|
# clean everything. And add ourself to the dirty list
|
||||||
|
# regardless.
|
||||||
if not self._dirty_base_classes:
|
if not self._dirty_base_classes:
|
||||||
_babase.pushcall(self._run_change_callbacks)
|
_babase.pushcall(self._run_change_callbacks)
|
||||||
self._dirty_base_classes.add(baseclass)
|
self._dirty_base_classes.add(baseclass)
|
||||||
|
|
||||||
def getclass(self, baseclass: T) -> T:
|
def getclass(self, baseclass: T) -> T:
|
||||||
"""Given a base-class, return the currently set implementation class.
|
"""Given a base-class, return the current implementation class.
|
||||||
|
|
||||||
If no custom implementation has been set, the provided base-class
|
If no custom implementation has been set, the provided
|
||||||
is returned.
|
base-class is returned.
|
||||||
"""
|
"""
|
||||||
assert _babase.in_logic_thread()
|
assert _babase.in_logic_thread()
|
||||||
|
|
||||||
@ -77,7 +81,7 @@ class AppComponentSubsystem:
|
|||||||
def register_change_callback(
|
def register_change_callback(
|
||||||
self, baseclass: T, callback: Callable[[T], None]
|
self, baseclass: T, callback: Callable[[T], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a callback to fire when a class implementation changes.
|
"""Register a callback to fire on class implementation changes.
|
||||||
|
|
||||||
The callback will be scheduled to run in the logic thread event
|
The callback will be scheduled to run in the logic thread event
|
||||||
loop. Note that any further setclass calls before the callback
|
loop. Note that any further setclass calls before the callback
|
||||||
|
|||||||
27
src/assets/ba_data/python/babase/_appintent.py
Normal file
27
src/assets/ba_data/python/babase/_appintent.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Provides AppIntent functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AppIntent:
|
||||||
|
"""A high level directive given to the app.
|
||||||
|
|
||||||
|
Category: **App Classes**
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class AppIntentDefault(AppIntent):
|
||||||
|
"""Tells the app to simply run in its default mode."""
|
||||||
|
|
||||||
|
|
||||||
|
class AppIntentExec(AppIntent):
|
||||||
|
"""Tells the app to exec some Python code."""
|
||||||
|
|
||||||
|
def __init__(self, code: str):
|
||||||
|
self.code = code
|
||||||
35
src/assets/ba_data/python/babase/_appmode.py
Normal file
35
src/assets/ba_data/python/babase/_appmode.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Provides AppMode functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from babase._appintent import AppIntent
|
||||||
|
|
||||||
|
|
||||||
|
class AppMode:
|
||||||
|
"""A high level mode for the app.
|
||||||
|
|
||||||
|
Category: **App Classes**
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def supports_intent(cls, intent: AppIntent) -> bool:
|
||||||
|
"""Return whether our mode can handle the provided intent."""
|
||||||
|
del intent
|
||||||
|
|
||||||
|
# Say no to everything by default. Let's make mode explicitly
|
||||||
|
# lay out everything they *do* support.
|
||||||
|
return False
|
||||||
|
|
||||||
|
def handle_intent(self, intent: AppIntent) -> None:
|
||||||
|
"""Handle an intent."""
|
||||||
|
|
||||||
|
def on_activate(self) -> None:
|
||||||
|
"""Called when the mode is being activated."""
|
||||||
|
|
||||||
|
def on_deactivate(self) -> None:
|
||||||
|
"""Called when the mode is being deactivated."""
|
||||||
34
src/assets/ba_data/python/babase/_appmodeselector.py
Normal file
34
src/assets/ba_data/python/babase/_appmodeselector.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Provides AppMode functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from babase._appintent import AppIntent
|
||||||
|
from babase._appmode import AppMode
|
||||||
|
|
||||||
|
|
||||||
|
class AppModeSelector:
|
||||||
|
"""Defines which AppModes to use to handle given AppIntents.
|
||||||
|
|
||||||
|
Category: **App Classes**
|
||||||
|
|
||||||
|
The app calls an instance of this class when passed an AppIntent to
|
||||||
|
determine which AppMode to use to handle the intent. Plugins or
|
||||||
|
spinoff projects can modify high level app behavior by replacing or
|
||||||
|
modifying this.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# pylint: disable=useless-return
|
||||||
|
|
||||||
|
def app_mode_for_intent(self, intent: AppIntent) -> type[AppMode]:
|
||||||
|
"""Given an AppIntent, return the AppMode that should handle it.
|
||||||
|
|
||||||
|
If None is returned, the AppIntent will be ignored.
|
||||||
|
|
||||||
|
This is called in a background thread, so avoid any calls
|
||||||
|
limited to logic thread use/etc.
|
||||||
|
"""
|
||||||
|
raise RuntimeError('app_mode_for_intent() should be overridden.')
|
||||||
@ -31,7 +31,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
# Build number and version of the ballistica binary we expect to be
|
# Build number and version of the ballistica binary we expect to be
|
||||||
# using.
|
# using.
|
||||||
TARGET_BALLISTICA_BUILD = 21022
|
TARGET_BALLISTICA_BUILD = 21023
|
||||||
TARGET_BALLISTICA_VERSION = '1.7.20'
|
TARGET_BALLISTICA_VERSION = '1.7.20'
|
||||||
|
|
||||||
_g_env_config: EnvConfig | None = None
|
_g_env_config: EnvConfig | None = None
|
||||||
|
|||||||
@ -36,6 +36,8 @@ from _babase import (
|
|||||||
displaytimer,
|
displaytimer,
|
||||||
DisplayTimer,
|
DisplayTimer,
|
||||||
)
|
)
|
||||||
|
from babase._appintent import AppIntent, AppIntentDefault, AppIntentExec
|
||||||
|
from babase._appmode import AppMode
|
||||||
from babase._error import NotFoundError, NodeNotFoundError, ContextError
|
from babase._error import NotFoundError, NodeNotFoundError, ContextError
|
||||||
from babase._language import Lstr
|
from babase._language import Lstr
|
||||||
from babase._general import (
|
from babase._general import (
|
||||||
@ -55,7 +57,6 @@ from babase._mgen.enums import (
|
|||||||
InputType,
|
InputType,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
from _bascenev1 import (
|
from _bascenev1 import (
|
||||||
get_foreground_host_session,
|
get_foreground_host_session,
|
||||||
get_foreground_host_activity,
|
get_foreground_host_activity,
|
||||||
@ -135,6 +136,7 @@ from _bascenev1 import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from bascenev1._appmode import SceneV1AppMode
|
||||||
from bascenev1._session import Session
|
from bascenev1._session import Session
|
||||||
from bascenev1._map import Map
|
from bascenev1._map import Map
|
||||||
from bascenev1._coopsession import CoopSession
|
from bascenev1._coopsession import CoopSession
|
||||||
@ -200,11 +202,6 @@ from bascenev1._dependency import (
|
|||||||
AssetPackage,
|
AssetPackage,
|
||||||
)
|
)
|
||||||
|
|
||||||
# if TYPE_CHECKING:
|
|
||||||
# from babase._app import App
|
|
||||||
|
|
||||||
# app: App
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'app',
|
'app',
|
||||||
'get_local_active_input_devices_count',
|
'get_local_active_input_devices_count',
|
||||||
@ -383,6 +380,11 @@ __all__ = [
|
|||||||
'DisplayTimer',
|
'DisplayTimer',
|
||||||
'Time',
|
'Time',
|
||||||
'BaseTime',
|
'BaseTime',
|
||||||
|
'AppIntent',
|
||||||
|
'AppIntentDefault',
|
||||||
|
'AppIntentExec',
|
||||||
|
'AppMode',
|
||||||
|
'SceneV1AppMode',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Sanity check: we want to keep ballistica's dependencies and
|
# Sanity check: we want to keep ballistica's dependencies and
|
||||||
|
|||||||
36
src/assets/ba_data/python/bascenev1/_appmode.py
Normal file
36
src/assets/ba_data/python/bascenev1/_appmode.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Released under the MIT License. See LICENSE for details.
|
||||||
|
#
|
||||||
|
"""Provides AppMode functionality."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from babase import AppMode, AppIntentExec, AppIntentDefault
|
||||||
|
import _bascenev1
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from babase import AppIntent
|
||||||
|
|
||||||
|
|
||||||
|
class SceneV1AppMode(AppMode):
|
||||||
|
"""Our app-mode."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def supports_intent(cls, intent: AppIntent) -> bool:
|
||||||
|
# We support default and exec intents currently.
|
||||||
|
return isinstance(intent, AppIntentExec | AppIntentDefault)
|
||||||
|
|
||||||
|
def handle_intent(self, intent: AppIntent) -> None:
|
||||||
|
if isinstance(intent, AppIntentExec):
|
||||||
|
_bascenev1.handle_app_intent_exec(intent.code)
|
||||||
|
return
|
||||||
|
assert isinstance(intent, AppIntentDefault)
|
||||||
|
_bascenev1.handle_app_intent_default()
|
||||||
|
|
||||||
|
def on_activate(self) -> None:
|
||||||
|
# Let the native layer do its thing.
|
||||||
|
_bascenev1.app_mode_activate()
|
||||||
|
|
||||||
|
def on_deactivate(self) -> None:
|
||||||
|
# Let the native layer do its thing.
|
||||||
|
_bascenev1.app_mode_deactivate()
|
||||||
@ -58,6 +58,8 @@ from _babase import (
|
|||||||
)
|
)
|
||||||
from _babase import screenmessage
|
from _babase import screenmessage
|
||||||
|
|
||||||
|
from babase._appintent import AppIntent, AppIntentDefault, AppIntentExec
|
||||||
|
from babase._appmode import AppMode
|
||||||
from babase._general import Call, WeakCall, AppTime, DisplayTime
|
from babase._general import Call, WeakCall, AppTime, DisplayTime
|
||||||
from babase._language import Lstr
|
from babase._language import Lstr
|
||||||
from babase._plugin import PotentialPlugin, Plugin
|
from babase._plugin import PotentialPlugin, Plugin
|
||||||
@ -201,6 +203,10 @@ __all__ = [
|
|||||||
'displaytimer',
|
'displaytimer',
|
||||||
'DisplayTimer',
|
'DisplayTimer',
|
||||||
'uibounds',
|
'uibounds',
|
||||||
|
'AppIntent',
|
||||||
|
'AppIntentDefault',
|
||||||
|
'AppIntentExec',
|
||||||
|
'AppMode',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Sanity check: we want to keep ballistica's dependencies and
|
# Sanity check: we want to keep ballistica's dependencies and
|
||||||
|
|||||||
@ -1326,7 +1326,7 @@ void Assets::SetLanguageKeys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Let some subsystems know that language has changed.
|
// Let some subsystems know that language has changed.
|
||||||
g_base->app_mode->LanguageChanged();
|
g_base->app_mode()->LanguageChanged();
|
||||||
g_base->ui->LanguageChanged();
|
g_base->ui->LanguageChanged();
|
||||||
g_base->graphics->LanguageChanged();
|
g_base->graphics->LanguageChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,8 +71,8 @@ BaseFeatureSet::BaseFeatureSet()
|
|||||||
text_graphics{new TextGraphics()},
|
text_graphics{new TextGraphics()},
|
||||||
audio_server{new AudioServer()},
|
audio_server{new AudioServer()},
|
||||||
assets{new Assets()},
|
assets{new Assets()},
|
||||||
app_mode{TempSV1CreateAppMode()},
|
// app_mode{TempSV1CreateAppMode()},
|
||||||
// app_mode{AppModeEmpty::GetSingleton()},
|
app_mode_{AppModeEmpty::GetSingleton()},
|
||||||
stdio_console{g_buildconfig.enable_stdio_console() ? new StdioConsole()
|
stdio_console{g_buildconfig.enable_stdio_console() ? new StdioConsole()
|
||||||
: nullptr} {
|
: nullptr} {
|
||||||
// We're a singleton. If there's already one of us, something's wrong.
|
// We're a singleton. If there's already one of us, something's wrong.
|
||||||
@ -202,6 +202,11 @@ void BaseFeatureSet::StartApp() {
|
|||||||
g_core->BootLog("start-app end");
|
g_core->BootLog("start-app end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseFeatureSet::set_app_mode(AppMode* mode) {
|
||||||
|
assert(InLogicThread());
|
||||||
|
app_mode_ = mode;
|
||||||
|
}
|
||||||
|
|
||||||
auto BaseFeatureSet::AppManagesEventLoop() -> bool {
|
auto BaseFeatureSet::AppManagesEventLoop() -> bool {
|
||||||
return app->ManagesEventLoop();
|
return app->ManagesEventLoop();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -702,9 +702,11 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
|
|||||||
UI* const ui;
|
UI* const ui;
|
||||||
Utils* const utils;
|
Utils* const utils;
|
||||||
|
|
||||||
|
auto* console() const { return console_; }
|
||||||
|
auto* app_mode() const { return app_mode_; }
|
||||||
|
void set_app_mode(AppMode* mode);
|
||||||
|
|
||||||
// Non-const bits (fixme: clean up access to these).
|
// Non-const bits (fixme: clean up access to these).
|
||||||
AppMode* app_mode;
|
|
||||||
auto* console() { return console_; }
|
|
||||||
TouchInput* touch_input{};
|
TouchInput* touch_input{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -713,6 +715,7 @@ class BaseFeatureSet : public FeatureSetNativeComponent,
|
|||||||
void PrintContextForCallableLabel(const char* label);
|
void PrintContextForCallableLabel(const char* label);
|
||||||
void PrintContextUnavailable();
|
void PrintContextUnavailable();
|
||||||
|
|
||||||
|
AppMode* app_mode_;
|
||||||
Console* console_{};
|
Console* console_{};
|
||||||
std::string console_startup_messages_;
|
std::string console_startup_messages_;
|
||||||
bool called_start_app_{};
|
bool called_start_app_{};
|
||||||
|
|||||||
@ -416,7 +416,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (show_ping_) {
|
if (show_ping_) {
|
||||||
std::string ping_str = g_base->app_mode->GetPingString();
|
std::string ping_str = g_base->app_mode()->GetPingString();
|
||||||
float ping{};
|
float ping{};
|
||||||
if (!ping_str.empty()) {
|
if (!ping_str.empty()) {
|
||||||
if (ping_str != ping_string_) {
|
if (ping_str != ping_string_) {
|
||||||
@ -452,7 +452,7 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (show_net_info_) {
|
if (show_net_info_) {
|
||||||
auto net_info_str{g_base->app_mode->GetNetworkDebugString()};
|
auto net_info_str{g_base->app_mode()->GetNetworkDebugString()};
|
||||||
if (!net_info_str.empty()) {
|
if (!net_info_str.empty()) {
|
||||||
if (net_info_str != net_info_string_) {
|
if (net_info_str != net_info_string_) {
|
||||||
net_info_string_ = net_info_str;
|
net_info_string_ = net_info_str;
|
||||||
@ -908,6 +908,7 @@ void Graphics::AddScreenMessage(const std::string& msg, const Vector3f& color,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::Reset() {
|
void Graphics::Reset() {
|
||||||
|
assert(g_base->InLogicThread());
|
||||||
fade_ = 0;
|
fade_ = 0;
|
||||||
fade_start_ = 0;
|
fade_start_ = 0;
|
||||||
|
|
||||||
@ -1075,7 +1076,7 @@ void Graphics::DrawWorld(FrameDef* frame_def) {
|
|||||||
|
|
||||||
// Draw all session contents (nodes, etc.)
|
// Draw all session contents (nodes, etc.)
|
||||||
overlay_node_z_depth_ = -0.95f;
|
overlay_node_z_depth_ = -0.95f;
|
||||||
g_base->app_mode->DrawWorld(frame_def);
|
g_base->app_mode()->DrawWorld(frame_def);
|
||||||
g_base->bg_dynamics->Draw(frame_def);
|
g_base->bg_dynamics->Draw(frame_def);
|
||||||
|
|
||||||
// Lastly draw any blotches that have been building up.
|
// Lastly draw any blotches that have been building up.
|
||||||
@ -1131,7 +1132,7 @@ void Graphics::BuildAndPushFrameDef() {
|
|||||||
// wants to know.
|
// wants to know.
|
||||||
if (last_frame_def_graphics_quality_ != frame_def->quality()) {
|
if (last_frame_def_graphics_quality_ != frame_def->quality()) {
|
||||||
last_frame_def_graphics_quality_ = frame_def->quality();
|
last_frame_def_graphics_quality_ = frame_def->quality();
|
||||||
g_base->app_mode->GraphicsQualityChanged(frame_def->quality());
|
g_base->app_mode()->GraphicsQualityChanged(frame_def->quality());
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyCamera(frame_def);
|
ApplyCamera(frame_def);
|
||||||
@ -1142,7 +1143,7 @@ void Graphics::BuildAndPushFrameDef() {
|
|||||||
} else {
|
} else {
|
||||||
// Ok, we're drawing a real frame.
|
// Ok, we're drawing a real frame.
|
||||||
|
|
||||||
bool session_fills_screen = g_base->app_mode->DoesWorldFillScreen();
|
bool session_fills_screen = g_base->app_mode()->DoesWorldFillScreen();
|
||||||
|
|
||||||
frame_def->set_needs_clear(!session_fills_screen);
|
frame_def->set_needs_clear(!session_fills_screen);
|
||||||
DrawWorld(frame_def);
|
DrawWorld(frame_def);
|
||||||
|
|||||||
@ -995,8 +995,8 @@ void JoystickInput::HandleSDLEvent(const SDL_Event* e) {
|
|||||||
} else {
|
} else {
|
||||||
// FIXME: Need a call we can make for this.
|
// FIXME: Need a call we can make for this.
|
||||||
bool do_party_button = false;
|
bool do_party_button = false;
|
||||||
int party_size = g_base->app_mode->GetPartySize();
|
int party_size = g_base->app_mode()->GetPartySize();
|
||||||
if (party_size > 1 || g_base->app_mode->HasConnectionToHost()
|
if (party_size > 1 || g_base->app_mode()->HasConnectionToHost()
|
||||||
|| g_base->ui->root_ui()->always_draw_party_icon()) {
|
|| g_base->ui->root_ui()->always_draw_party_icon()) {
|
||||||
do_party_button = true;
|
do_party_button = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -266,7 +266,7 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) {
|
|||||||
|
|
||||||
// Let the current app-mode assign it a delegate.
|
// Let the current app-mode assign it a delegate.
|
||||||
auto delegate = Object::CompleteDeferred(
|
auto delegate = Object::CompleteDeferred(
|
||||||
g_base->app_mode->CreateInputDeviceDelegate(device));
|
g_base->app_mode()->CreateInputDeviceDelegate(device));
|
||||||
device->set_delegate(delegate);
|
device->set_delegate(delegate);
|
||||||
delegate->set_input_device(device);
|
delegate->set_input_device(device);
|
||||||
|
|
||||||
@ -980,12 +980,12 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) {
|
|||||||
|
|
||||||
case SDLK_EQUALS:
|
case SDLK_EQUALS:
|
||||||
case SDLK_PLUS:
|
case SDLK_PLUS:
|
||||||
g_base->app_mode->ChangeGameSpeed(1);
|
g_base->app_mode()->ChangeGameSpeed(1);
|
||||||
handled = true;
|
handled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_MINUS:
|
case SDLK_MINUS:
|
||||||
g_base->app_mode->ChangeGameSpeed(-1);
|
g_base->app_mode()->ChangeGameSpeed(-1);
|
||||||
handled = true;
|
handled = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -63,7 +63,7 @@ void Logic::OnAppStart() {
|
|||||||
g_base->input->OnAppStart();
|
g_base->input->OnAppStart();
|
||||||
g_base->ui->OnAppStart();
|
g_base->ui->OnAppStart();
|
||||||
g_core->platform->OnAppStart();
|
g_core->platform->OnAppStart();
|
||||||
g_base->app_mode->OnAppStart();
|
g_base->app_mode()->OnAppStart();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->OnAppStart();
|
g_base->Plus()->OnAppStart();
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ void Logic::OnAppPause() {
|
|||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->OnAppPause();
|
g_base->Plus()->OnAppPause();
|
||||||
}
|
}
|
||||||
g_base->app_mode->OnAppPause();
|
g_base->app_mode()->OnAppPause();
|
||||||
g_core->platform->OnAppPause();
|
g_core->platform->OnAppPause();
|
||||||
g_base->ui->OnAppPause();
|
g_base->ui->OnAppPause();
|
||||||
g_base->input->OnAppPause();
|
g_base->input->OnAppPause();
|
||||||
@ -108,7 +108,7 @@ void Logic::OnAppResume() {
|
|||||||
g_base->input->OnAppResume();
|
g_base->input->OnAppResume();
|
||||||
g_base->ui->OnAppResume();
|
g_base->ui->OnAppResume();
|
||||||
g_core->platform->OnAppResume();
|
g_core->platform->OnAppResume();
|
||||||
g_base->app_mode->OnAppResume();
|
g_base->app_mode()->OnAppResume();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->OnAppResume();
|
g_base->Plus()->OnAppResume();
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ void Logic::OnAppShutdown() {
|
|||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->OnAppShutdown();
|
g_base->Plus()->OnAppShutdown();
|
||||||
}
|
}
|
||||||
g_base->app_mode->OnAppShutdown();
|
g_base->app_mode()->OnAppShutdown();
|
||||||
g_core->platform->OnAppResume();
|
g_core->platform->OnAppResume();
|
||||||
g_base->ui->OnAppShutdown();
|
g_base->ui->OnAppShutdown();
|
||||||
g_base->input->OnAppShutdown();
|
g_base->input->OnAppShutdown();
|
||||||
@ -152,7 +152,7 @@ void Logic::ApplyAppConfig() {
|
|||||||
g_base->input->ApplyAppConfig();
|
g_base->input->ApplyAppConfig();
|
||||||
g_base->ui->ApplyAppConfig();
|
g_base->ui->ApplyAppConfig();
|
||||||
g_core->platform->ApplyAppConfig();
|
g_core->platform->ApplyAppConfig();
|
||||||
g_base->app_mode->ApplyAppConfig();
|
g_base->app_mode()->ApplyAppConfig();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->ApplyAppConfig();
|
g_base->Plus()->ApplyAppConfig();
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ void Logic::OnInitialScreenCreated() {
|
|||||||
1000 / 10, true, NewLambdaRunnable([this] { StepDisplayTime(); }));
|
1000 / 10, true, NewLambdaRunnable([this] { StepDisplayTime(); }));
|
||||||
}
|
}
|
||||||
// Let our initial app-mode know it has become active.
|
// Let our initial app-mode know it has become active.
|
||||||
g_base->app_mode->OnActivate();
|
g_base->app_mode()->OnActivate();
|
||||||
|
|
||||||
// Let the Python layer know what's up. It will probably flip to
|
// Let the Python layer know what's up. It will probably flip to
|
||||||
// 'Launching' state.
|
// 'Launching' state.
|
||||||
@ -224,6 +224,13 @@ void Logic::CompleteAppBootstrapping() {
|
|||||||
|
|
||||||
g_core->BootLog("app bootstrapping complete");
|
g_core->BootLog("app bootstrapping complete");
|
||||||
|
|
||||||
|
// Reset our various subsystems to a default state.
|
||||||
|
g_base->ui->Reset();
|
||||||
|
g_base->input->Reset();
|
||||||
|
g_base->graphics->Reset();
|
||||||
|
g_base->python->Reset();
|
||||||
|
g_base->audio->Reset();
|
||||||
|
|
||||||
// Let Python know we're done bootstrapping so it can flip the app
|
// Let Python know we're done bootstrapping so it can flip the app
|
||||||
// into the 'launching' state.
|
// into the 'launching' state.
|
||||||
g_base->python->objs()
|
g_base->python->objs()
|
||||||
@ -232,7 +239,7 @@ void Logic::CompleteAppBootstrapping() {
|
|||||||
app_bootstrapping_complete_ = true;
|
app_bootstrapping_complete_ = true;
|
||||||
|
|
||||||
// TODO(ericf): update this for the shiny new app-mode world.
|
// TODO(ericf): update this for the shiny new app-mode world.
|
||||||
if (explicit_bool(true)) {
|
if (explicit_bool(false)) {
|
||||||
// If we were passed launch command args, run them.
|
// If we were passed launch command args, run them.
|
||||||
if (g_core->core_config().exec_command.has_value()) {
|
if (g_core->core_config().exec_command.has_value()) {
|
||||||
bool success = PythonCommand(*g_core->core_config().exec_command,
|
bool success = PythonCommand(*g_core->core_config().exec_command,
|
||||||
@ -248,6 +255,8 @@ void Logic::CompleteAppBootstrapping() {
|
|||||||
if (!appmode->GetForegroundSession()) {
|
if (!appmode->GetForegroundSession()) {
|
||||||
appmode->RunMainMenu();
|
appmode->RunMainMenu();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Reset various subsystems
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePendingWorkTimer();
|
UpdatePendingWorkTimer();
|
||||||
@ -267,7 +276,7 @@ void Logic::OnScreenSizeChange(float virtual_width, float virtual_height,
|
|||||||
g_base->input->OnScreenSizeChange();
|
g_base->input->OnScreenSizeChange();
|
||||||
g_base->ui->OnScreenSizeChange();
|
g_base->ui->OnScreenSizeChange();
|
||||||
g_core->platform->OnScreenSizeChange();
|
g_core->platform->OnScreenSizeChange();
|
||||||
g_base->app_mode->OnScreenSizeChange();
|
g_base->app_mode()->OnScreenSizeChange();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->OnScreenSizeChange();
|
g_base->Plus()->OnScreenSizeChange();
|
||||||
}
|
}
|
||||||
@ -287,7 +296,7 @@ void Logic::StepDisplayTime() {
|
|||||||
g_base->input->StepDisplayTime();
|
g_base->input->StepDisplayTime();
|
||||||
g_base->ui->StepDisplayTime();
|
g_base->ui->StepDisplayTime();
|
||||||
g_core->platform->StepDisplayTime();
|
g_core->platform->StepDisplayTime();
|
||||||
g_base->app_mode->StepDisplayTime();
|
g_base->app_mode()->StepDisplayTime();
|
||||||
if (g_base->HavePlus()) {
|
if (g_base->HavePlus()) {
|
||||||
g_base->Plus()->StepDisplayTime();
|
g_base->Plus()->StepDisplayTime();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -234,7 +234,7 @@ auto NetworkReader::RunThread() -> int {
|
|||||||
memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
|
memcpy(s_buffer.data(), buffer + 1, rresult2 - 1);
|
||||||
s_buffer[rresult2 - 1] = 0; // terminate string
|
s_buffer[rresult2 - 1] = 0; // terminate string
|
||||||
std::string response =
|
std::string response =
|
||||||
g_base->app_mode->HandleJSONPing(s_buffer.data());
|
g_base->app_mode()->HandleJSONPing(s_buffer.data());
|
||||||
if (!response.empty()) {
|
if (!response.empty()) {
|
||||||
std::vector<char> msg(1 + response.size());
|
std::vector<char> msg(1 + response.size());
|
||||||
msg[0] = BA_PACKET_JSON_PONG;
|
msg[0] = BA_PACKET_JSON_PONG;
|
||||||
@ -302,7 +302,7 @@ auto NetworkReader::RunThread() -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case BA_PACKET_HOST_QUERY: {
|
case BA_PACKET_HOST_QUERY: {
|
||||||
g_base->app_mode->HandleGameQuery(buffer, rresult2, &from);
|
g_base->app_mode()->HandleGameQuery(buffer, rresult2, &from);
|
||||||
|
|
||||||
// HandleGameQuery(buffer, rresult2, &from);
|
// HandleGameQuery(buffer, rresult2, &from);
|
||||||
break;
|
break;
|
||||||
@ -338,8 +338,9 @@ void NetworkReader::PushIncomingUDPPacketCall(const std::vector<uint8_t>& data,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_base->logic->event_loop()->PushCall(
|
g_base->logic->event_loop()->PushCall([data, addr] {
|
||||||
[data, addr] { g_base->app_mode->HandleIncomingUDPPacket(data, addr); });
|
g_base->app_mode()->HandleIncomingUDPPacket(data, addr);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkReader::OpenSockets() {
|
void NetworkReader::OpenSockets() {
|
||||||
|
|||||||
@ -239,7 +239,7 @@ static auto PyPushCall(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
// Run this with an empty context by default, or foreground if
|
// Run this with an empty context by default, or foreground if
|
||||||
// requested.
|
// requested.
|
||||||
ScopedSetContext ssc(other_thread_use_fg_context
|
ScopedSetContext ssc(other_thread_use_fg_context
|
||||||
? g_base->app_mode->GetForegroundContext()
|
? g_base->app_mode()->GetForegroundContext()
|
||||||
: ContextRef(nullptr));
|
: ContextRef(nullptr));
|
||||||
|
|
||||||
PythonRef(call_obj, PythonRef::kSteal).Call();
|
PythonRef(call_obj, PythonRef::kSteal).Call();
|
||||||
@ -1243,6 +1243,28 @@ static PyMethodDef PyIsOSPlayingMusicDef = {
|
|||||||
"(Used to determine whether the game should avoid playing its own)",
|
"(Used to determine whether the game should avoid playing its own)",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------- exec_arg -----------------------------------
|
||||||
|
|
||||||
|
static auto PyExecArg(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
|
||||||
|
if (g_core->core_config().exec_command.has_value()) {
|
||||||
|
return PyUnicode_FromString(g_core->core_config().exec_command->c_str());
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyExecArgDef = {
|
||||||
|
"exec_arg", // name
|
||||||
|
(PyCFunction)PyExecArg, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"exec_arg() -> str | None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)\n",
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
||||||
@ -1281,6 +1303,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
|||||||
PyMacMusicAppGetPlaylistsDef,
|
PyMacMusicAppGetPlaylistsDef,
|
||||||
PyIsOSPlayingMusicDef,
|
PyIsOSPlayingMusicDef,
|
||||||
PyBootLogDef,
|
PyBootLogDef,
|
||||||
|
PyExecArgDef,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/ballistica/base/support/classic_soft.h
Normal file
18
src/ballistica/base/support/classic_soft.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Released under the MIT License. See LICENSE for details.
|
||||||
|
|
||||||
|
#ifndef BALLISTICA_BASE_SUPPORT_CLASSIC_SOFT_H_
|
||||||
|
#define BALLISTICA_BASE_SUPPORT_CLASSIC_SOFT_H_
|
||||||
|
|
||||||
|
namespace ballistica::base {
|
||||||
|
|
||||||
|
/// 'Soft' interface to the classic feature-set.
|
||||||
|
/// Feature-sets listing classic as a soft requirement must limit their use of
|
||||||
|
/// it to these methods and should be prepared to handle the not-present
|
||||||
|
/// case.
|
||||||
|
class ClassicSoftInterface {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ballistica::base
|
||||||
|
|
||||||
|
#endif // BALLISTICA_BASE_SUPPORT_CLASSIC_SOFT_H_
|
||||||
@ -107,7 +107,7 @@ void StdioConsole::OnMainThreadStartApp() {
|
|||||||
void StdioConsole::PushCommand(const std::string& command) {
|
void StdioConsole::PushCommand(const std::string& command) {
|
||||||
g_base->logic->event_loop()->PushCall([command] {
|
g_base->logic->event_loop()->PushCall([command] {
|
||||||
// These are always run in whichever context is 'visible'.
|
// These are always run in whichever context is 'visible'.
|
||||||
ScopedSetContext ssc(g_base->app_mode->GetForegroundContext());
|
ScopedSetContext ssc(g_base->app_mode()->GetForegroundContext());
|
||||||
PythonCommand cmd(command, "<stdin>");
|
PythonCommand cmd(command, "<stdin>");
|
||||||
if (!g_core->user_ran_commands) {
|
if (!g_core->user_ran_commands) {
|
||||||
g_core->user_ran_commands = true;
|
g_core->user_ran_commands = true;
|
||||||
|
|||||||
@ -146,7 +146,7 @@ void Console::PushCommand(const std::string& command) {
|
|||||||
assert(g_base);
|
assert(g_base);
|
||||||
g_base->logic->event_loop()->PushCall([command] {
|
g_base->logic->event_loop()->PushCall([command] {
|
||||||
// These are always run in whichever context is 'visible'.
|
// These are always run in whichever context is 'visible'.
|
||||||
ScopedSetContext ssc(g_base->app_mode->GetForegroundContext());
|
ScopedSetContext ssc(g_base->app_mode()->GetForegroundContext());
|
||||||
PythonCommand cmd(command, "<console>");
|
PythonCommand cmd(command, "<console>");
|
||||||
if (!g_core->user_ran_commands) {
|
if (!g_core->user_ran_commands) {
|
||||||
g_core->user_ran_commands = true;
|
g_core->user_ran_commands = true;
|
||||||
|
|||||||
@ -660,7 +660,7 @@ static PyMethodDef PyEndHostScanningDef = {
|
|||||||
static auto PyHaveConnectedClients(PyObject* self, PyObject* args,
|
static auto PyHaveConnectedClients(PyObject* self, PyObject* args,
|
||||||
PyObject* keywds) -> PyObject* {
|
PyObject* keywds) -> PyObject* {
|
||||||
BA_PYTHON_TRY;
|
BA_PYTHON_TRY;
|
||||||
if (g_base->app_mode->HasConnectionToClients()) {
|
if (g_base->app_mode()->HasConnectionToClients()) {
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
} else {
|
} else {
|
||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
#include "ballistica/scene_v1/support/session_stream.h"
|
#include "ballistica/scene_v1/support/session_stream.h"
|
||||||
#include "ballistica/shared/generic/json.h"
|
#include "ballistica/shared/generic/json.h"
|
||||||
#include "ballistica/shared/generic/utils.h"
|
#include "ballistica/shared/generic/utils.h"
|
||||||
|
#include "ballistica/shared/python/python_command.h"
|
||||||
|
|
||||||
namespace ballistica::scene_v1 {
|
namespace ballistica::scene_v1 {
|
||||||
|
|
||||||
@ -1611,6 +1612,109 @@ static PyMethodDef PySetInternalMusicDef = {
|
|||||||
"(internal).",
|
"(internal).",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --------------------------- app_mode_activate -------------------------------
|
||||||
|
|
||||||
|
static auto PyAppModeActivate(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
g_base->set_app_mode(SceneV1AppMode::GetSingleton());
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyAppModeActivateDef = {
|
||||||
|
"app_mode_activate", // name
|
||||||
|
(PyCFunction)PyAppModeActivate, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"app_mode_activate() -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------------- app_mode_deactivate ------------------------------
|
||||||
|
|
||||||
|
static auto PyAppModeDeactivate(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
// Currently doing nothing.
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyAppModeDeactivateDef = {
|
||||||
|
"app_mode_deactivate", // name
|
||||||
|
(PyCFunction)PyAppModeDeactivate, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"app_mode_deactivate() -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------- handle_app_intent_default ---------------------------
|
||||||
|
|
||||||
|
static auto PyHandleAppIntentDefault(PyObject* self) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
BA_PRECONDITION(g_base->InLogicThread());
|
||||||
|
auto* appmode = SceneV1AppMode::GetActiveOrThrow();
|
||||||
|
appmode->RunMainMenu();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyHandleAppIntentDefaultDef = {
|
||||||
|
"handle_app_intent_default", // name
|
||||||
|
(PyCFunction)PyHandleAppIntentDefault, // method
|
||||||
|
METH_NOARGS, // flags
|
||||||
|
|
||||||
|
"handle_app_intent_default() -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------ handle_app_intent_exec -----------------------------
|
||||||
|
|
||||||
|
static auto PyHandleAppIntentExec(PyObject* self, PyObject* args,
|
||||||
|
PyObject* keywds) -> PyObject* {
|
||||||
|
BA_PYTHON_TRY;
|
||||||
|
const char* command;
|
||||||
|
static const char* kwlist[] = {"command", nullptr};
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s",
|
||||||
|
const_cast<char**>(kwlist), &command)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto* appmode = SceneV1AppMode::GetActiveOrThrow();
|
||||||
|
|
||||||
|
// Run the command.
|
||||||
|
if (g_core->core_config().exec_command.has_value()) {
|
||||||
|
bool success = PythonCommand(*g_core->core_config().exec_command,
|
||||||
|
BA_BUILD_COMMAND_FILENAME)
|
||||||
|
.Exec(true, nullptr, nullptr);
|
||||||
|
if (!success) {
|
||||||
|
// FIXME: what should we do in this case?
|
||||||
|
// exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the stuff we just ran didn't result in a session, create a default
|
||||||
|
// one.
|
||||||
|
if (!appmode->GetForegroundSession()) {
|
||||||
|
appmode->RunMainMenu();
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
BA_PYTHON_CATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyHandleAppIntentExecDef = {
|
||||||
|
"handle_app_intent_exec", // name
|
||||||
|
(PyCFunction)PyHandleAppIntentExec, // method
|
||||||
|
METH_VARARGS | METH_KEYWORDS, // flags
|
||||||
|
|
||||||
|
"handle_app_intent_exec(command: str) -> None\n"
|
||||||
|
"\n"
|
||||||
|
"(internal)",
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> {
|
auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> {
|
||||||
@ -1646,6 +1750,10 @@ auto PythonMethodsScene::GetMethods() -> std::vector<PyMethodDef> {
|
|||||||
PyBaseTimeDef,
|
PyBaseTimeDef,
|
||||||
PyBaseTimerDef,
|
PyBaseTimerDef,
|
||||||
PyLsInputDevicesDef,
|
PyLsInputDevicesDef,
|
||||||
|
PyAppModeActivateDef,
|
||||||
|
PyAppModeDeactivateDef,
|
||||||
|
PyHandleAppIntentDefaultDef,
|
||||||
|
PyHandleAppIntentExecDef,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -315,7 +315,7 @@ auto SceneV1AppMode::GetActive() -> SceneV1AppMode* {
|
|||||||
// keep in mind that app-mode may change under them.
|
// keep in mind that app-mode may change under them.
|
||||||
|
|
||||||
// Otherwise return our singleton only if it is current.
|
// Otherwise return our singleton only if it is current.
|
||||||
if (g_base->app_mode == g_scene_v1_app_mode) {
|
if (g_base->app_mode() == g_scene_v1_app_mode) {
|
||||||
return g_scene_v1_app_mode;
|
return g_scene_v1_app_mode;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1389,7 +1389,7 @@ void SceneV1AppMode::HandleGameQuery(const char* buffer, size_t size,
|
|||||||
if (size == 5) {
|
if (size == 5) {
|
||||||
// If we're already in a party, don't advertise since they
|
// If we're already in a party, don't advertise since they
|
||||||
// wouldn't be able to join us anyway.
|
// wouldn't be able to join us anyway.
|
||||||
if (g_base->app_mode->HasConnectionToHost()) {
|
if (g_base->app_mode()->HasConnectionToHost()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
namespace ballistica::scene_v1 {
|
namespace ballistica::scene_v1 {
|
||||||
|
|
||||||
auto ContextRefSceneV1::FromAppForegroundContext() -> ContextRefSceneV1 {
|
auto ContextRefSceneV1::FromAppForegroundContext() -> ContextRefSceneV1 {
|
||||||
auto* c = g_base->app_mode->GetForegroundContext().Get();
|
auto* c = g_base->app_mode()->GetForegroundContext().Get();
|
||||||
return ContextRefSceneV1(c);
|
return ContextRefSceneV1(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
|||||||
namespace ballistica {
|
namespace ballistica {
|
||||||
|
|
||||||
// These are set automatically via script; don't modify them here.
|
// These are set automatically via script; don't modify them here.
|
||||||
const int kEngineBuildNumber = 21022;
|
const int kEngineBuildNumber = 21023;
|
||||||
const char* kEngineVersion = "1.7.20";
|
const char* kEngineVersion = "1.7.20";
|
||||||
|
|
||||||
auto MonolithicMain(const core::CoreConfig& core_config) -> int {
|
auto MonolithicMain(const core::CoreConfig& core_config) -> int {
|
||||||
|
|||||||
@ -2665,8 +2665,8 @@ static auto PyCanShowAd(PyObject* self, PyObject* args, PyObject* keywds)
|
|||||||
// them or whatnot). Also disallow ads if remote apps are connected; at least
|
// them or whatnot). Also disallow ads if remote apps are connected; at least
|
||||||
// on Android, ads pause our activity which disconnects the remote app.
|
// on Android, ads pause our activity which disconnects the remote app.
|
||||||
// (need to fix this).
|
// (need to fix this).
|
||||||
if (g_base->app_mode->HasConnectionToHost()
|
if (g_base->app_mode()->HasConnectionToHost()
|
||||||
|| g_base->app_mode->HasConnectionToClients()
|
|| g_base->app_mode()->HasConnectionToClients()
|
||||||
|| g_base->input->HaveRemoteAppController()) {
|
|| g_base->input->HaveRemoteAppController()) {
|
||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
@ -2873,8 +2873,8 @@ static auto PyIsPartyIconVisible(PyObject* self, PyObject* args,
|
|||||||
PyObject* keywds) -> PyObject* {
|
PyObject* keywds) -> PyObject* {
|
||||||
BA_PYTHON_TRY;
|
BA_PYTHON_TRY;
|
||||||
bool party_button_active =
|
bool party_button_active =
|
||||||
(g_base->app_mode->HasConnectionToClients()
|
(g_base->app_mode()->HasConnectionToClients()
|
||||||
|| g_base->app_mode->HasConnectionToHost()
|
|| g_base->app_mode()->HasConnectionToHost()
|
||||||
|| g_base->ui->root_ui()->always_draw_party_icon());
|
|| g_base->ui->root_ui()->always_draw_party_icon());
|
||||||
if (party_button_active) {
|
if (party_button_active) {
|
||||||
Py_RETURN_TRUE;
|
Py_RETURN_TRUE;
|
||||||
|
|||||||
@ -42,8 +42,9 @@ RootUI::~RootUI() = default;
|
|||||||
|
|
||||||
void RootUI::TogglePartyWindowKeyPress() {
|
void RootUI::TogglePartyWindowKeyPress() {
|
||||||
assert(g_base->InLogicThread());
|
assert(g_base->InLogicThread());
|
||||||
if (g_base->app_mode->GetPartySize() > 1
|
if (g_base->app_mode()->GetPartySize() > 1
|
||||||
|| g_base->app_mode->HasConnectionToHost() || always_draw_party_icon()) {
|
|| g_base->app_mode()->HasConnectionToHost()
|
||||||
|
|| always_draw_party_icon()) {
|
||||||
ActivatePartyIcon();
|
ActivatePartyIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,8 +78,8 @@ auto RootUI::HandleMouseButtonDown(float x, float y) -> bool {
|
|||||||
// floats over the top). Party button is to the left of menu button.
|
// floats over the top). Party button is to the left of menu button.
|
||||||
if (explicit_bool(DO_OLD_MENU_PARTY_BUTTONS)) {
|
if (explicit_bool(DO_OLD_MENU_PARTY_BUTTONS)) {
|
||||||
bool party_button_active = (!party_window_open_
|
bool party_button_active = (!party_window_open_
|
||||||
&& (g_base->app_mode->HasConnectionToClients()
|
&& (g_base->app_mode()->HasConnectionToClients()
|
||||||
|| g_base->app_mode->HasConnectionToHost()
|
|| g_base->app_mode()->HasConnectionToHost()
|
||||||
|| always_draw_party_icon()));
|
|| always_draw_party_icon()));
|
||||||
float party_button_left =
|
float party_button_left =
|
||||||
menu_active ? 2 * menu_button_size_ : menu_button_size_;
|
menu_active ? 2 * menu_button_size_ : menu_button_size_;
|
||||||
@ -202,17 +203,17 @@ void RootUI::Draw(base::FrameDef* frame_def) {
|
|||||||
// To the left of the menu button, draw our connected-players indicator
|
// To the left of the menu button, draw our connected-players indicator
|
||||||
// (this probably shouldn't live here).
|
// (this probably shouldn't live here).
|
||||||
bool draw_connected_players_icon = false;
|
bool draw_connected_players_icon = false;
|
||||||
int party_size = g_base->app_mode->GetPartySize();
|
int party_size = g_base->app_mode()->GetPartySize();
|
||||||
bool is_host = (!g_base->app_mode->HasConnectionToHost());
|
bool is_host = (!g_base->app_mode()->HasConnectionToHost());
|
||||||
millisecs_t last_connection_to_client_join_time =
|
millisecs_t last_connection_to_client_join_time =
|
||||||
g_base->app_mode->LastClientJoinTime();
|
g_base->app_mode()->LastClientJoinTime();
|
||||||
|
|
||||||
bool show_client_joined =
|
bool show_client_joined =
|
||||||
(is_host && last_connection_to_client_join_time != 0
|
(is_host && last_connection_to_client_join_time != 0
|
||||||
&& real_time - last_connection_to_client_join_time < 5000);
|
&& real_time - last_connection_to_client_join_time < 5000);
|
||||||
|
|
||||||
if (!party_window_open_
|
if (!party_window_open_
|
||||||
&& (party_size != 0 || g_base->app_mode->HasConnectionToHost()
|
&& (party_size != 0 || g_base->app_mode()->HasConnectionToHost()
|
||||||
|| always_draw_party_icon_)) {
|
|| always_draw_party_icon_)) {
|
||||||
draw_connected_players_icon = true;
|
draw_connected_players_icon = true;
|
||||||
}
|
}
|
||||||
@ -221,7 +222,7 @@ void RootUI::Draw(base::FrameDef* frame_def) {
|
|||||||
// Flash and show a message if we're in the main menu instructing the
|
// Flash and show a message if we're in the main menu instructing the
|
||||||
// player to start a game.
|
// player to start a game.
|
||||||
bool flash = false;
|
bool flash = false;
|
||||||
bool in_main_menu = g_base->app_mode->InMainMenu();
|
bool in_main_menu = g_base->app_mode()->InMainMenu();
|
||||||
|
|
||||||
if (in_main_menu && party_size > 0 && show_client_joined) flash = true;
|
if (in_main_menu && party_size > 0 && show_client_joined) flash = true;
|
||||||
|
|
||||||
|
|||||||
@ -895,7 +895,7 @@ void RootWidget::UpdateForFocusedWindow() {
|
|||||||
void RootWidget::UpdateForFocusedWindow(Widget* widget) {
|
void RootWidget::UpdateForFocusedWindow(Widget* widget) {
|
||||||
// Take note if the current session is the main menu; we do a few things
|
// Take note if the current session is the main menu; we do a few things
|
||||||
// differently there.
|
// differently there.
|
||||||
in_main_menu_ = g_base->app_mode->InMainMenu();
|
in_main_menu_ = g_base->app_mode()->InMainMenu();
|
||||||
|
|
||||||
if (widget == nullptr) {
|
if (widget == nullptr) {
|
||||||
toolbar_visibility_ = ToolbarVisibility::kInGame;
|
toolbar_visibility_ = ToolbarVisibility::kInGame;
|
||||||
|
|||||||
@ -312,7 +312,10 @@ class ProjectUpdater:
|
|||||||
)
|
)
|
||||||
|
|
||||||
for i, change in enumerate(auto_changes):
|
for i, change in enumerate(auto_changes):
|
||||||
print(f'{Clr.BLU}Correcting file: {change[0]}{Clr.RST}')
|
print(
|
||||||
|
f'{Clr.BLU}{Clr.BLD}Correcting'
|
||||||
|
f' {change[0]} line {change[1].line_number+1}{Clr.RST}'
|
||||||
|
)
|
||||||
with open(
|
with open(
|
||||||
os.path.join(self.projroot, change[0]), encoding='utf-8'
|
os.path.join(self.projroot, change[0]), encoding='utf-8'
|
||||||
) as infile:
|
) as infile:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user