mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 13:25:31 +08:00
added bascenev1.get_connection_to_host_info_2()
This commit is contained in:
parent
c6f0ecf17e
commit
5cf8065c40
100
.efrocachemap
generated
100
.efrocachemap
generated
@ -421,18 +421,18 @@
|
||||
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
|
||||
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
|
||||
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
|
||||
"build/assets/ba_data/data/langdata.json": "c6f94f9c1dc833c537d16672d9018b94",
|
||||
"build/assets/ba_data/data/langdata.json": "4a35cc51d1021fa7e525123bcf99043c",
|
||||
"build/assets/ba_data/data/languages/arabic.json": "00ba700de6c672a56658a6bd1ad27523",
|
||||
"build/assets/ba_data/data/languages/belarussian.json": "7fe38341815ca6ff4d95224196e7a67e",
|
||||
"build/assets/ba_data/data/languages/chinese.json": "5761468d25f2bd4e79921826cebd572b",
|
||||
"build/assets/ba_data/data/languages/chinesetraditional.json": "f858da49be0a5374157c627857751078",
|
||||
"build/assets/ba_data/data/languages/croatian.json": "766532c67af5bd0144c2d63cab0516fa",
|
||||
"build/assets/ba_data/data/languages/czech.json": "93c5fe0d884d95435da6c675f64e30e0",
|
||||
"build/assets/ba_data/data/languages/czech.json": "cd21ad8c6b8e9ed700284cf1e1aecbf8",
|
||||
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
|
||||
"build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e",
|
||||
"build/assets/ba_data/data/languages/english.json": "bd43b77b1ccca059573acbde148b4767",
|
||||
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
|
||||
"build/assets/ba_data/data/languages/filipino.json": "afbda3adf14555e1567ee63c32e340e7",
|
||||
"build/assets/ba_data/data/languages/filipino.json": "0f5ad7c06db70027b116dfd9324bdf67",
|
||||
"build/assets/ba_data/data/languages/french.json": "49ff6d211537b8003b8241438dca661d",
|
||||
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
|
||||
"build/assets/ba_data/data/languages/gibberish.json": "9aae526303a22372fe9b4cf1781520ef",
|
||||
@ -445,12 +445,12 @@
|
||||
"build/assets/ba_data/data/languages/malay.json": "832562ce997fc70704b9234c95fb2e38",
|
||||
"build/assets/ba_data/data/languages/persian.json": "d742f4a6d3c3555031102b21abdcbb5b",
|
||||
"build/assets/ba_data/data/languages/polish.json": "b9a58b70ed5e99d8b7fa2392b2eb0cda",
|
||||
"build/assets/ba_data/data/languages/portuguese.json": "556af4e8170356ad239412e1743e20d5",
|
||||
"build/assets/ba_data/data/languages/portuguese.json": "e3adc6c04486d21e84019a0b03ce11b1",
|
||||
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
|
||||
"build/assets/ba_data/data/languages/russian.json": "e120993371f52edd2d99f2236188933c",
|
||||
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
|
||||
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef",
|
||||
"build/assets/ba_data/data/languages/spanish.json": "80ea58bd3295a0252b7fdac9154aa22f",
|
||||
"build/assets/ba_data/data/languages/spanish.json": "1d14210b4eefb48130608bd0495b7900",
|
||||
"build/assets/ba_data/data/languages/swedish.json": "5142a96597d17d8344be96a603da64ac",
|
||||
"build/assets/ba_data/data/languages/tamil.json": "b4de1a2851afe4869c82e9acd94cd89c",
|
||||
"build/assets/ba_data/data/languages/thai.json": "77755219bbf5fb7eea0d6b226684f403",
|
||||
@ -4060,50 +4060,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": "8561660678904509458b80bb4b62d8ea",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "f2e7de4723ce8fb6984a5bbd9ac93aa6",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "af1ade2cc275dacc7e1793383d766f3d",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bb806faa941b6c3c7834383264cf8571",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "648bfaca6487ff13cd27a31e317878f0",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "38501876d5009ecaa936994ec6fbb3a2",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "f7d354aded26684974b4d0fbb8725762",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "f6ceb8135fe4fb9aa7fc13fb1b835077",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "402cb0d5a0abecfa9e578f3801b15e59",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "4eae3e6ade00be0224839bfc16351d2c",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "c6dd9b6cf876db50aa8d0cc0cc80efa4",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "79d19536ed7de918c947c5095286b8ce",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "409140e2c39941dbc66088417399d5ea",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "1a25fd7e3c5b94a294ce769083b71751",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7bfbb50681473702f286a50e56277b93",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "37ce7d3b865c0b58161c2d4ccdb54256",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "728dfc083916d7199dee1e75ad12e9fc",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "fbf59de05d7e121d9c5dd164939228dc",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "1eb456e1b1c4d215912809950d938c1a",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "65f507699fed78fcfa12e3e63af2bf8b",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "4f5d3cafbea651078c1721684b61033a",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "7436c575aee1f9d112d41f18e2ae6b22",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "4f5d3cafbea651078c1721684b61033a",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "7436c575aee1f9d112d41f18e2ae6b22",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "3ffcb35eb71566fefb7d9ad2589b37b4",
|
||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "ce9de33efccb9aa1e301fe4f11e6b1c1",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "3ffcb35eb71566fefb7d9ad2589b37b4",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "ce9de33efccb9aa1e301fe4f11e6b1c1",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "9d674b5e8a8357b9462a65359611ea45",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "e6d1c0b9bf27c34968e512c5db8e7de5",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "9d674b5e8a8357b9462a65359611ea45",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "e6d1c0b9bf27c34968e512c5db8e7de5",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "910b5e39fe4ba5bb849505c578efe3ec",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "2d9e14f7cfe50b1dc51e5e9eae05b5fd",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "b83a67eeaed0fc99bf995767a8150e5d",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "2d9e14f7cfe50b1dc51e5e9eae05b5fd",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "f6a855e83d7816e73d9859ff9e508190",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "6cd203dce2718e0eded672c83c51506a",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "a1f81d6527bba562c3626e520ab8aa2d",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "8b6a8b19f73b67413612185aa2d9ca5d",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "2534af31cf9f8a86ddb7c92b0184f4b2",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "0cf7fb12f97a3f8176462ec5d1ddb992",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "4afbbfa78e25e932d9392a1bd6bacc52",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a0ba1ed33b7a83543b51f24a96941dfa",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "6135aeb242afaf9d1114810a67c89cec",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "bbbbb14d42ed6eb0c5eb56867b7fb870",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "cd28f9cc4652736a31c677fc4e5dbaf1",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "239c608cc52c0320210e56ad6abe57a5",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "e76d67cacf1393d33796d6b6b1bf1413",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "a7eaa8dc4d859ef7a735483b04ccec4a",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "7a2eef42da34a35ddcc2fd7c66843b1b",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "694599ac6a967b2ed383b27bf8093e5b",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "c91cbab6a07affa22e0612210f8b807c",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "d460f7a3909f92d5dbf752e4521a9fbc",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0a0abfe75bc987e7b65a3cfa106e8353",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "8f21405b29f2b2ab01323d711492cca0",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "96dc73e819f41f99a1b2dbb45f79d551",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "c79ac51cd2deabb1c2d0acddeaf81c30",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "f06ec14e8c3106be9df91af7da621dc9",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "f389f9a7b1afc81f76787722340cfa9c",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "c7dab78aac11cb1430d8456d5d48107a",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "67e29852dfee2e63e179cfebf608ef26",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9778f8faf91c9993fbf3015bd4554a87",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "73477bd15b9e3834314fd878c9e108d4",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "fb9b8443c1b4cccad749df7d6328220f",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "384fb7fd55ad5a6cdbb662da1ec402ab",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "fb9b8443c1b4cccad749df7d6328220f",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "384fb7fd55ad5a6cdbb662da1ec402ab",
|
||||
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "bc7d0811bcd87156ebf5292a38a1c350",
|
||||
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "bb32f45054b6999300bf8b41d6a4b402",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "bc7d0811bcd87156ebf5292a38a1c350",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "bb32f45054b6999300bf8b41d6a4b402",
|
||||
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "8d9a1505bf397f4902baabed7c1cf438",
|
||||
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "f4d9c115e22dd81e36d1c5baeac8d848",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "8d9a1505bf397f4902baabed7c1cf438",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "f4d9c115e22dd81e36d1c5baeac8d848",
|
||||
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "fb72c92ec6ec0e1c8f4ced32abd86505",
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "131aab20cfe77fe89c3f452a855f1e68",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "ee10cdc9f9a861e2be0f1a208c0ca0fe",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "131aab20cfe77fe89c3f452a855f1e68",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "678fabc6dfd6f401ee8942d088ee9181",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "e092d2aed8464a61a623d79ca25308d8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "6b658f49be396ad645c5e57464739a3b",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "9d79a56403a6d806ff131a7de664dfa7",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "e831a26d2c28e862d51e24393d158c99",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "46fe1c89bcc75c781729ec9e5491c610",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "9c6278d7df3ce4db2ffe7794a0fd35b7",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "110c35a17b462864075800756b5e541a",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",
|
||||
@ -4112,7 +4112,7 @@
|
||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",
|
||||
"src/ballistica/core/mgen/pyembed/env.inc": "8be46e5818f360d10b7b0224a9e91d07",
|
||||
"src/ballistica/core/mgen/python_modules_monolithic.h": "fb967ed1c7db0c77d8deb4f00a7103c5",
|
||||
"src/ballistica/scene_v1/mgen/pyembed/binding_scene_v1.inc": "d80f970053099b3044204bfe29ddefce",
|
||||
"src/ballistica/scene_v1/mgen/pyembed/binding_scene_v1.inc": "c25b263f2a31fb5ebe057db07d144879",
|
||||
"src/ballistica/template_fs/mgen/pyembed/binding_template_fs.inc": "44a45492db057bf7f7158c3b0fa11f0f",
|
||||
"src/ballistica/ui_v1/mgen/pyembed/binding_ui_v1.inc": "f5f054050d2b2fcd3763a4833fb32269"
|
||||
}
|
||||
1
.idea/ballisticakit.iml
generated
1
.idea/ballisticakit.iml
generated
@ -21,7 +21,6 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-android" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-cmake" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-ios.xcodeproj" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-mac.xcodeproj" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-windows" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-windows-oculus" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/ballisticakit-xcode" />
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
### 1.7.31 (build 21700, api 8, 2023-12-09)
|
||||
|
||||
### 1.7.31 (build 21707, api 8, 2023-12-13)
|
||||
- added `bascenev1.get_connection_to_host_info_2()` which is an improved
|
||||
type-safe version of `bascenev1.get_connection_to_host_info()`.
|
||||
|
||||
### 1.7.30 (build 21697, api 8, 2023-12-08)
|
||||
- Continued work on the big 1.7.28 update.
|
||||
- Got the Android version back up and running. There's been lots of cleanup and
|
||||
|
||||
1
ballisticakit-cmake/.idea/misc.xml
generated
1
ballisticakit-cmake/.idea/misc.xml
generated
@ -14,7 +14,6 @@
|
||||
<file path="$PROJECT_DIR$/../ballisticakit-android" />
|
||||
<file path="$PROJECT_DIR$/.idea" />
|
||||
<file path="$PROJECT_DIR$/../ballisticakit-ios.xcodeproj" />
|
||||
<file path="$PROJECT_DIR$/../ballisticakit-mac.xcodeproj" />
|
||||
<file path="$PROJECT_DIR$/../ballisticakit-windows" />
|
||||
<file path="$PROJECT_DIR$/../ballisticakit-xcode" />
|
||||
<file path="$PROJECT_DIR$/../build" />
|
||||
|
||||
@ -152,7 +152,6 @@ ctx.filter_dirs = {
|
||||
'ballisticakit-cmake',
|
||||
'ballisticakit-xcode/BallisticaKit.xcodeproj',
|
||||
'ballisticakit-ios.xcodeproj',
|
||||
'ballisticakit-mac.xcodeproj',
|
||||
'config',
|
||||
'src/assets/pdoc',
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
"ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_general.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_hooks.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_keyboard.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_language.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_login.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/babase/__pycache__/_math.cpython-311.opt-1.pyc",
|
||||
@ -50,7 +49,6 @@
|
||||
"ba_data/python/babase/_error.py",
|
||||
"ba_data/python/babase/_general.py",
|
||||
"ba_data/python/babase/_hooks.py",
|
||||
"ba_data/python/babase/_keyboard.py",
|
||||
"ba_data/python/babase/_language.py",
|
||||
"ba_data/python/babase/_login.py",
|
||||
"ba_data/python/babase/_math.py",
|
||||
@ -152,6 +150,7 @@
|
||||
"ba_data/python/bascenev1/__pycache__/_messages.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_multiteamsession.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_music.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_net.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_nodeactor.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_player.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bascenev1/__pycache__/_playlist.cpython-311.opt-1.pyc",
|
||||
@ -186,6 +185,7 @@
|
||||
"ba_data/python/bascenev1/_messages.py",
|
||||
"ba_data/python/bascenev1/_multiteamsession.py",
|
||||
"ba_data/python/bascenev1/_music.py",
|
||||
"ba_data/python/bascenev1/_net.py",
|
||||
"ba_data/python/bascenev1/_nodeactor.py",
|
||||
"ba_data/python/bascenev1/_player.py",
|
||||
"ba_data/python/bascenev1/_playlist.py",
|
||||
@ -352,10 +352,12 @@
|
||||
"ba_data/python/bauiv1/__init__.py",
|
||||
"ba_data/python/bauiv1/__pycache__/__init__.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/__pycache__/_hooks.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/__pycache__/_keyboard.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/__pycache__/_subsystem.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/__pycache__/_uitypes.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/__pycache__/onscreenkeyboard.cpython-311.opt-1.pyc",
|
||||
"ba_data/python/bauiv1/_hooks.py",
|
||||
"ba_data/python/bauiv1/_keyboard.py",
|
||||
"ba_data/python/bauiv1/_subsystem.py",
|
||||
"ba_data/python/bauiv1/_uitypes.py",
|
||||
"ba_data/python/bauiv1/onscreenkeyboard.py",
|
||||
|
||||
@ -178,7 +178,6 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_error.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_general.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_hooks.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_keyboard.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_language.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_login.py \
|
||||
$(BUILD_DIR)/ba_data/python/babase/_math.py \
|
||||
@ -237,6 +236,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_messages.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_multiteamsession.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_music.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_net.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_nodeactor.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_player.py \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/_playlist.py \
|
||||
@ -326,6 +326,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/batemplatefs/_subsystem.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__init__.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/_hooks.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/_keyboard.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/_subsystem.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/_uitypes.py \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/onscreenkeyboard.py \
|
||||
@ -452,7 +453,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_error.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_general.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_hooks.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_keyboard.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_language.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_login.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/babase/__pycache__/_math.cpython-311.opt-1.pyc \
|
||||
@ -511,6 +511,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_messages.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_multiteamsession.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_music.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_net.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_nodeactor.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_player.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bascenev1/__pycache__/_playlist.cpython-311.opt-1.pyc \
|
||||
@ -600,6 +601,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
|
||||
$(BUILD_DIR)/ba_data/python/batemplatefs/__pycache__/_subsystem.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/__init__.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/_hooks.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/_keyboard.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/_subsystem.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/_uitypes.cpython-311.opt-1.pyc \
|
||||
$(BUILD_DIR)/ba_data/python/bauiv1/__pycache__/onscreenkeyboard.cpython-311.opt-1.pyc \
|
||||
|
||||
@ -154,7 +154,6 @@ from babase._general import (
|
||||
getclass,
|
||||
get_type_name,
|
||||
)
|
||||
from babase._keyboard import Keyboard
|
||||
from babase._language import Lstr, LanguageSubsystem
|
||||
from babase._login import LoginAdapter, LoginInfo
|
||||
|
||||
@ -261,7 +260,6 @@ __all__ = [
|
||||
'is_point_in_box',
|
||||
'is_running_on_fire_tv',
|
||||
'is_xcode_build',
|
||||
'Keyboard',
|
||||
'LanguageSubsystem',
|
||||
'lock_all_input',
|
||||
'LoginAdapter',
|
||||
|
||||
@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
||||
from babase._login import LoginAdapter, LoginInfo
|
||||
|
||||
|
||||
DEBUG_LOG = _babase.temp_testing()
|
||||
DEBUG_LOG = False
|
||||
|
||||
|
||||
class AccountV2Subsystem:
|
||||
|
||||
@ -31,6 +31,7 @@ class AppMode:
|
||||
AppExperience associated with the AppMode must be supported by
|
||||
the current app and runtime environment.
|
||||
"""
|
||||
# FIXME: check AppExperience.
|
||||
return cls._supports_intent(intent)
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -325,7 +325,7 @@ def dump_app_state(
|
||||
)
|
||||
|
||||
|
||||
def log_dumped_app_state() -> None:
|
||||
def log_dumped_app_state(from_previous_run: bool = False) -> None:
|
||||
"""If an app-state dump exists, log it and clear it. No-op otherwise."""
|
||||
|
||||
try:
|
||||
@ -352,8 +352,13 @@ def log_dumped_app_state() -> None:
|
||||
|
||||
metadata = dataclass_from_json(DumpedAppStateMetadata, appstatedata)
|
||||
|
||||
header = (
|
||||
'Found app state dump from previous app run'
|
||||
if from_previous_run
|
||||
else 'App state dump'
|
||||
)
|
||||
out += (
|
||||
f'App state dump:\nReason: {metadata.reason}\n'
|
||||
f'{header}:\nReason: {metadata.reason}\n'
|
||||
f'Time: {metadata.app_time:.2f}'
|
||||
)
|
||||
tbpath = os.path.join(
|
||||
@ -383,7 +388,7 @@ class AppHealthMonitor(AppSubsystem):
|
||||
|
||||
def on_app_loading(self) -> None:
|
||||
# If any traceback dumps happened last run, log and clear them.
|
||||
log_dumped_app_state()
|
||||
log_dumped_app_state(from_previous_run=True)
|
||||
|
||||
def _app_monitor_thread_main(self) -> None:
|
||||
_babase.set_thread_name('ballistica app-monitor')
|
||||
|
||||
@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
||||
from typing import Callable
|
||||
|
||||
|
||||
DEBUG_LOG = _babase.temp_testing()
|
||||
DEBUG_LOG = False
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@ -24,6 +24,8 @@ if TYPE_CHECKING:
|
||||
# instead of these or to make the meta system aware of arbitrary classes.
|
||||
EXPORT_CLASS_NAME_SHORTCUTS: dict[str, str] = {
|
||||
'plugin': 'babase.Plugin',
|
||||
# DEPRECATED as of 12/2023. Currently am warning if finding these
|
||||
# but should take this out eventually.
|
||||
'keyboard': 'babase.Keyboard',
|
||||
}
|
||||
|
||||
@ -414,30 +416,27 @@ class DirectoryScan:
|
||||
if export_class_name is not None:
|
||||
classname = modulename + '.' + export_class_name
|
||||
|
||||
# Since we'll soon have multiple versions of 'game'
|
||||
# classes we need to migrate people to using base
|
||||
# class names for them.
|
||||
if exporttypestr == 'game':
|
||||
# Migrating away from the 'keyboard' name shortcut
|
||||
# since it's specific to bauiv1; warn if we find it.
|
||||
if exporttypestr == 'keyboard':
|
||||
logging.warning(
|
||||
"metascan: %s:%d: '# ba_meta export"
|
||||
" game' tag should be replaced by '# ba_meta"
|
||||
" export bascenev1.GameActivity'.",
|
||||
" keyboard' tag should be replaced by '# ba_meta"
|
||||
" export bauiv1.Keyboard'.",
|
||||
subpath,
|
||||
lindex + 1,
|
||||
)
|
||||
self.results.announce_errors_occurred = True
|
||||
else:
|
||||
# If export type is one of our shortcuts, sub in the
|
||||
# actual class path. Otherwise assume its a classpath
|
||||
# itself.
|
||||
exporttype = EXPORT_CLASS_NAME_SHORTCUTS.get(
|
||||
exporttypestr
|
||||
)
|
||||
if exporttype is None:
|
||||
exporttype = exporttypestr
|
||||
self.results.exports.setdefault(exporttype, []).append(
|
||||
classname
|
||||
)
|
||||
|
||||
# If export type is one of our shortcuts, sub in the
|
||||
# actual class path. Otherwise assume its a classpath
|
||||
# itself.
|
||||
exporttype = EXPORT_CLASS_NAME_SHORTCUTS.get(exporttypestr)
|
||||
if exporttype is None:
|
||||
exporttype = exporttypestr
|
||||
self.results.exports.setdefault(exporttype, []).append(
|
||||
classname
|
||||
)
|
||||
|
||||
def _get_export_class_name(
|
||||
self, subpath: Path, lines: list[str], lindex: int
|
||||
|
||||
@ -97,7 +97,7 @@ class AdsSubsystem:
|
||||
show = True
|
||||
|
||||
# No ads without net-connections, etc.
|
||||
if not bauiv1.can_show_ad():
|
||||
if not plus.can_show_ad():
|
||||
show = False
|
||||
if classic.accounts.have_pro():
|
||||
show = False # Pro disables interstitials.
|
||||
@ -135,7 +135,7 @@ class AdsSubsystem:
|
||||
# ad-show-threshold and see if we should *actually* show
|
||||
# (we reach our threshold faster the longer we've been
|
||||
# playing).
|
||||
base = 'ads' if bauiv1.has_video_ads() else 'ads2'
|
||||
base = 'ads' if plus.has_video_ads() else 'ads2'
|
||||
min_lc = plus.get_v1_account_misc_read_val(base + '.minLC', 0.0)
|
||||
max_lc = plus.get_v1_account_misc_read_val(base + '.maxLC', 5.0)
|
||||
min_lc_scale = plus.get_v1_account_misc_read_val(
|
||||
|
||||
@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21700
|
||||
TARGET_BALLISTICA_BUILD = 21707
|
||||
TARGET_BALLISTICA_VERSION = '1.7.31'
|
||||
|
||||
|
||||
|
||||
@ -249,3 +249,18 @@ class PlusSubsystem(AppSubsystem):
|
||||
) -> None:
|
||||
"""(internal)"""
|
||||
return _baplus.tournament_query(callback, args)
|
||||
|
||||
@staticmethod
|
||||
def have_incentivized_ad() -> bool:
|
||||
"""Is an incentivized ad available?"""
|
||||
return _baplus.have_incentivized_ad()
|
||||
|
||||
@staticmethod
|
||||
def has_video_ads() -> bool:
|
||||
"""Are video ads available?"""
|
||||
return _baplus.has_video_ads()
|
||||
|
||||
@staticmethod
|
||||
def can_show_ad() -> bool:
|
||||
"""Can we show an ad?"""
|
||||
return _baplus.can_show_ad()
|
||||
|
||||
@ -78,6 +78,7 @@ from _bascenev1 import (
|
||||
end_host_scanning,
|
||||
get_chat_messages,
|
||||
get_connection_to_host_info,
|
||||
get_connection_to_host_info_2,
|
||||
get_foreground_host_activity,
|
||||
get_foreground_host_session,
|
||||
get_game_port,
|
||||
@ -202,6 +203,7 @@ from bascenev1._multiteamsession import (
|
||||
DEFAULT_TEAM_NAMES,
|
||||
)
|
||||
from bascenev1._music import MusicType, setmusic
|
||||
from bascenev1._net import HostInfo
|
||||
from bascenev1._nodeactor import NodeActor
|
||||
from bascenev1._powerup import get_default_powerup_distribution
|
||||
from bascenev1._profile import (
|
||||
@ -303,6 +305,7 @@ __all__ = [
|
||||
'GameTip',
|
||||
'get_chat_messages',
|
||||
'get_connection_to_host_info',
|
||||
'get_connection_to_host_info_2',
|
||||
'get_default_free_for_all_playlist',
|
||||
'get_default_teams_playlist',
|
||||
'get_default_powerup_distribution',
|
||||
@ -338,6 +341,7 @@ __all__ = [
|
||||
'have_connected_clients',
|
||||
'have_touchscreen_input',
|
||||
'HitMessage',
|
||||
'HostInfo',
|
||||
'host_scan_cycle',
|
||||
'ImpactDamageMessage',
|
||||
'increment_analytics_count',
|
||||
|
||||
24
src/assets/ba_data/python/bascenev1/_net.py
Normal file
24
src/assets/ba_data/python/bascenev1/_net.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Functionality related to net play."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class HostInfo:
|
||||
"""Info about a host."""
|
||||
|
||||
name: str
|
||||
build_number: int
|
||||
|
||||
# Note this can be None for non-ip hosts such as bluetooth.
|
||||
address: str | None
|
||||
|
||||
# Note this can be None for non-ip hosts such as bluetooth.
|
||||
port: int | None
|
||||
@ -62,7 +62,6 @@ from babase import (
|
||||
is_browser_likely_available,
|
||||
is_running_on_fire_tv,
|
||||
is_xcode_build,
|
||||
Keyboard,
|
||||
lock_all_input,
|
||||
LoginAdapter,
|
||||
LoginInfo,
|
||||
@ -94,7 +93,6 @@ from babase import (
|
||||
|
||||
from _bauiv1 import (
|
||||
buttonwidget,
|
||||
can_show_ad,
|
||||
checkboxwidget,
|
||||
columnwidget,
|
||||
containerwidget,
|
||||
@ -103,8 +101,6 @@ from _bauiv1 import (
|
||||
getmesh,
|
||||
getsound,
|
||||
gettexture,
|
||||
has_video_ads,
|
||||
have_incentivized_ad,
|
||||
hscrollwidget,
|
||||
imagewidget,
|
||||
is_party_icon_visible,
|
||||
@ -125,6 +121,7 @@ from _bauiv1 import (
|
||||
Widget,
|
||||
widget,
|
||||
)
|
||||
from bauiv1._keyboard import Keyboard
|
||||
from bauiv1._uitypes import Window, uicleanupcheck
|
||||
from bauiv1._subsystem import UIV1Subsystem
|
||||
|
||||
@ -144,7 +141,6 @@ __all__ = [
|
||||
'AppTimer',
|
||||
'buttonwidget',
|
||||
'Call',
|
||||
'can_show_ad',
|
||||
'fullscreen_control_available',
|
||||
'fullscreen_control_get',
|
||||
'fullscreen_control_key_shortcut',
|
||||
@ -178,8 +174,6 @@ __all__ = [
|
||||
'getmesh',
|
||||
'getsound',
|
||||
'gettexture',
|
||||
'has_video_ads',
|
||||
'have_incentivized_ad',
|
||||
'have_permission',
|
||||
'hscrollwidget',
|
||||
'imagewidget',
|
||||
|
||||
@ -12,6 +12,7 @@ from typing import TYPE_CHECKING
|
||||
import babase
|
||||
|
||||
import _bauiv1
|
||||
from bauiv1._keyboard import Keyboard
|
||||
from bauiv1._uitypes import Window
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -252,9 +253,7 @@ class OnScreenKeyboardWindow(Window):
|
||||
# Show change instructions only if we have more than one
|
||||
# keyboard option.
|
||||
keyboards = (
|
||||
babase.app.meta.scanresults.exports_of_class(
|
||||
babase.Keyboard
|
||||
)
|
||||
babase.app.meta.scanresults.exports_of_class(Keyboard)
|
||||
if babase.app.meta.scanresults is not None
|
||||
else []
|
||||
)
|
||||
@ -286,10 +285,10 @@ class OnScreenKeyboardWindow(Window):
|
||||
|
||||
def _get_keyboard(self) -> bui.Keyboard:
|
||||
assert babase.app.meta.scanresults is not None
|
||||
classname = babase.app.meta.scanresults.exports_of_class(
|
||||
babase.Keyboard
|
||||
)[self._keyboard_index]
|
||||
kbclass = babase.getclass(classname, babase.Keyboard)
|
||||
classname = babase.app.meta.scanresults.exports_of_class(Keyboard)[
|
||||
self._keyboard_index
|
||||
]
|
||||
kbclass = babase.getclass(classname, Keyboard)
|
||||
return kbclass()
|
||||
|
||||
def _refresh(self) -> None:
|
||||
@ -384,9 +383,7 @@ class OnScreenKeyboardWindow(Window):
|
||||
|
||||
def _next_keyboard(self) -> None:
|
||||
assert babase.app.meta.scanresults is not None
|
||||
kbexports = babase.app.meta.scanresults.exports_of_class(
|
||||
babase.Keyboard
|
||||
)
|
||||
kbexports = babase.app.meta.scanresults.exports_of_class(Keyboard)
|
||||
self._keyboard_index = (self._keyboard_index + 1) % len(kbexports)
|
||||
|
||||
self._load_keyboard()
|
||||
|
||||
@ -415,7 +415,7 @@ class CoopBrowserWindow(bui.Window):
|
||||
)
|
||||
|
||||
# Decrement time on our tournament buttons.
|
||||
ads_enabled = bui.have_incentivized_ad()
|
||||
ads_enabled = plus.have_incentivized_ad()
|
||||
for tbtn in self._tournament_buttons:
|
||||
tbtn.time_remaining = max(0, tbtn.time_remaining - 1)
|
||||
if tbtn.time_remaining_value_text is not None:
|
||||
@ -430,7 +430,7 @@ class CoopBrowserWindow(bui.Window):
|
||||
)
|
||||
|
||||
# Also adjust the ad icon visibility.
|
||||
if tbtn.allow_ads and bui.has_video_ads():
|
||||
if tbtn.allow_ads and plus.has_video_ads():
|
||||
bui.imagewidget(
|
||||
edit=tbtn.entry_fee_ad_image,
|
||||
opacity=1.0 if ads_enabled else 0.25,
|
||||
|
||||
@ -638,8 +638,8 @@ class TournamentButton:
|
||||
|
||||
# Now, if this fee allows ads and we support video ads, show
|
||||
# the 'or ad' version.
|
||||
if allow_ads and bui.has_video_ads():
|
||||
ads_enabled = bui.have_incentivized_ad()
|
||||
if allow_ads and plus.has_video_ads():
|
||||
ads_enabled = plus.have_incentivized_ad()
|
||||
bui.imagewidget(
|
||||
edit=self.entry_fee_ad_image,
|
||||
opacity=1.0 if ads_enabled else 0.25,
|
||||
|
||||
@ -334,7 +334,7 @@ class GetCurrencyWindow(bui.Window):
|
||||
tex_scale=1.2,
|
||||
) # 19.99-ish
|
||||
|
||||
self._enable_ad_button = bui.has_video_ads()
|
||||
self._enable_ad_button = plus.has_video_ads()
|
||||
h = self._width * 0.5 + 110.0
|
||||
v = self._height - b_size[1] - 115.0
|
||||
|
||||
@ -561,7 +561,7 @@ class GetCurrencyWindow(bui.Window):
|
||||
next_reward_ad_time
|
||||
)
|
||||
now = datetime.datetime.utcnow()
|
||||
if bui.have_incentivized_ad() and (
|
||||
if plus.have_incentivized_ad() and (
|
||||
next_reward_ad_time is None or next_reward_ad_time <= now
|
||||
):
|
||||
self._ad_button_greyed = False
|
||||
|
||||
@ -9,7 +9,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import babase
|
||||
import bauiv1 as bui
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Iterable
|
||||
@ -33,15 +33,15 @@ def split(chars: Iterable[str], maxlen: int) -> list[list[str]]:
|
||||
|
||||
|
||||
def generate_emojis(maxlen: int) -> list[list[str]]:
|
||||
"""Generates a lot of UTF8 emojis prepared for babase.Keyboard pages"""
|
||||
"""Generates a lot of UTF8 emojis prepared for bui.Keyboard pages"""
|
||||
all_emojis = split([chr(i) for i in range(0x1F601, 0x1F650)], maxlen)
|
||||
all_emojis += split([chr(i) for i in range(0x2702, 0x27B1)], maxlen)
|
||||
all_emojis += split([chr(i) for i in range(0x1F680, 0x1F6C1)], maxlen)
|
||||
return all_emojis
|
||||
|
||||
|
||||
# ba_meta export keyboard
|
||||
class EnglishKeyboard(babase.Keyboard):
|
||||
# ba_meta export bauiv1.Keyboard
|
||||
class EnglishKeyboard(bui.Keyboard):
|
||||
"""Default English keyboard."""
|
||||
|
||||
name = 'English'
|
||||
|
||||
@ -92,9 +92,10 @@ class PartyWindow(bui.Window):
|
||||
iconscale=1.2,
|
||||
)
|
||||
|
||||
info = bs.get_connection_to_host_info()
|
||||
if info.get('name', '') != '':
|
||||
title = bui.Lstr(value=info['name'])
|
||||
info = bs.get_connection_to_host_info_2()
|
||||
|
||||
if info is not None and info.name != '':
|
||||
title = bui.Lstr(value=info.name)
|
||||
else:
|
||||
title = bui.Lstr(resource=self._r + '.titleText')
|
||||
|
||||
@ -481,7 +482,8 @@ class PartyWindow(bui.Window):
|
||||
kick_str = bui.Lstr(resource='kickText')
|
||||
else:
|
||||
# kick-votes appeared in build 14248
|
||||
if bs.get_connection_to_host_info().get('build_number', 0) < 14248:
|
||||
info = bs.get_connection_to_host_info_2()
|
||||
if info is None or info.build_number < 14248:
|
||||
return
|
||||
kick_str = bui.Lstr(resource='kickVoteText')
|
||||
assert bui.app.classic is not None
|
||||
|
||||
@ -34,6 +34,7 @@ class TournamentEntryWindow(PopupWindow):
|
||||
# pylint: disable=too-many-statements
|
||||
|
||||
assert bui.app.classic is not None
|
||||
assert bui.app.plus
|
||||
bui.set_analytics_screen('Tournament Entry Window')
|
||||
|
||||
self._tournament_id = tournament_id
|
||||
@ -100,7 +101,7 @@ class TournamentEntryWindow(PopupWindow):
|
||||
self._launched = False
|
||||
|
||||
# Show the ad button only if we support ads *and* it has a level 1 fee.
|
||||
self._do_ad_btn = bui.has_video_ads() and self._allow_ads
|
||||
self._do_ad_btn = bui.app.plus.has_video_ads() and self._allow_ads
|
||||
|
||||
x_offs = 0 if self._do_ad_btn else 85
|
||||
|
||||
@ -477,7 +478,7 @@ class TournamentEntryWindow(PopupWindow):
|
||||
)
|
||||
|
||||
if self._do_ad_btn:
|
||||
enabled = bui.have_incentivized_ad()
|
||||
enabled = plus.have_incentivized_ad()
|
||||
have_ad_tries_remaining = (
|
||||
self._tournament_info['adTriesRemaining'] is not None
|
||||
and self._tournament_info['adTriesRemaining'] > 0
|
||||
|
||||
@ -195,6 +195,12 @@ void BaseFeatureSet::OnAssetsAvailable() {
|
||||
}
|
||||
|
||||
void BaseFeatureSet::StartApp() {
|
||||
// {
|
||||
// // TEST - recreate the ID python dumps in its thread tracebacks.
|
||||
// auto val = PyThread_get_thread_ident();
|
||||
// printf("MAIN THREAD IS %#018lx\n", val);
|
||||
// }
|
||||
|
||||
BA_PRECONDITION(g_core->InMainThread());
|
||||
BA_PRECONDITION(g_base);
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ void Networking::SendTo(const std::vector<uint8_t>& buffer,
|
||||
if (sd != -1) {
|
||||
sendto(sd, (const char*)&buffer[0],
|
||||
static_cast_check_fit<socket_send_length_t>(buffer.size()), 0,
|
||||
addr.GetSockAddr(), addr.GetSockAddrLen());
|
||||
addr.AsSockAddr(), addr.GetSockAddrLen());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -58,8 +58,8 @@ auto BasePlatform::GetPublicDeviceUUID() -> std::string {
|
||||
// We used to plug version in directly here, but that caused uuids to
|
||||
// shuffle too rapidly during periods of rapid development. This
|
||||
// keeps it more constant.
|
||||
// __last_rand_uuid_component_shuffle_date__ 2023 6 15
|
||||
auto rand_uuid_component{"JVRWZ82D4WMBO110OA0IFJV7JKMQV8W3"};
|
||||
// __last_rand_uuid_component_shuffle_date__ 2023 12 13
|
||||
auto rand_uuid_component{"7YM96RZHN6ZCPZGTQONULZO1JU5NMMC7"};
|
||||
|
||||
inputs.emplace_back(rand_uuid_component);
|
||||
auto gil{Python::ScopedInterpreterLock()};
|
||||
|
||||
@ -368,12 +368,64 @@ void CoreFeatureSet::StartSuicideTimer(const std::string& action,
|
||||
}
|
||||
}
|
||||
|
||||
// auto CoreFeatureSet::InMainThread() -> bool {
|
||||
// return std::this_thread::get_id() == main_thread_id;
|
||||
// // if (main_event_loop_) {
|
||||
// // return main_event_loop_->ThreadIsCurrent();
|
||||
// // }
|
||||
// // return false;
|
||||
// }
|
||||
void CoreFeatureSet::RegisterThread(const std::string& name) {
|
||||
{
|
||||
std::scoped_lock lock(thread_info_map_mutex_);
|
||||
|
||||
// Should be registering each thread just once.
|
||||
assert(thread_info_map_.find(std::this_thread::get_id())
|
||||
== thread_info_map_.end());
|
||||
thread_info_map_[std::this_thread::get_id()] = name;
|
||||
}
|
||||
|
||||
// Also set the name at the OS leve when possible. Prepend 'ballistica'
|
||||
// since there's generally lots of other random threads in the mix.
|
||||
//
|
||||
// Note that we currently don't do this for our main thread because (on
|
||||
// Linux at least) that changes the process name we see in top/etc. On
|
||||
// other platforms we could reconsider, but its generally clear what the
|
||||
// main thread is anyway in most scenarios.
|
||||
if (!InMainThread()) {
|
||||
g_core->platform->SetCurrentThreadName("ballistica " + name);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreFeatureSet::UnregisterThread() {
|
||||
std::scoped_lock lock(thread_info_map_mutex_);
|
||||
auto i = thread_info_map_.find(std::this_thread::get_id());
|
||||
assert(i != thread_info_map_.end());
|
||||
if (i != thread_info_map_.end()) {
|
||||
thread_info_map_.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
auto CoreFeatureSet::CurrentThreadName() -> std::string {
|
||||
if (g_core == nullptr) {
|
||||
return "unknown(not-yet-inited)";
|
||||
}
|
||||
{
|
||||
std::scoped_lock lock(g_core->thread_info_map_mutex_);
|
||||
auto i = g_core->thread_info_map_.find(std::this_thread::get_id());
|
||||
if (i != g_core->thread_info_map_.end()) {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Ask pthread for the thread name if we don't have one.
|
||||
// FIXME - move this to platform.
|
||||
#if BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS || BA_OSTYPE_LINUX
|
||||
std::string name = "unknown (sys-name=";
|
||||
char buffer[256];
|
||||
int result = pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
|
||||
if (result == 0) {
|
||||
name += std::string("\"") + buffer + "\")";
|
||||
} else {
|
||||
name += "<error " + std::to_string(result) + ">";
|
||||
}
|
||||
return name;
|
||||
#else
|
||||
return "unknown";
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ballistica::core
|
||||
|
||||
@ -144,6 +144,12 @@ class CoreFeatureSet {
|
||||
return using_custom_app_python_dir_;
|
||||
}
|
||||
|
||||
/// Register various info about the current thread.
|
||||
void RegisterThread(const std::string& name);
|
||||
|
||||
/// Should be called by a thread before it exits.
|
||||
void UnregisterThread();
|
||||
|
||||
// Subsystems.
|
||||
CorePython* const python;
|
||||
CorePlatform* const platform;
|
||||
@ -158,8 +164,6 @@ class CoreFeatureSet {
|
||||
bool v1_cloud_log_full{};
|
||||
int master_server_source{};
|
||||
std::vector<EventLoop*> suspendable_event_loops;
|
||||
std::mutex thread_name_map_mutex;
|
||||
std::unordered_map<std::thread::id, std::string> thread_name_map;
|
||||
std::mutex v1_cloud_log_mutex;
|
||||
std::string v1_cloud_log;
|
||||
|
||||
@ -173,6 +177,7 @@ class CoreFeatureSet {
|
||||
auto vr_mode() const { return vr_mode_; }
|
||||
auto event_loops_suspended() const { return event_loops_suspended_; }
|
||||
void set_event_loops_suspended(bool val) { event_loops_suspended_ = val; }
|
||||
static auto CurrentThreadName() -> std::string;
|
||||
|
||||
private:
|
||||
explicit CoreFeatureSet(CoreConfig config);
|
||||
@ -204,6 +209,8 @@ class CoreFeatureSet {
|
||||
std::optional<std::string> ba_env_user_python_dir_;
|
||||
std::optional<std::string> ba_env_site_python_dir_;
|
||||
std::string ba_env_data_dir_;
|
||||
std::mutex thread_info_map_mutex_;
|
||||
std::unordered_map<std::thread::id, std::string> thread_info_map_;
|
||||
};
|
||||
|
||||
} // namespace ballistica::core
|
||||
|
||||
@ -466,7 +466,7 @@ auto CorePlatformApple::CanShowBlockingFatalErrorDialog() -> bool {
|
||||
if (g_buildconfig.xcode_build() && g_buildconfig.ostype_macos()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return CorePlatform::CanShowBlockingFatalErrorDialog();
|
||||
}
|
||||
|
||||
void CorePlatformApple::BlockingFatalErrorDialog(const std::string& message) {
|
||||
|
||||
@ -826,11 +826,9 @@ auto CorePlatform::MacMusicAppGetPlaylists() -> std::list<std::string> {
|
||||
}
|
||||
|
||||
void CorePlatform::SetCurrentThreadName(const std::string& name) {
|
||||
// Currently we leave the main thread alone, otherwise we show up as
|
||||
// "BallisticaMainThread" under "top" on linux (should check other platforms).
|
||||
if (g_core->InMainThread()) {
|
||||
return;
|
||||
}
|
||||
// We should never be doing this for the main thread.
|
||||
BA_PRECONDITION_FATAL(!g_core->InMainThread());
|
||||
|
||||
#if BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS
|
||||
pthread_setname_np(name.c_str());
|
||||
#elif BA_OSTYPE_LINUX || BA_OSTYPE_ANDROID
|
||||
|
||||
@ -18,7 +18,7 @@ auto ConnectionToHostUDP::SwitchProtocol() -> bool {
|
||||
|
||||
// Need a new request id so we ignore further responses to our previous
|
||||
// requests.
|
||||
GetRequestID();
|
||||
GetRequestID_();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -32,7 +32,7 @@ ConnectionToHostUDP::ConnectionToHostUDP(const SockAddr& addr)
|
||||
did_die_(false),
|
||||
last_host_response_time_millisecs_(
|
||||
static_cast<millisecs_t>(g_base->logic->display_time() * 1000.0)) {
|
||||
GetRequestID();
|
||||
GetRequestID_();
|
||||
if (auto* appmode = SceneV1AppMode::GetActiveOrWarn()) {
|
||||
if (appmode->connections()->GetPrintUDPConnectProgress()) {
|
||||
ScreenMessage(g_base->assets->GetResourceString("connectingToPartyText"));
|
||||
@ -46,11 +46,11 @@ ConnectionToHostUDP::~ConnectionToHostUDP() {
|
||||
set_connection_dying(true);
|
||||
}
|
||||
|
||||
void ConnectionToHostUDP::GetRequestID() {
|
||||
void ConnectionToHostUDP::GetRequestID_() {
|
||||
// We store a unique-ish request ID to minimize the chance that data for
|
||||
// previous connections/etc will muck with us.
|
||||
// Try to start this value at something that won't be common in packets to
|
||||
// minimize chance of garbage packets causing trouble.
|
||||
// previous connections/etc will muck with us. Try to start this value at
|
||||
// something that won't be common in packets to minimize chance of garbage
|
||||
// packets causing trouble.
|
||||
static auto next_request_id =
|
||||
static_cast<uint8_t>(71 + (rand() % 151)); // NOLINT
|
||||
request_id_ = next_request_id++;
|
||||
@ -95,13 +95,14 @@ void ConnectionToHostUDP::Update() {
|
||||
{1, 0, 0});
|
||||
}
|
||||
|
||||
// Die immediately in this case; no use trying to wait for a disconnect-ack
|
||||
// since we've already given up hope of hearing from them.
|
||||
// Die immediately in this case; no use trying to wait for a
|
||||
// disconnect-ack since we've already given up hope of hearing from
|
||||
// them.
|
||||
Die();
|
||||
return;
|
||||
} else if (errored()) {
|
||||
// If we've errored, keep sending disconnect-requests periodically.
|
||||
// Once we get a response (or time out in the above code) we'll die.
|
||||
// If we've errored, keep sending disconnect-requests periodically. Once
|
||||
// we get a response (or time out in the above code) we'll die.
|
||||
if (current_time_millisecs - last_disconnect_request_time_ > 1000) {
|
||||
last_disconnect_request_time_ = current_time_millisecs;
|
||||
|
||||
@ -189,8 +190,8 @@ void ConnectionToHostUDP::Error(const std::string& msg) {
|
||||
auto ConnectionToHostUDP::GetAsUDP() -> ConnectionToHostUDP* { return this; }
|
||||
|
||||
void ConnectionToHostUDP::RequestDisconnect() {
|
||||
// Mark us as errored so all future communication results in more disconnect
|
||||
// requests.
|
||||
// Mark us as errored so all future communication results in more
|
||||
// disconnect requests.
|
||||
set_errored(true);
|
||||
if (client_id_ != -1) {
|
||||
SendDisconnectRequest();
|
||||
|
||||
@ -23,8 +23,8 @@ class ConnectionToHostUDP : public ConnectionToHost {
|
||||
void set_client_id(int val) { client_id_ = val; }
|
||||
auto client_id() const -> int { return client_id_; }
|
||||
|
||||
// Attempt connecting via a different protocol. If none are left to try,
|
||||
// returns false.
|
||||
/// Attempt connecting via a different protocol. If none are left to try,
|
||||
/// returns false.
|
||||
auto SwitchProtocol() -> bool;
|
||||
void RequestDisconnect() override;
|
||||
|
||||
@ -32,16 +32,18 @@ class ConnectionToHostUDP : public ConnectionToHost {
|
||||
void Error(const std::string& error_msg) override;
|
||||
void Die();
|
||||
void SendDisconnectRequest();
|
||||
const auto& addr() const { return *addr_; }
|
||||
|
||||
private:
|
||||
void GetRequestID();
|
||||
uint8_t request_id_{};
|
||||
std::unique_ptr<SockAddr> addr_;
|
||||
void GetRequestID_();
|
||||
|
||||
bool did_die_{};
|
||||
uint8_t request_id_{};
|
||||
int client_id_{};
|
||||
millisecs_t last_client_id_request_time_{};
|
||||
millisecs_t last_disconnect_request_time_{};
|
||||
int client_id_{};
|
||||
millisecs_t last_host_response_time_millisecs_{};
|
||||
std::unique_ptr<SockAddr> addr_;
|
||||
};
|
||||
|
||||
} // namespace ballistica::scene_v1
|
||||
|
||||
@ -5,13 +5,17 @@
|
||||
#include "ballistica/base/assets/assets.h"
|
||||
#include "ballistica/base/networking/network_reader.h"
|
||||
#include "ballistica/base/python/base_python.h"
|
||||
#include "ballistica/core/python/core_python.h"
|
||||
#include "ballistica/scene_v1/connection/connection_set.h"
|
||||
#include "ballistica/scene_v1/connection/connection_to_client.h"
|
||||
#include "ballistica/scene_v1/connection/connection_to_host.h"
|
||||
#include "ballistica/scene_v1/connection/connection_to_host_udp.h"
|
||||
#include "ballistica/scene_v1/python/scene_v1_python.h"
|
||||
#include "ballistica/scene_v1/support/scene_v1_app_mode.h"
|
||||
#include "ballistica/shared/math/vector3f.h"
|
||||
#include "ballistica/shared/networking/sockaddr.h"
|
||||
#include "ballistica/shared/python/python.h"
|
||||
#include "ballistica/shared/python/python_ref.h"
|
||||
#include "ballistica/shared/python/python_sys.h"
|
||||
|
||||
namespace ballistica::scene_v1 {
|
||||
@ -20,8 +24,7 @@ namespace ballistica::scene_v1 {
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
|
||||
|
||||
// ------------------------- get_public_party_enabled
|
||||
// ---------------------------
|
||||
// ----------------------- get_public_party_enabled ---------------------------
|
||||
|
||||
static auto PyGetPublicPartyEnabled(PyObject* self, PyObject* args,
|
||||
PyObject* keywds) -> PyObject* {
|
||||
@ -411,7 +414,10 @@ static auto PyGetConnectionToHostInfo(PyObject* self, PyObject* args,
|
||||
const_cast<char**>(kwlist))) {
|
||||
return nullptr;
|
||||
}
|
||||
// Error if we're not in our app-mode.
|
||||
BA_LOG_ONCE(LogLevel::kWarning,
|
||||
"bascenev1.get_connection_to_host_info() is deprecated; use "
|
||||
"bascenev1.get_connection_to_host_info_2().");
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* appmode = SceneV1AppMode::GetActiveOrThrow();
|
||||
|
||||
ConnectionToHost* hc = appmode->connections()->connection_to_host();
|
||||
@ -435,6 +441,57 @@ static PyMethodDef PyGetConnectionToHostInfoDef = {
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// --------------------- get_connection_to_host_info_2 -------------------------
|
||||
|
||||
static auto PyGetConnectionToHostInfo2(PyObject* self, PyObject* args,
|
||||
PyObject* keywds) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
static const char* kwlist[] = {nullptr};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "",
|
||||
const_cast<char**>(kwlist))) {
|
||||
return nullptr;
|
||||
}
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* appmode = SceneV1AppMode::GetActiveOrThrow();
|
||||
|
||||
ConnectionToHost* hc = appmode->connections()->connection_to_host();
|
||||
if (hc) {
|
||||
PythonRef addr_obj;
|
||||
PythonRef port_obj;
|
||||
if (ConnectionToHostUDP* hcu = dynamic_cast<ConnectionToHostUDP*>(hc)) {
|
||||
addr_obj.Steal(PyUnicode_FromString(hcu->addr().AddressString().c_str()));
|
||||
port_obj.Steal(PyLong_FromLong(hcu->addr().Port()));
|
||||
} else {
|
||||
addr_obj.Acquire(Py_None);
|
||||
port_obj.Acquire(Py_None);
|
||||
}
|
||||
auto args =
|
||||
g_core->python->objs().Get(core::CorePython::ObjID::kEmptyTuple);
|
||||
auto keywds = PythonRef::Stolen(Py_BuildValue(
|
||||
"{sssisOsO}", "name", hc->party_name().c_str(), "build_number",
|
||||
hc->build_number(), "address", addr_obj.Get(), "port", port_obj.Get()));
|
||||
auto result = g_scene_v1->python->objs()
|
||||
.Get(SceneV1Python::ObjID::kHostInfoClass)
|
||||
.Call(args, keywds);
|
||||
if (!result.Exists()) {
|
||||
throw Exception("Failed to instantiate HostInfo.", PyExcType::kRuntime);
|
||||
}
|
||||
return result.HandOver();
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyGetConnectionToHostInfo2Def = {
|
||||
"get_connection_to_host_info_2", // name
|
||||
(PyCFunction)PyGetConnectionToHostInfo2, // method
|
||||
METH_VARARGS | METH_KEYWORDS, // flags
|
||||
|
||||
"get_connection_to_host_info_2() -> bascenev1.HostInfo | None\n"
|
||||
"\n"
|
||||
"Return info about the host we are currently connected to.",
|
||||
};
|
||||
|
||||
// --------------------------- disconnect_from_host ----------------------------
|
||||
|
||||
static auto PyDisconnectFromHost(PyObject* self, PyObject* args,
|
||||
@ -701,6 +758,7 @@ static auto PyChatMessage(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
&clients_obj, &sender_override_obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
auto* appmode = SceneV1AppMode::GetActiveOrThrow();
|
||||
|
||||
message = g_base->python->GetPyLString(message_obj);
|
||||
@ -775,6 +833,7 @@ auto PythonMethodsNetworking::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyDisconnectClientDef,
|
||||
PyGetClientPublicDeviceUUIDDef,
|
||||
PyGetConnectionToHostInfoDef,
|
||||
PyGetConnectionToHostInfo2Def,
|
||||
PyClientInfoQueryResponseDef,
|
||||
PyConnectToPartyDef,
|
||||
PySetAuthenticateClientsDef,
|
||||
|
||||
@ -91,6 +91,7 @@ class SceneV1Python {
|
||||
kGetPlayerIconCall,
|
||||
kFilterChatMessageCall,
|
||||
kHandleLocalChatMessageCall,
|
||||
kHostInfoClass,
|
||||
kLast // Sentinel; must be at end.
|
||||
};
|
||||
|
||||
|
||||
@ -37,21 +37,16 @@ class ClientSessionNet : public ClientSession {
|
||||
auto GetBucketNum() -> int;
|
||||
|
||||
bool writing_replay_{};
|
||||
int delay_sample_counter_{};
|
||||
float max_delay_smoothed_{};
|
||||
float last_bucket_max_delay_{};
|
||||
float current_delay_{};
|
||||
millisecs_t base_time_received_{};
|
||||
millisecs_t last_base_time_receive_time_{};
|
||||
millisecs_t leading_base_time_received_{};
|
||||
millisecs_t leading_base_time_receive_time_{};
|
||||
Object::WeakRef<ConnectionToHost> connection_to_host_;
|
||||
std::vector<SampleBucket> buckets_{5};
|
||||
|
||||
// float bucket_max_smoothed_{};
|
||||
// float bucket_min_smoothed_{};
|
||||
float max_delay_smoothed_{};
|
||||
float last_bucket_max_delay_{};
|
||||
float current_delay_{};
|
||||
|
||||
int delay_sample_counter_{};
|
||||
// int adjust_counter_{};
|
||||
};
|
||||
|
||||
} // namespace ballistica::scene_v1
|
||||
|
||||
@ -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 = 21700;
|
||||
const int kEngineBuildNumber = 21707;
|
||||
const char* kEngineVersion = "1.7.31";
|
||||
const int kEngineApiVersion = 8;
|
||||
|
||||
@ -290,7 +290,7 @@ void ScreenMessage(const std::string& msg) {
|
||||
auto CurrentThreadName() -> std::string {
|
||||
// Currently just ask event-loop for this but perhaps should be talking
|
||||
// more directly to the OS/etc. to cover more cases.
|
||||
return EventLoop::CurrentThreadName();
|
||||
return core::CoreFeatureSet::CurrentThreadName();
|
||||
}
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -98,21 +98,6 @@ EventLoop::EventLoop(EventLoopID identifier_in, ThreadSource source)
|
||||
}
|
||||
}
|
||||
|
||||
void EventLoop::SetInternalThreadName_(const std::string& name) {
|
||||
assert(g_core);
|
||||
std::scoped_lock lock(g_core->thread_name_map_mutex);
|
||||
g_core->thread_name_map[std::this_thread::get_id()] = name;
|
||||
}
|
||||
|
||||
void EventLoop::ClearCurrentThreadName() {
|
||||
assert(g_core);
|
||||
std::scoped_lock lock(g_core->thread_name_map_mutex);
|
||||
auto i = g_core->thread_name_map.find(std::this_thread::get_id());
|
||||
if (i != g_core->thread_name_map.end()) {
|
||||
g_core->thread_name_map.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
// These are all exactly the same; its just a way to try and clarify
|
||||
// in stack traces which thread is running in case it is not otherwise
|
||||
// evident.
|
||||
@ -341,53 +326,40 @@ void EventLoop::GetThreadMessages_(std::list<ThreadMessage_>* messages) {
|
||||
|
||||
void EventLoop::BootstrapThread_() {
|
||||
assert(!bootstrapped_);
|
||||
assert(g_core);
|
||||
thread_id_ = std::this_thread::get_id();
|
||||
const char* id_string;
|
||||
|
||||
switch (identifier_) {
|
||||
case EventLoopID::kLogic:
|
||||
name_ = "logic";
|
||||
id_string = "ballistica logic";
|
||||
break;
|
||||
case EventLoopID::kStdin:
|
||||
name_ = "stdin";
|
||||
id_string = "ballistica stdin";
|
||||
break;
|
||||
case EventLoopID::kAssets:
|
||||
name_ = "assets";
|
||||
id_string = "ballistica assets";
|
||||
break;
|
||||
case EventLoopID::kFileOut:
|
||||
name_ = "fileout";
|
||||
id_string = "ballistica file-out";
|
||||
break;
|
||||
case EventLoopID::kMain:
|
||||
name_ = "main";
|
||||
id_string = "ballistica main";
|
||||
break;
|
||||
case EventLoopID::kAudio:
|
||||
name_ = "audio";
|
||||
id_string = "ballistica audio";
|
||||
break;
|
||||
case EventLoopID::kBGDynamics:
|
||||
name_ = "bgdynamics";
|
||||
id_string = "ballistica bg-dynamics";
|
||||
break;
|
||||
case EventLoopID::kNetworkWrite:
|
||||
name_ = "networkwrite";
|
||||
id_string = "ballistica network-write";
|
||||
break;
|
||||
default:
|
||||
throw Exception();
|
||||
}
|
||||
assert(!name_.empty() && id_string);
|
||||
SetInternalThreadName_(name_);
|
||||
|
||||
// Note: we currently don't do this for our main thread because it
|
||||
// changes the process name we see in top/etc. Should look into that.
|
||||
if (identifier_ != EventLoopID::kMain) {
|
||||
g_core->platform->SetCurrentThreadName(id_string);
|
||||
}
|
||||
assert(!name_.empty());
|
||||
g_core->RegisterThread(name_);
|
||||
bootstrapped_ = true;
|
||||
}
|
||||
|
||||
@ -410,7 +382,7 @@ auto EventLoop::ThreadMain_() -> int {
|
||||
|
||||
RunToCompletion();
|
||||
|
||||
ClearCurrentThreadName();
|
||||
g_core->UnregisterThread();
|
||||
return 0;
|
||||
} catch (const std::exception& e) {
|
||||
auto error_msg = std::string("Unhandled exception in ")
|
||||
@ -622,35 +594,6 @@ void EventLoop::DeleteTimer(int id) {
|
||||
timers_.DeleteTimer(id);
|
||||
}
|
||||
|
||||
auto EventLoop::CurrentThreadName() -> std::string {
|
||||
if (g_core == nullptr) {
|
||||
return "unknown(not-yet-inited)";
|
||||
}
|
||||
{
|
||||
std::scoped_lock lock(g_core->thread_name_map_mutex);
|
||||
auto i = g_core->thread_name_map.find(std::this_thread::get_id());
|
||||
if (i != g_core->thread_name_map.end()) {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Ask pthread for the thread name if we don't have one.
|
||||
// FIXME - move this to platform.
|
||||
#if BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS || BA_OSTYPE_LINUX
|
||||
std::string name = "unknown (sys-name=";
|
||||
char buffer[256];
|
||||
int result = pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
|
||||
if (result == 0) {
|
||||
name += std::string("\"") + buffer + "\")";
|
||||
} else {
|
||||
name += "<error " + std::to_string(result) + ">";
|
||||
}
|
||||
return name;
|
||||
#else
|
||||
return "unknown";
|
||||
#endif
|
||||
}
|
||||
|
||||
void EventLoop::RunPendingRunnables_() {
|
||||
// Pull all runnables off the list first (its possible for one of these
|
||||
// runnables to add more) and then process them.
|
||||
|
||||
@ -25,10 +25,6 @@ class EventLoop {
|
||||
ThreadSource source = ThreadSource::kCreate);
|
||||
virtual ~EventLoop();
|
||||
|
||||
void ClearCurrentThreadName();
|
||||
|
||||
static auto CurrentThreadName() -> std::string;
|
||||
|
||||
static void SetEventLoopsSuspended(bool enable);
|
||||
static auto AreEventLoopsSuspended() -> bool;
|
||||
|
||||
@ -113,7 +109,6 @@ class EventLoop {
|
||||
: type(type), runnable(runnable), completion_flag{completion_flag} {}
|
||||
};
|
||||
auto CheckPushRunnableSafety_() -> bool;
|
||||
void SetInternalThreadName_(const std::string& name);
|
||||
void WaitForNextEvent_(bool single_cycle);
|
||||
void LogThreadMessageTally_(
|
||||
std::vector<std::pair<LogLevel, std::string>>* log_entries);
|
||||
|
||||
@ -91,12 +91,16 @@ void FatalError::ReportFatalError(const std::string& message,
|
||||
if (trace) {
|
||||
std::string tracestr = trace->FormatForDisplay();
|
||||
if (!tracestr.empty()) {
|
||||
logmsg += ("\nCPP-STACK-TRACE-BEGIN:\n" + tracestr
|
||||
+ "\nCPP-STACK-TRACE-END");
|
||||
logmsg +=
|
||||
(("\n----------------------- BALLISTICA-NATIVE-STACK-TRACE-BEGIN "
|
||||
"--------------------\n")
|
||||
+ tracestr
|
||||
+ ("\n----------------------- BALLISTICA-NATIVE-STACK-TRACE-END "
|
||||
"----------------------"));
|
||||
}
|
||||
delete trace;
|
||||
} else {
|
||||
logmsg += "\n(CPP-STACK-TRACE-UNAVAILABLE)";
|
||||
logmsg += "\n(BALLISTICA-NATIVE-STACK-TRACE-UNAVAILABLE)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,12 +159,10 @@ void FatalError::DoBlockingFatalErrorDialog(const std::string& message) {
|
||||
bool* startedptr{&started};
|
||||
bool* finishedptr{&finished};
|
||||
|
||||
// If our thread is holding the GIL, release it to give the main thread
|
||||
// a better chance of getting to the point of displaying the fatal
|
||||
// error.
|
||||
if (Python::HaveGIL()) {
|
||||
Python::PermanentlyReleaseGIL();
|
||||
}
|
||||
// If our thread is holding the GIL, release it while we spin; otherwise
|
||||
// we can wind up in deadlock if the main thread wants it.
|
||||
Python::ScopedInterpreterLockRelease gil_release;
|
||||
|
||||
g_base_soft->PushMainThreadRunnable(
|
||||
NewLambdaRunnableUnmanaged([message, startedptr, finishedptr] {
|
||||
*startedptr = true;
|
||||
|
||||
@ -14,22 +14,48 @@ SockAddr::SockAddr(const std::string& addr, int port) {
|
||||
if (result == 1) {
|
||||
auto* a = reinterpret_cast<sockaddr_in*>(&addr_);
|
||||
a->sin_family = AF_INET;
|
||||
a->sin_port = htons(port); // NOLINT
|
||||
a->sin_port = htons(port);
|
||||
a->sin_addr = addr_out;
|
||||
return;
|
||||
} else {
|
||||
struct in6_addr addr6Out {};
|
||||
result = inet_pton(AF_INET6, addr.c_str(), &addr6Out);
|
||||
struct in6_addr addr6_out {};
|
||||
result = inet_pton(AF_INET6, addr.c_str(), &addr6_out);
|
||||
if (result == 1) {
|
||||
auto* a = reinterpret_cast<sockaddr_in6*>(&addr_);
|
||||
a->sin6_family = AF_INET6;
|
||||
a->sin6_port = htons(port); // NOLINT
|
||||
a->sin6_addr = addr6Out;
|
||||
a->sin6_port = htons(port);
|
||||
a->sin6_addr = addr6_out;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw Exception("Invalid address: '" + addr + "'.");
|
||||
throw Exception("Invalid address: '" + addr + "'.", PyExcType::kValue);
|
||||
}
|
||||
|
||||
auto SockAddr::AddressString() const -> std::string {
|
||||
if (IsV6()) {
|
||||
char ip_str[INET6_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET6, &(AsSockAddrIn6()->sin6_addr), ip_str,
|
||||
INET6_ADDRSTRLEN)
|
||||
== nullptr) {
|
||||
throw Exception("inet_ntop failed for v6 addr", PyExcType::kValue);
|
||||
}
|
||||
return ip_str;
|
||||
}
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET, &(AsSockAddrIn()->sin_addr), ip_str, INET_ADDRSTRLEN)
|
||||
== nullptr) {
|
||||
throw Exception("inet_ntop failed for v4 addr", PyExcType::kValue);
|
||||
}
|
||||
return ip_str;
|
||||
}
|
||||
|
||||
auto SockAddr::Port() const -> int {
|
||||
if (IsV6()) {
|
||||
return ntohs(AsSockAddrIn6()->sin6_port);
|
||||
} else {
|
||||
return ntohs(AsSockAddrIn()->sin_port);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -15,16 +15,33 @@ class SockAddr {
|
||||
public:
|
||||
SockAddr() { memset(&addr_, 0, sizeof(addr_)); }
|
||||
|
||||
// Creates from an ipv4 or ipv6 address string;
|
||||
// throws an exception on error.
|
||||
// Creates from an ipv4 or ipv6 address string; throws an exception on
|
||||
// error.
|
||||
SockAddr(const std::string& addr, int port);
|
||||
|
||||
explicit SockAddr(const sockaddr_storage& addr_in) {
|
||||
addr_ = addr_in;
|
||||
assert(addr_.ss_family == AF_INET || addr_.ss_family == AF_INET6);
|
||||
}
|
||||
auto GetSockAddr() const -> const sockaddr* {
|
||||
|
||||
auto AsSockAddr() const -> const sockaddr* {
|
||||
return reinterpret_cast<const sockaddr*>(&addr_);
|
||||
}
|
||||
|
||||
auto AsSockAddrIn() const -> const sockaddr_in* {
|
||||
assert(!IsV6());
|
||||
return reinterpret_cast<const sockaddr_in*>(&addr_);
|
||||
}
|
||||
|
||||
auto AsSockAddrIn6() const -> const sockaddr_in6* {
|
||||
assert(IsV6());
|
||||
return reinterpret_cast<const sockaddr_in6*>(&addr_);
|
||||
}
|
||||
|
||||
auto AddressString() const -> std::string;
|
||||
|
||||
auto Port() const -> int;
|
||||
|
||||
auto GetSockAddrLen() const -> socklen_t {
|
||||
switch (addr_.ss_family) {
|
||||
case AF_INET:
|
||||
@ -32,9 +49,10 @@ class SockAddr {
|
||||
case AF_INET6:
|
||||
return sizeof(sockaddr_in6);
|
||||
default:
|
||||
throw Exception();
|
||||
throw Exception(PyExcType::kValue);
|
||||
}
|
||||
}
|
||||
|
||||
auto IsV6() const -> bool {
|
||||
switch (addr_.ss_family) {
|
||||
case AF_INET:
|
||||
@ -45,25 +63,22 @@ class SockAddr {
|
||||
throw Exception();
|
||||
}
|
||||
}
|
||||
|
||||
auto operator==(const SockAddr& other) const -> bool {
|
||||
if (addr_.ss_family != other.addr_.ss_family) return false;
|
||||
if (addr_.ss_family == AF_INET) {
|
||||
return (reinterpret_cast<const sockaddr_in&>(addr_).sin_addr.s_addr
|
||||
== reinterpret_cast<const sockaddr_in&>(other.addr_)
|
||||
.sin_addr.s_addr)
|
||||
&& (reinterpret_cast<const sockaddr_in&>(addr_).sin_port
|
||||
== reinterpret_cast<const sockaddr_in&>(other.addr_).sin_port);
|
||||
auto* a1 = AsSockAddrIn();
|
||||
auto* a2 = other.AsSockAddrIn();
|
||||
return !memcmp(&(a1->sin_addr), &(a2->sin_addr), sizeof(in_addr))
|
||||
&& a1->sin_port == a2->sin_port;
|
||||
}
|
||||
if (addr_.ss_family == AF_INET6) {
|
||||
return !memcmp(&(reinterpret_cast<const sockaddr_in6&>(addr_).sin6_addr),
|
||||
&(reinterpret_cast<const sockaddr_in6&>(other.addr_)
|
||||
.sin6_addr),
|
||||
sizeof(in6_addr))
|
||||
&& (reinterpret_cast<const sockaddr_in6&>(addr_).sin6_port
|
||||
== reinterpret_cast<const sockaddr_in6&>(other.addr_)
|
||||
.sin6_port);
|
||||
auto* a1 = AsSockAddrIn6();
|
||||
auto* a2 = other.AsSockAddrIn6();
|
||||
return !memcmp(&(a1->sin6_addr), &(a2->sin6_addr), sizeof(in6_addr))
|
||||
&& a1->sin6_port == a2->sin6_port;
|
||||
}
|
||||
throw Exception();
|
||||
throw Exception(PyExcType::kValue);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -416,9 +416,7 @@ class Python::ScopedInterpreterLock::Impl {
|
||||
};
|
||||
|
||||
Python::ScopedInterpreterLock::ScopedInterpreterLock()
|
||||
: impl_{new Python::ScopedInterpreterLock::Impl()}
|
||||
// impl_{std::make_unique<Python::ScopedInterpreterLock::Impl>()}
|
||||
{}
|
||||
: impl_{new Python::ScopedInterpreterLock::Impl()} {}
|
||||
|
||||
Python::ScopedInterpreterLock::~ScopedInterpreterLock() { delete impl_; }
|
||||
|
||||
|
||||
@ -41,7 +41,8 @@ class Python {
|
||||
|
||||
/// Use this to protect Python code that may be run in cases where we
|
||||
/// don't hold the Global Interpreter Lock (GIL). (Basically anything
|
||||
/// outside of the logic thread).
|
||||
/// outside of the logic thread). This will release and then restore
|
||||
/// the GIL if it is held initially; otherwise it is a no-op.
|
||||
class ScopedInterpreterLock {
|
||||
public:
|
||||
ScopedInterpreterLock();
|
||||
@ -49,9 +50,6 @@ class Python {
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
// Note: should use unique_ptr for this, but build fails on raspberry pi
|
||||
// (gcc 8.3.0). Works on Ubuntu 9.3 so should try again later.
|
||||
// std::unique_ptr<Impl> impl_{};
|
||||
Impl* impl_{};
|
||||
};
|
||||
|
||||
@ -64,9 +62,6 @@ class Python {
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
// Note: should use unique_ptr for this, but build fails on raspberry pi
|
||||
// (gcc 8.3.0). Works on Ubuntu 9.3 so should try again later.
|
||||
// std::unique_ptr<Impl> impl_{};
|
||||
Impl* impl_{};
|
||||
};
|
||||
|
||||
|
||||
@ -118,7 +118,9 @@ class PythonRef {
|
||||
/// Release the held reference (if one is held).
|
||||
void Release();
|
||||
|
||||
/// Clear the ref without decrementing its count and return the raw PyObject*
|
||||
/// Clear the ref without decrementing its count and return the raw
|
||||
/// PyObject*. Useful for functions that are expected to return a new
|
||||
/// Python ref.
|
||||
auto HandOver() -> PyObject* {
|
||||
assert(obj_);
|
||||
PyObject* obj = obj_;
|
||||
@ -151,8 +153,9 @@ class PythonRef {
|
||||
/// Throws Exception if an error occurs.
|
||||
auto DictGetItem(const char* name) const -> PythonRef;
|
||||
|
||||
/// The equivalent of calling Python str() on the contained PyObject.
|
||||
/// Gracefully handles invalid refs.
|
||||
/// The equivalent of calling Python str() on the contained PyObject, and
|
||||
/// gracefully handles invalid refs. To throw exceptions on invalid refs,
|
||||
/// use ValueAsString();
|
||||
auto Str() const -> std::string;
|
||||
|
||||
/// The equivalent of calling repr() on the contained PyObject.
|
||||
|
||||
@ -2589,90 +2589,6 @@ static PyMethodDef PyGetSpecialWidgetDef = {
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// -------------------------- have_incentivized_ad -----------------------------
|
||||
|
||||
// returns an extra hash value that can be incorporated into security checks;
|
||||
// this contains things like whether console commands have been run, etc.
|
||||
static auto PyHaveIncentivizedAd(PyObject* self, PyObject* args,
|
||||
PyObject* keywds) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
static const char* kwlist[] = {nullptr};
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "",
|
||||
const_cast<char**>(kwlist))) {
|
||||
return nullptr;
|
||||
}
|
||||
if (g_core->have_incentivized_ad) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyHaveIncentivizedAdDef = {
|
||||
"have_incentivized_ad", // name
|
||||
(PyCFunction)PyHaveIncentivizedAd, // method
|
||||
METH_VARARGS | METH_KEYWORDS, // flags
|
||||
|
||||
"have_incentivized_ad() -> bool\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ----------------------------- can_show_ad -----------------------------------
|
||||
|
||||
// this returns whether it makes sense to show an currently
|
||||
static auto PyCanShowAd(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
-> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
// if we've got any network connections, no ads.
|
||||
// (don't want to make someone on the other end wait or risk disconnecting
|
||||
// them or whatnot). Also disallow ads if remote apps are connected; at least
|
||||
// on Android, ads pause our activity which disconnects the remote app.
|
||||
// (need to fix this).
|
||||
if (g_base->app_mode()->HasConnectionToHost()
|
||||
|| g_base->app_mode()->HasConnectionToClients()
|
||||
|| g_base->input->HaveRemoteAppController()) {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_RETURN_TRUE; // all systems go..
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyCanShowAdDef = {
|
||||
"can_show_ad", // name
|
||||
(PyCFunction)PyCanShowAd, // method
|
||||
METH_VARARGS | METH_KEYWORDS, // flags
|
||||
"can_show_ad() -> bool\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ---------------------------- has_video_ads ----------------------------------
|
||||
|
||||
static auto PyHasVideoAds(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
-> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
if (g_core->platform->GetHasVideoAds()) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyHasVideoAdsDef = {
|
||||
"has_video_ads", // name
|
||||
(PyCFunction)PyHasVideoAds, // method
|
||||
METH_VARARGS | METH_KEYWORDS, // flags
|
||||
|
||||
"has_video_ads() -> bool\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
|
||||
// ------------------------------ back_press -----------------------------------
|
||||
|
||||
static auto PyBackPress(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
@ -2893,9 +2809,6 @@ auto PythonMethodsUIV1::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyOpenFileExternallyDef,
|
||||
PyOpenURLDef,
|
||||
PyBackPressDef,
|
||||
PyHasVideoAdsDef,
|
||||
PyCanShowAdDef,
|
||||
PyHaveIncentivizedAdDef,
|
||||
PyGetSpecialWidgetDef,
|
||||
PySetPartyWindowOpenDef,
|
||||
PySetPartyIconAlwaysVisibleDef,
|
||||
|
||||
@ -10,6 +10,7 @@ from bascenev1._player import Player
|
||||
from bascenev1._dependency import AssetPackage
|
||||
from bascenev1._activity import Activity
|
||||
from bascenev1._session import Session
|
||||
from bascenev1._net import HostInfo
|
||||
import _bascenev1
|
||||
|
||||
# The C++ layer looks for this variable:
|
||||
@ -30,4 +31,5 @@ values = [
|
||||
AssetPackage, # kAssetPackageClass
|
||||
Activity, # kActivityClass
|
||||
Session, # kSceneV1SessionClass
|
||||
HostInfo, # kHostInfoClass
|
||||
]
|
||||
|
||||
@ -5,22 +5,49 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Annotated
|
||||
|
||||
from efro.dataclassio import ioprepped, IOAttrs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
class AppExperience(Enum):
|
||||
"""Overall experience that can be provided by a Ballistica app.
|
||||
class AppInterfaceIdiom(Enum):
|
||||
"""A general form-factor or way of experiencing a Ballistica app.
|
||||
|
||||
This corresponds generally, but not exactly, to distinct apps built
|
||||
with Ballistica. However, a single app may support multiple experiences,
|
||||
or there may be multiple apps targeting one experience. Cloud components
|
||||
such as leagues are generally associated with an AppExperience.
|
||||
Note that it is possible for a running app to switch idioms (for
|
||||
instance if a mobile device or computer is connected to a TV).
|
||||
"""
|
||||
|
||||
# A special experience category that is supported everywhere. Used
|
||||
PHONE = 'phone'
|
||||
TABLET = 'tablet'
|
||||
DESKTOP = 'desktop'
|
||||
TV = 'tv'
|
||||
XR = 'xr'
|
||||
|
||||
|
||||
class AppExperience(Enum):
|
||||
"""A particular experience that can be provided by a Ballistica app.
|
||||
|
||||
This is one metric used to isolate different playerbases from
|
||||
eachother where there might be no technical barriers doing so.
|
||||
For example, a casual one-hand-playable phone game and an augmented
|
||||
reality tabletop game may both use the same scene-versions and
|
||||
networking-protocols and whatnot, but it would make no sense to
|
||||
allow players of one join servers for the other. AppExperience can
|
||||
be used to keep these player bases separate.
|
||||
|
||||
Generally a single Ballistica app targets a single AppExperience.
|
||||
This is not a technical requirement, however. A single app may
|
||||
support multiple experiences, or there may be multiple apps
|
||||
targeting one experience. Cloud components such as leagues are
|
||||
generally associated with an AppExperience so that they are only
|
||||
visible to client apps designed for that play style.
|
||||
"""
|
||||
|
||||
# An experience that is supported everywhere. Used
|
||||
# for the default empty AppMode when starting the app, etc.
|
||||
EMPTY = 'empty'
|
||||
|
||||
@ -33,3 +60,79 @@ class AppExperience(Enum):
|
||||
# touch-screen allowing a mobile device to be used as a game
|
||||
# controller.
|
||||
REMOTE = 'remote'
|
||||
|
||||
|
||||
class AppArchitecture(Enum):
|
||||
"""Processor architecture the App is running on."""
|
||||
|
||||
ARM = 'arm'
|
||||
ARM64 = 'arm64'
|
||||
X86 = 'x86'
|
||||
X86_64 = 'x86_64'
|
||||
|
||||
|
||||
class AppPlatform(Enum):
|
||||
"""Overall platform a Ballistica build can be targeting.
|
||||
|
||||
Each distinct flavor of an app has a unique combination
|
||||
of AppPlatform and AppVariant. Generally platform describes
|
||||
a set of hardware, while variant describes a destination or
|
||||
purpose for the build.
|
||||
"""
|
||||
|
||||
MAC = 'mac'
|
||||
WINDOWS = 'windows'
|
||||
LINUX = 'linux'
|
||||
ANDROID = 'android'
|
||||
IOS = 'ios'
|
||||
TVOS = 'tvos'
|
||||
|
||||
|
||||
class AppVariant(Enum):
|
||||
"""A unique Ballistica build type within a single platform.
|
||||
|
||||
Each distinct flavor of an app has a unique combination
|
||||
of AppPlatform and AppVariant. Generally platform describes
|
||||
a set of hardware, while variant describes a destination or
|
||||
purpose for the build.
|
||||
"""
|
||||
|
||||
# Default builds.
|
||||
GENERIC = 'generic'
|
||||
|
||||
# Builds intended for public testing (may have some extra checks
|
||||
# or logging enabled).
|
||||
TEST = 'test'
|
||||
|
||||
# Various stores.
|
||||
AMAZON_APPSTORE = 'amazon_appstore'
|
||||
GOOGLE_PLAY = 'google_play'
|
||||
APP_STORE = 'app_store'
|
||||
WINDOWS_STORE = 'windows_store'
|
||||
STEAM = 'steam'
|
||||
META = 'meta'
|
||||
EPIC_GAMES_STORE = 'epic_games_store'
|
||||
|
||||
# Other.
|
||||
ARCADE = 'arcade'
|
||||
DEMO = 'demo'
|
||||
|
||||
|
||||
@ioprepped
|
||||
@dataclass
|
||||
class AppInstanceInfo:
|
||||
"""General info about an individual running app."""
|
||||
|
||||
name = Annotated[str, IOAttrs('n')]
|
||||
version = Annotated[str, IOAttrs('v')]
|
||||
build = Annotated[int, IOAttrs('b')]
|
||||
|
||||
platform = Annotated[AppPlatform, IOAttrs('p')]
|
||||
variant = Annotated[AppVariant, IOAttrs('va')]
|
||||
architecture = Annotated[AppArchitecture, IOAttrs('a')]
|
||||
os_version = Annotated[str | None, IOAttrs('o')]
|
||||
|
||||
interface_idiom: Annotated[AppInterfaceIdiom, IOAttrs('i')]
|
||||
locale: Annotated[str, IOAttrs('l')]
|
||||
|
||||
device: Annotated[str | None, IOAttrs('d')]
|
||||
|
||||
@ -216,6 +216,12 @@ def _writefuncs(
|
||||
'import bascenev1 # pylint: disable=cyclic-import\n'
|
||||
'return bascenev1.Time(0.0)'
|
||||
)
|
||||
elif returns == 'bascenev1.HostInfo | None':
|
||||
returnstr = (
|
||||
'import bascenev1 # pylint: disable=cyclic-import\n'
|
||||
'return bascenev1.HostInfo(\'dummyname\', -1,'
|
||||
' \'dummy_addr\', -1)'
|
||||
)
|
||||
elif returns == 'babase.DisplayTime':
|
||||
returnstr = (
|
||||
'import babase # pylint: disable=cyclic-import\n'
|
||||
|
||||
@ -426,7 +426,6 @@ class ProjectUpdater:
|
||||
# from batools.xcode import update_xcode_project
|
||||
|
||||
for projpath in [
|
||||
# 'ballisticakit-mac.xcodeproj/project.pbxproj',
|
||||
# 'ballisticakit-ios.xcodeproj/project.pbxproj',
|
||||
'ballisticakit-xcode/BallisticaKit.xcodeproj/project.pbxproj',
|
||||
]:
|
||||
|
||||
@ -62,7 +62,7 @@ def build_openal(arch: str, mode: str) -> None:
|
||||
)
|
||||
# subprocess.run(['git', 'checkout', '1.23.1'], check=True, cwd=builddir)
|
||||
subprocess.run(
|
||||
['git', 'checkout', '5b5b948516f7340810ebbfdd5e46eb40f85d2e56'],
|
||||
['git', 'checkout', 'b81a270f6c1e795ca70d7684e0ccf35a19f247e2'],
|
||||
check=True,
|
||||
cwd=builddir,
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user