diff --git a/.efrocachemap b/.efrocachemap
index 15bf8e53..a1bce6d4 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -420,8 +420,8 @@
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/60/ad/38269b7f1c7dc20cb9a506cd0681",
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/72/85/d6fc4d16b7081d91fba2850b5b10",
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/e9/ae/1d674d0c086eaa0bd1c3b1db0505",
- "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/e8/42/a43c158be7fa45f2c0c3d4b84a1f",
- "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/5b/cf/4501b151257c3d8d6ee8d0497d14",
+ "assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/5a/10/dae249cdd589b795fd341ebbec42",
+ "assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/e2/24/5e7ea9ca5c9de4d3b7a28e53564d",
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/61/03/89070ca765e06da3a419a579f503",
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/f8/15/e1a2fa38697417bcf2cf19cd34ef",
"assets/build/ba_data/data/languages/chinesetraditional.json": "https://files.ballistica.net/cache/ba1/44/aa/c12568afb4558dc7f9f2fa155467",
@@ -431,17 +431,17 @@
"assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/68/93/da8e9874f41a786edf52ba4ccaad",
"assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/72/80/d6395c8a168558750c0d79ce769b",
"assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/4c/c7/0184b8178869d1a3827a1bfcd5bb",
- "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/8f/73/093120ae2241d8f4b899ccda2d75",
- "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/25/65/1cb03566e73811fc6e1b841d9072",
- "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/ef/e6/d4909f571d7473fd04055728490e",
+ "assets/build/ba_data/data/languages/filipino.json": "https://files.ballistica.net/cache/ba1/e9/07/b2dc862601bcd70701b083d43279",
+ "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/2e/48/b0a8fafc5e5436e99d9a3d697d23",
+ "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/8a/09/3e0fa9e44913b53f4dab195d3fae",
"assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/8a/2a/b2bc00eed0608b2199b2bc379b2e",
- "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/82/eb/37ff44af76812097f9c98f05c730",
- "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/50/e8/837be1324c8128507b3df89b689f",
+ "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/e0/04/6be14bff785255719756e0906ea9",
+ "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/91/98/42701cd595c2f70b7484614a8f49",
"assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/d8/f2/aa16bc336bd7660cc86c3264bfc4",
- "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/e3/85/14e57e3f49505e5a190daf7fe276",
+ "assets/build/ba_data/data/languages/indonesian.json": "https://files.ballistica.net/cache/ba1/7f/a9/db86d4c8b70f06fd8a1fe0c0511b",
"assets/build/ba_data/data/languages/italian.json": "https://files.ballistica.net/cache/ba1/1a/10/9563348e729d1e5c8ae8c9cbc1f2",
"assets/build/ba_data/data/languages/korean.json": "https://files.ballistica.net/cache/ba1/a8/e9/171a904f1331fdb7b1918a0f2598",
- "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/83/4a/ec10142ac479bf8d80455b47a62b",
+ "assets/build/ba_data/data/languages/persian.json": "https://files.ballistica.net/cache/ba1/df/b1/b2c9ebaad5e873ebedd365726d3d",
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/19/e9/59c891b1fb85f3ba9f19283c233d",
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/da/95/36797ec53a697a04e55b225a701d",
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/d7/06/9d70642d0a4d1e3b1c2149d7a17c",
@@ -452,7 +452,7 @@
"assets/build/ba_data/data/languages/swedish.json": "https://files.ballistica.net/cache/ba1/91/0a/35c4baf539d5951fc03a794c0e0b",
"assets/build/ba_data/data/languages/tamil.json": "https://files.ballistica.net/cache/ba1/94/1a/533bc718e676191bafc25e2dc98f",
"assets/build/ba_data/data/languages/thai.json": "https://files.ballistica.net/cache/ba1/f7/df/7ba5f99c5c2c4c86fc0503fcf0b7",
- "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/14/a0/783cc6da2d122e9a7482c6a5ef8c",
+ "assets/build/ba_data/data/languages/turkish.json": "https://files.ballistica.net/cache/ba1/9a/90/8e2ed626def09f88c3b9ab5215a3",
"assets/build/ba_data/data/languages/ukrainian.json": "https://files.ballistica.net/cache/ba1/ab/35/644e4239cfa62a597a905412b90c",
"assets/build/ba_data/data/languages/venetian.json": "https://files.ballistica.net/cache/ba1/53/9e/068074156b38bab7f732977a4031",
"assets/build/ba_data/data/languages/vietnamese.json": "https://files.ballistica.net/cache/ba1/25/13/b64b849fc9fedcc18d81f6e08c4d",
@@ -944,10 +944,10 @@
"assets/build/ba_data/models/zoeUpperArm.bob": "https://files.ballistica.net/cache/ba1/99/38/b7694cae0804260eeb337aa1676a",
"assets/build/ba_data/models/zoeUpperLeg.bob": "https://files.ballistica.net/cache/ba1/83/4f/28b2202d0109fa93272c0b09fa2d",
"assets/build/ba_data/python-site-packages/_yaml/__init__.py": "https://files.ballistica.net/cache/ba1/0d/45/65ba92f51d411dcffac8835b6130",
- "assets/build/ba_data/python-site-packages/certifi/__init__.py": "https://files.ballistica.net/cache/ba1/ca/90/4cf111df6bafc9735f6d2a05d6f2",
+ "assets/build/ba_data/python-site-packages/certifi/__init__.py": "https://files.ballistica.net/cache/ba1/f0/50/dbe7d0065006ac12adf2eaa239fc",
"assets/build/ba_data/python-site-packages/certifi/__main__.py": "https://files.ballistica.net/cache/ba1/b2/bb/d7d8216212bcf66cdc3067700fb7",
- "assets/build/ba_data/python-site-packages/certifi/cacert.pem": "https://files.ballistica.net/cache/ba1/c9/f9/e2d0dd61a7f4e36a3309a3981d07",
- "assets/build/ba_data/python-site-packages/certifi/core.py": "https://files.ballistica.net/cache/ba1/8a/01/33e774b2ed89a56756f32d2f3bef",
+ "assets/build/ba_data/python-site-packages/certifi/cacert.pem": "https://files.ballistica.net/cache/ba1/eb/1c/18ef584961785d002a2550d389e0",
+ "assets/build/ba_data/python-site-packages/certifi/core.py": "https://files.ballistica.net/cache/ba1/ac/28/37f05b52df3806856bce2c0b9772",
"assets/build/ba_data/python-site-packages/typing_extensions.py": "https://files.ballistica.net/cache/ba1/a5/c3/66c408bfad73af8644f507d8ee17",
"assets/build/ba_data/python-site-packages/yaml/__init__.py": "https://files.ballistica.net/cache/ba1/e5/47/17715ca7620f3b9749558b9dcb2d",
"assets/build/ba_data/python-site-packages/yaml/composer.py": "https://files.ballistica.net/cache/ba1/3e/aa/d7fcfc4707ad19a6964d72654b82",
@@ -3995,50 +3995,51 @@
"assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e",
"assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34",
"ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a",
- "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ad/15/3b9d4eb830dd3f65266b90544461",
- "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/3f/94/ce703438b67755c530ca90d7147e",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/57/49/aef9dbd58c9638d2f57c61fa9dee",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/53/73/7aee5551f9aa8c60bfa36ce86889",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8d/cd/61b3022a6a3620bb9a0d288a3a07",
- "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/67/d3/7e7b3147c119bcf9edc62f271755",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/41/81/b4225f4df31a6bb482eee912d1e7",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8a/3e/9a284ee8d8cb75fef73f31c95a8f",
- "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a5/a2/69829de7375f981ac01464d1271c",
- "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8f/de/c40022e95c0d51e3ea7d68713ac8",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2a/e3/74cdea89e9606f525ae01f5fb860",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/b3/8f5c7076b293ce6a961b23321ebe",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/45/4b/43950780d121290a40cb444e86c4",
- "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/6c/5c8a7cab586c813a07d5180e25c2",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ca/36/94c0d402ec38ffdd74cd165f51c3",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b7/a9/14ea5150ad61a43b5780975551ac",
- "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/23/72/2bdc1106cdf2aa163a591e7c47b8",
- "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/1e/d9/5a7fd190b86683bef223c1cdb0b6",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/2e/f1/27b90831c9a25d2b9d06a266e931",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/17/ce/d3e33370c016fc8110e6dddd120f",
- "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/32/b0/df61f7b69d796fbdf2aa0d11974b",
- "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/42/31/a45e87e70e5d5232956586620f35",
- "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/94/5e/6ac9534c08e600201b04d28a6069",
- "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5f/5d/52e74182f459f5b7b55ae07b36c6",
- "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/9d/367338622b31482a8ef87621f5aa",
- "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a8/18/4dff9ab6b2529d258a2ee5607d0c",
- "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/79/b9/e5e9d0f92f82f6cf35abf0c049cf",
- "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/b4/2c65b84265e0b2d576317ca86e77",
- "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d1/86/635b942e0837be18e6d9d859f2c4",
- "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b0/f5/3da5acc926ca5e6c02307b8a16a6",
- "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a3/51/d624ac150603304183ba23d369a2",
- "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e2/51/5eb2216e4cdc531c500244316f1d",
- "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b1/2b/c72179ed1d11ae7e11f429b90ae9",
- "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/78/cca5ff0fcc837467cd23239537c7",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e7/6e/eb7102dd939e85172d729ba471b8",
- "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e7/92/b7c90b5dbf614aa056cf467f73e0",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/cf/d9/52c1c145efa1a24ebf54dd71f691",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/31/15/ef849aeaf5a9cc2169e6ec4998c8",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/86/a7/def29184cd6e947469726ae382e1",
- "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/5f/30/42705d0b580994d1345c34651170",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/2f/b1/6a6e8cf45fc5afa4085bf90a526f",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/7e/fb/e7eaee33c6196f9204a2997fc65c",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/5a/39/e00cddb91e8eca83b117235c1332",
- "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/07/dd/6e331996e6e6907f05a21abc20a6",
- "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/7d/3e/229a581cb2454ed856f1d8b564a7",
- "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/98/12/571b2160d69d42580e8f31fa6a8d"
+ "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2a/10/01cc7af239cfca6d9abeb6e6deb5",
+ "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fd/49/6da409797f98e3834cdd2ba9a1e5",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/cd/ba/2e17df1379cd7f60708f1ec3aecb",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/72/0d/d953d2cda66ea47552c6a3f5dfee",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/12/44/fac079140811eaf6b3dd1f1d0fe0",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/00/74/a671dd7047610d8d555c4b0a303c",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/23/4a/40c6eb2af25a0a8f29530f8e63b0",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b3/ff/ced34572d1502e3ce393338810a9",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cd/73/54f48f6cb05f5dab5e32532b831a",
+ "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/26/ca/b667ad8ba524618e62ffc5a58c45",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c9/f1/f92e2fd877e32f2364eb1656052b",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/dc/d61b2e43131283a6049f203943bc",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b3/8b/84937c08100c035641764b95fe1d",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d0/59/e84165efa3367582461128db885a",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/3f/da203a1eb557318e9abc5f76aac1",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/07/db/5d04f8f0736732cdba70bb85fb19",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/ad/79/b6fcb72c6ff1ac3d507dd938ce14",
+ "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/46/5a/582ca64edfc416e140f4b5b1827d",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/5b/b5/ca8b600f49d4c28108f4e16c2f00",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/48/3f/8327430b9c194c14974bed19ea16",
+ "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/41/b3/5a5813294b9281ca6bbb1f5caebe",
+ "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/28/05/b6cc01e7b6762a3c8d47851cd30c",
+ "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f7/8c/36acf6d02d7c322aed086cc4ec3f",
+ "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ca/65/de52706de6aa624f01c5907e5367",
+ "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2d/3d/3e3e65846f42810c032cb5efd997",
+ "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/da/bf/c4a1f6e6d2495723acbd93e1b22c",
+ "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/34/6605f152207515d50174eca420e7",
+ "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8c/b6/770c3d26d70edec763335c38de73",
+ "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/33/10/a753a671240f243b2351b5730917",
+ "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1c/e4/05dc037f8669fc5ddc993dc8defc",
+ "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7c/c9/879778a21f2403346adf8db17318",
+ "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/86/36/6d77a933a8126df4fde064fe881f",
+ "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/80/e8/1c9c69d9fd5e47d0fd6e3c9b1134",
+ "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/e2/4208f2fc902ed0526bf4cb5bbc54",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e2/95/5fd6cede6b0e88753bb50b437110",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/87/0b/442839bc7a21c12ed6e173abf7ca",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/b6/aa/0666c00d1751f934cc1b0907fa40",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/aa/22/3afc115395a7909eac78d98cf856",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9f/e6/5097b01991ce22e1d3fd594808b2",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/d9/4f/7f2a34294f53378990487655f4ab",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/18/d3/50bbe34de1862d8224dafa8792e7",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/82/93/f80194878bfed43f58809a7e9823",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/73/54/88f193633990884b61719a481dec",
+ "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/f4/23/2a4e21dc99e6135c1cb102f6ca37",
+ "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/c0/32/b7907e3859a5c5013a3d97b6b523",
+ "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/2d/4f/f4fe67827f36cd59cd5193333a02",
+ "src/ballistica/generated/python_embedded/bootstrap_monolithic.inc": "https://files.ballistica.net/cache/ba1/ef/c1/aa5f1aa10af89f5c0b1e616355fd"
}
\ No newline at end of file
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 013a0841..de2b9cc5 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -64,9 +64,11 @@
aiomain
alarmsound
alibaba
+ allerrors
allpaths
allsettings
allteams
+ allwarnings
aman
amazonaws
aname
@@ -111,6 +113,7 @@
appspot
appstate
appstore
+ apptime
apputils
archivepath
archivepathbase
@@ -234,6 +237,7 @@
benning
bfiledir
bfiles
+ bgdynamics
bgmodel
bgrn
bgterrain
@@ -415,6 +419,7 @@
cleanlist
cleanupcheck
cleanupchecks
+ clearsign
clientid
clientlist
clienttobasn
@@ -433,6 +438,7 @@
clrhdr
clrnames
clrred
+ cmakelist
cmakelists
cmakeserver
cmath
@@ -1341,6 +1347,7 @@
levelgametype
levelmodule
levelname
+ levelno
lfull
lfval
libballisticacore
@@ -1647,6 +1654,7 @@
nettest
nettesting
netutils
+ networkwrite
nevermind
newactivity
newdamage
@@ -2380,6 +2388,7 @@
startscan
startsplits
starttime
+ startupmsg
statestr
statictest
statictestfiles
@@ -2408,6 +2417,7 @@
stot
strftime
stringified
+ stringifying
stringprep
stringptr
strippable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd70dfde..ba74fb7a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
-### 1.7.7 (build 20798, api 7, 2022-09-09)
+### 1.7.9 (build 20877, api 7, 2022-09-21)
+- Cleaned up the efro.message system to isolate response types that are used purely internally (via a new SysResponse type).
+- Fixed bug with 'Disable Camera Shake' option. (GitHub #511)
+- Fixed an issue where Co-op football would play no music.
- Accept "fairydust" as an emit type in `ba.emitfx()`.
+
+### 1.7.8 (build 20871, api 7, 2022-09-21)
+- Fixed tournament scores submits which were broken in 1.7.7 (oops).
+- Added @clear command to stdin command reader.
+
+### 1.7.7 (build 20868, api 7, 2022-09-20)
- Added `ba.app.meta.load_exported_classes()` for loading classes discovered by the meta subsystem cleanly in a background thread.
- Improved logging of missing playlist game types.
- Some ba.Lstr functionality can now be used in background threads.
@@ -9,7 +18,7 @@
- Added support for the console tool in the new devices section on ballistica.net.
- Increased timeouts in net-testing gui and a few other places to be able to better diagnose/handle places with very poor connectivity.
- Removed `Platform::SetLastPyCall()` which was just for debugging and which has not been useful in a while.
-- Moved some app bootstrapping from the C++ layer to the ba._bootstrap module.
+- Moved some app bootstrapping from the C++ layer to the `ba._bootstrap` module.
- The game will now properly return to the stress-test window after a stress test finishes (thanks vishal332008!)
- Continue window will now pause the game to avoid running up times in the background (thanks vishal332008!)
- Keepaway and KingOfTheHill now have epic options (thanks FAL-Guys!)
@@ -17,14 +26,37 @@
- Starting to rename the 'game' thread to the 'logic' thread. This is the thread where most high level app logic happen, not only game logic.
- `_ba.in_game_thread()` is now `_ba.in_logic_thread()`.
- Misc C++ layer tidying/refactoring.
-- Split out the `_ba` binary module into `_ba` and `_bainternal`. This will eventually allow running without the closed-source parts (_bainternal) present at all.
+- Split out the `_ba` binary module into `_ba` and `_bainternal`. This will eventually allow running without the closed-source parts (`_bainternal`) present at all.
- There is now a `_bainternal.py` dummy-module alongside the existing `_ba.py` one. Be sure to exclude it from any script collections used by the game (the same as `_ba.py`).
-- Added checks to make sure _ba or _bainternal arent used outside of ba. Any 'internal' functionality needed outside of ba should be exposed through ba.internal. _ba and _bainternal are internal implementation details.
+- Added checks to make sure `_ba` or `_bainternal` arent used outside of ba. Any 'internal' functionality needed outside of ba should be exposed through ba.internal. `_ba` and `_bainternal` are internal implementation details.
- Removed C++ Module class and simplified Thread class. The Module class was an old relic of long ago before C++ had lambdas and its existence was pretty pointless and confusing these days.
+- Renamed C++ App to AppFlavor and AppGlobals to App.
+- Renamed C++ Media to Assets.
+- Removed 'scores to beat' list in coop which was only ever functional in limited cases on the Mac version. Perhaps that feature can reappear in a cross-platform way sometime.
+- Simplified C++ bootstrapping to allocate all globals in one place.
+- Renamed C++ Game classes to Logic.
+- The app now bootstraps Python in the main thread instead of the logic thread. This will keep things more consistent later when we are able to run under an already-existing Python interpreter.
+- As a side-effect of initing Python in the main thread, it seems that Python now catches segfaults in our debug builds and prints Python stack traces. (see https://docs.python.org/3/library/faulthandler.html). We'll have to experiment and see if this is a net positive or something we want to disable or make optional.
+- Python and `_ba` are now completely initialized in public source code. Now we just need to enable the app to survive without `_bainternal` and it'll be possible to build a 100% open source app.
+- `Logging::Log()` in the C++ layer now takes a LogLevel arg (kDebug, kWarning, kError, etc.) and simply calls the equivalent Python logging.XXX call. This unifies our C++ and Python logging to go through the same place.
+- `ba.log()` is no more. Instead just use standard Python logging functions (logging.info(), logging.error(), etc.).
+- `_ba.getlog()` is now `_ba.get_v1_cloud_log()`. Note that this functionality will go away eventually so you should use `ba.app.log_handler` and/or standard Python logging functions to get at app logs.
+- Along the same lines, `_ba.get_log_file_path()` is now `_ba.get_v1_cloud_log_file_path()`.
+- Added `_ba.display_log()` function which ships a log message to the in-game terminal and platform-specific places like the Android log. The engine wires up standard Python logging output to go through this.
+- Added `_ba.v1_cloud_log()` which ships a message to the old v1-cloud-log (the log which is gathered and sent to the v1 master server to help me identify problems people are seeing). This is presently wired up to a subset of Python logging output to approximate how it used to work.
+- Note: Previously in the C++ layer some code would mix Python print calls (such as `PyErr_PrintEx()`) with ballistica::Log() calls. Previously these all wound up going to the same place (Python's sys.stderr) so it worked, but now they no longer do and so this sort of mixing should be avoided. So if you see a weird combination of colored log output lines with non-colored lines that seem to go together, please holler as it means something needs to be fixed.
+- Builds for Apple devices now explicitly set a thread stack size of 1MB. The default there is 512k and I was seeing some stack overflows for heavy physics sims or very recursive Python stuff.
+- If you want to grab recent logs, you can now use `ba.app.log_handler.get_cached()`. This will give you everything that has gone through Python logging, Python stdout/stderr, and the C++ Log() call (up to the max cache size that is).
+- LogHandler output now ALWAYS goes to stderr. Previously it only would if an interactive terminal was detected. This should make the binary easier to debug if run from scripts/etc. We can add a `--quiet` option if needed or whatnot.
+- (build 20859) Fixed an error setting up asyncio loops under Windows related to the fact that Python is now inited in the main thread.
+- (build 20864) Fatal-error message/traceback now properly prints to stderr again (I think the recent logging rejiggering caused it to stop).
+- (build 20864) Fixed an issue where the app could crash when connected to the cloud console while in a network game.
+- Added a simplified help() command which behaves reasonably under the in-game console or cloud-console.
+
### 1.7.6 (build 20687, api 7, 2022-08-11)
-- Cleaned up da MetaSubsystem code.
-- It is now possible to tell the meta system about arbitrary classes (ba_meta export foo.bar.Class) instead of just the preset types 'plugin', 'game', etc.
+- Cleaned up the MetaSubsystem code.
+- It is now possible to tell the meta system about arbitrary classes (ba\_meta export foo.bar.Class) instead of just the preset types 'plugin', 'game', etc.
- Newly discovered plugins are now activated immediately instead of requiring a restart.
### 1.7.5 (build 20672, api 7, 2022-07-25)
diff --git a/Makefile b/Makefile
index 53284308..59935c80 100644
--- a/Makefile
+++ b/Makefile
@@ -20,6 +20,10 @@ help:
# Set env-var BA_ENABLE_IRONY_BUILD_DB=1 to enable creating/updating a
# cmake compile-commands database for use with irony for emacs (and possibly
# other tools).
+# FIXME - this can break if we move/rename files and then run 'make update'
+# because it tries to use the previous cmakelist with the no-longer-valid
+# filename *before* it updates the cmakelist. Need to rethink order of
+# operations there.
ifeq ($(BA_ENABLE_IRONY_BUILD_DB),1)
PREREQ_IRONY = .cache/irony/compile_commands.json
endif
diff --git a/assets/src/ba_data/python/._ba_sources_hash b/assets/src/ba_data/python/._ba_sources_hash
index b56206f3..4d3af060 100644
--- a/assets/src/ba_data/python/._ba_sources_hash
+++ b/assets/src/ba_data/python/._ba_sources_hash
@@ -1 +1 @@
-126683827977798484003262787310231621875
\ No newline at end of file
+137071025041513581787580065580079045765
\ No newline at end of file
diff --git a/assets/src/ba_data/python/._bainternal_sources_hash b/assets/src/ba_data/python/._bainternal_sources_hash
index 1e1473b6..99a731ce 100644
--- a/assets/src/ba_data/python/._bainternal_sources_hash
+++ b/assets/src/ba_data/python/._bainternal_sources_hash
@@ -1 +1 @@
-27855823406376609779797608591198912121
\ No newline at end of file
+139020022013133168311319486434408589898
diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py
index 0705868d..2f751fc3 100644
--- a/assets/src/ba_data/python/_ba.py
+++ b/assets/src/ba_data/python/_ba.py
@@ -1108,12 +1108,6 @@ def add_clean_frame_callback(call: Callable) -> None:
return None
-def add_transaction(transaction: dict,
- callback: Callable | None = None) -> None:
- """(internal)"""
- return None
-
-
def android_get_external_files_dir() -> str:
"""(internal)
@@ -1137,6 +1131,11 @@ def android_show_wifi_settings() -> None:
return None
+def app_instance_uuid() -> str:
+ """(internal)"""
+ return str()
+
+
def apply_config() -> None:
"""(internal)"""
return None
@@ -1472,6 +1471,16 @@ def disconnect_from_host() -> None:
return None
+def display_log(name: str, level: str, message: str) -> None:
+ """(internal)
+
+ Sends a log message to the in-game console and any per-platform
+ log destinations (Android log, etc.). This generally is not called
+ directly and should instead be fed Python logging output.
+ """
+ return None
+
+
def do_once() -> bool:
"""Return whether this is the first time running a line of code.
@@ -1561,15 +1570,6 @@ def focus_window() -> None:
return None
-def game_service_has_leaderboard(game: str, config: str) -> bool:
- """(internal)
-
- Given a game and config string, returns whether there is a leaderboard
- for it on the game service.
- """
- return bool()
-
-
def get_appconfig_builtin_keys() -> list[str]:
"""(internal)"""
return ['blah', 'blah2']
@@ -1700,29 +1700,11 @@ def get_local_active_input_devices_count() -> int:
return int()
-def get_log_file_path() -> str:
- """(internal)
-
- Return the path to the app log file.
- """
- return str()
-
-
def get_low_level_config_value(key: str, default_value: int) -> int:
"""(internal)"""
return int()
-def get_master_server_address(source: int = -1,
- version: int = 1,
- internal: bool = False) -> str:
- """(internal)
-
- Return the address of the master server.
- """
- return str()
-
-
def get_max_graphics_quality() -> str:
"""(internal)
@@ -1731,11 +1713,6 @@ def get_max_graphics_quality() -> str:
return str()
-def get_news_show() -> str:
- """(internal)"""
- return str()
-
-
def get_package_collide_model(package: ba.AssetPackage,
name: str) -> ba.CollideModel:
"""(internal)"""
@@ -1767,16 +1744,6 @@ def get_package_texture(package: ba.AssetPackage, name: str) -> ba.Texture:
return ba.Texture()
-def get_price(item: str) -> str | None:
- """(internal)"""
- return ''
-
-
-def get_public_login_id() -> str | None:
- """(internal)"""
- return ''
-
-
def get_public_party_enabled() -> bool:
"""(internal)"""
return bool()
@@ -1787,16 +1754,6 @@ def get_public_party_max_size() -> int:
return int()
-def get_purchased(item: str) -> bool:
- """(internal)"""
- return bool()
-
-
-def get_purchases_state() -> int:
- """(internal)"""
- return int()
-
-
def get_qrcode_texture(url: str) -> ba.Texture:
"""(internal)"""
import ba # pylint: disable=cyclic-import
@@ -1824,11 +1781,6 @@ def get_replays_dir() -> str:
return str()
-def get_scores_to_beat(level: str, config: str, callback: Callable) -> None:
- """(internal)"""
- return None
-
-
def get_special_widget(name: str) -> Widget:
"""(internal)"""
return Widget()
@@ -1872,56 +1824,16 @@ def get_ui_input_device() -> ba.InputDevice:
return ba.InputDevice()
-def get_v1_account_display_string(full: bool = True) -> str:
+def get_v1_cloud_log() -> str:
"""(internal)"""
return str()
-def get_v1_account_misc_read_val(name: str, default_value: Any) -> Any:
- """(internal)"""
- return _uninferrable()
-
-
-def get_v1_account_misc_read_val_2(name: str, default_value: Any) -> Any:
- """(internal)"""
- return _uninferrable()
-
-
-def get_v1_account_misc_val(name: str, default_value: Any) -> Any:
- """(internal)"""
- return _uninferrable()
-
-
-def get_v1_account_name() -> str:
- """(internal)"""
- return str()
-
-
-def get_v1_account_state() -> str:
- """(internal)"""
- return str()
-
-
-def get_v1_account_state_num() -> int:
- """(internal)"""
- return int()
-
-
-def get_v1_account_ticket_count() -> int:
+def get_v1_cloud_log_file_path() -> str:
"""(internal)
- Returns the number of tickets for the current account.
+ Return the path to the app log file.
"""
- return int()
-
-
-def get_v1_account_type() -> str:
- """(internal)"""
- return str()
-
-
-def get_v2_fleet() -> str:
- """(internal)"""
return str()
@@ -2015,11 +1927,6 @@ def getinputdevice(name: str, unique_id: str, doraise: bool = True) -> Any:
return None
-def getlog() -> str:
- """(internal)"""
- return str()
-
-
def getmodel(name: str) -> ba.Model:
"""Return a model, loading it if necessary.
@@ -2129,11 +2036,6 @@ def have_incentivized_ad() -> bool:
return bool()
-def have_outstanding_transactions() -> bool:
- """(internal)"""
- return bool()
-
-
def have_permission(permission: ba.Permission) -> bool:
"""(internal)"""
return bool()
@@ -2210,15 +2112,10 @@ def imagewidget(edit: ba.Widget | None = None,
return ba.Widget()
-def in_game_purchase(item: str, price: int) -> None:
- """(internal)"""
- return None
-
-
def in_logic_thread() -> bool:
"""(internal)
- Returns whether or not the current thread is the game thread.
+ Returns whether or not the current thread is the logic thread.
"""
return bool()
@@ -2240,11 +2137,6 @@ def increment_analytics_counts_raw(name: str, increment: int = 1) -> None:
return None
-def is_blessed() -> bool:
- """(internal)"""
- return bool()
-
-
def is_in_replay() -> bool:
"""(internal)"""
return bool()
@@ -2301,22 +2193,6 @@ def lock_all_input() -> None:
return None
-def log(message: str, to_stdout: bool = True, to_server: bool = True) -> None:
- """Category: **General Utility Functions**
-
- Log a message. This goes to the default logging mechanism depending
- on the platform (stdout on mac, android log on android, etc).
-
- Log messages also go to the in-game console unless 'to_console'
- is False. They are also sent to the master-server for use in analyzing
- issues unless to_server is False.
-
- Python's standard print() is wired to call this (with default values)
- so in most cases you can just use that.
- """
- return None
-
-
def mac_music_app_get_library_source() -> None:
"""(internal)"""
return None
@@ -2352,14 +2228,6 @@ def mac_music_app_stop() -> None:
return None
-def mark_config_dirty() -> None:
- """(internal)
-
- Category: General Utility Functions
- """
- return None
-
-
def mark_log_sent() -> None:
"""(internal)"""
return None
@@ -2488,11 +2356,6 @@ def playsound(sound: Sound,
return None
-def power_ranking_query(callback: Callable, season: Any = None) -> None:
- """(internal)"""
- return None
-
-
def print_context() -> None:
"""(internal)
@@ -2509,23 +2372,6 @@ def print_load_info() -> None:
return None
-def print_stderr(message: str) -> None:
- """(internal)
-
- Print to system stderr.
- Also forwards to the internal console, etc.
- """
- return None
-
-
-def print_stdout(message: str) -> None:
- """(internal)
- Print to system stdout.
- Also forwards to the internal console, etc.
- """
- return None
-
-
def printnodes() -> None:
"""Print various info about existing nodes; useful for debugging.
@@ -2545,14 +2391,10 @@ def printobjects() -> None:
return None
-def purchase(item: str) -> None:
- """(internal)"""
- return None
-
-
def pushcall(call: Callable,
from_other_thread: bool = False,
- suppress_other_thread_warning: bool = False) -> None:
+ suppress_other_thread_warning: bool = False,
+ other_thread_use_fg_context: bool = False) -> None:
"""Pushes a call onto the event loop to be run during the next cycle.
Category: **General Utility Functions**
@@ -2560,12 +2402,14 @@ def pushcall(call: Callable,
This can be handy for calls that are disallowed from within other
callbacks, etc.
- This call expects to be used in the game thread, and will automatically
+ This call expects to be used in the logic thread, and will automatically
save and restore the ba.Context to behave seamlessly.
- If you want to push a call from outside of the game thread,
+ If you want to push a call from outside of the logic thread,
however, you can pass 'from_other_thread' as True. In this case
- the call will always run in the UI context on the game thread.
+ the call will always run in the UI context on the logic thread
+ or whichever context is in the foreground if
+ other_thread_use_fg_context is True.
"""
return None
@@ -2616,21 +2460,11 @@ def reload_media() -> None:
return None
-def report_achievement(achievement: str, pass_to_account: bool = True) -> None:
- """(internal)"""
- return None
-
-
def request_permission(permission: ba.Permission) -> None:
"""(internal)"""
return None
-def reset_achievements() -> None:
- """(internal)"""
- return None
-
-
def reset_game_activity_tracking() -> None:
"""(internal)"""
return None
@@ -2646,11 +2480,6 @@ def resolve_appconfig_value(key: str) -> Any:
return _uninferrable()
-def restore_purchases() -> None:
- """(internal)"""
- return None
-
-
def rowwidget(edit: ba.Widget | None = None,
parent: ba.Widget | None = None,
size: Sequence[float] | None = None,
@@ -2673,11 +2502,6 @@ def rowwidget(edit: ba.Widget | None = None,
return ba.Widget()
-def run_transactions() -> None:
- """(internal)"""
- return None
-
-
def safecolor(color: Sequence[float],
target_intensity: float = 0.6) -> tuple[float, ...]:
"""Given a color tuple, return a color safe to display as text.
@@ -2702,11 +2526,12 @@ def screenmessage(message: str | ba.Lstr,
Category: **General Utility Functions**
If 'top' is True, the message will go to the top message area.
- For 'top' messages, 'image' can be a texture to display alongside the
- message.
- If 'log' is True, the message will also be printed to the output log
- 'clients' can be a list of client-ids the message should be sent to,
- or None to specify that everyone should receive it.
+ For 'top' messages, 'image' must be a dict containing 'texture'
+ and 'tint_texture' textures and 'tint_color' and 'tint2_color'
+ colors. This defines an icon to display alongside the message.
+ If 'log' is True, the message will also be submitted to the log.
+ 'clients' can be a list of client-ids the message should be sent
+ to, or None to specify that everyone should receive it.
If 'transient' is True, the message will not be included in the
game-stream and thus will not show up when viewing replays.
Currently the 'clients' option only works for transient messages.
@@ -2953,48 +2778,11 @@ def show_progress_bar() -> None:
return None
-def sign_in_v1(account_type: str) -> None:
- """(internal)
-
- Category: General Utility Functions
- """
- return None
-
-
-def sign_out_v1(v2_embedded: bool = False) -> None:
- """(internal)
-
- Category: General Utility Functions
- """
- return None
-
-
def submit_analytics_counts() -> None:
"""(internal)"""
return None
-def submit_score(game: str,
- config: str,
- name: Any,
- score: int | None,
- callback: Callable,
- friend_callback: Callable | None,
- order: str = 'increasing',
- tournament_id: str | None = None,
- score_type: str = 'points',
- campaign: str | None = None,
- level: str | None = None) -> None:
- """(internal)
-
- Submit a score to the server; callback will be called with the results.
- As a courtesy, please don't send fake scores to the server. I'd prefer
- to devote my time to improving the game instead of trying to make the
- score server more mischief-proof.
- """
- return None
-
-
def textwidget(edit: ba.Widget | None = None,
parent: ba.Widget | None = None,
size: Sequence[float] | None = None,
@@ -3173,12 +2961,6 @@ def timer(time: float,
return None
-def tournament_query(callback: Callable[[dict | None], None],
- args: dict) -> None:
- """(internal)"""
- return None
-
-
def uibounds() -> tuple[float, float, float, float]:
"""(internal)
@@ -3198,6 +2980,19 @@ def unlock_all_input() -> None:
return None
+def user_ran_commands() -> None:
+ """(internal)"""
+ return None
+
+
+def v1_cloud_log(message: str) -> None:
+ """(internal)
+
+ Push messages to the old v1 cloud log.
+ """
+ return None
+
+
def value_test(arg: str,
change: float | None = None,
absolute: float | None = None) -> float:
diff --git a/assets/src/ba_data/python/ba/__init__.py b/assets/src/ba_data/python/ba/__init__.py
index 4b06c0ed..43d98979 100644
--- a/assets/src/ba_data/python/ba/__init__.py
+++ b/assets/src/ba_data/python/ba/__init__.py
@@ -13,12 +13,11 @@ from _ba import (
Node, SessionPlayer, Sound, Texture, Timer, Vec3, Widget, buttonwidget,
camerashake, checkboxwidget, columnwidget, containerwidget, do_once,
emitfx, getactivity, getcollidemodel, getmodel, getnodes, getsession,
- getsound, gettexture, hscrollwidget, imagewidget, log, newactivity,
- newnode, playsound, printnodes, printobjects, pushcall, quit, rowwidget,
- safecolor, screenmessage, scrollwidget, set_analytics_screen, charstr,
- textwidget, time, timer, open_url, widget, clipboard_is_supported,
- clipboard_has_text, clipboard_get_text, clipboard_set_text, getdata,
- in_logic_thread)
+ getsound, gettexture, hscrollwidget, imagewidget, newactivity, newnode,
+ playsound, printnodes, printobjects, pushcall, quit, rowwidget, safecolor,
+ screenmessage, scrollwidget, set_analytics_screen, charstr, textwidget,
+ time, timer, open_url, widget, clipboard_is_supported, clipboard_has_text,
+ clipboard_get_text, clipboard_set_text, getdata, in_logic_thread)
from ba._activity import Activity
from ba._plugin import PotentialPlugin, Plugin, PluginSubsystem
from ba._actor import Actor
@@ -103,7 +102,7 @@ __all__ = [
'ImpactDamageMessage', 'in_logic_thread', 'InputDevice',
'InputDeviceNotFoundError', 'InputType', 'IntChoiceSetting', 'IntSetting',
'is_browser_likely_available', 'is_point_in_box', 'Keyboard',
- 'LanguageSubsystem', 'Level', 'Lobby', 'log', 'Lstr', 'Map', 'Material',
+ 'LanguageSubsystem', 'Level', 'Lobby', 'Lstr', 'Map', 'Material',
'MetadataSubsystem', 'Model', 'MultiTeamSession', 'MusicPlayer',
'MusicPlayMode', 'MusicSubsystem', 'MusicType', 'newactivity', 'newnode',
'Node', 'NodeActor', 'NodeNotFoundError', 'normalized_color',
diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py
index b1c012c9..b976517b 100644
--- a/assets/src/ba_data/python/ba/_app.py
+++ b/assets/src/ba_data/python/ba/_app.py
@@ -26,6 +26,7 @@ if TYPE_CHECKING:
import asyncio
from typing import Any, Callable
+ import efro.log
import ba
from ba._cloud import CloudSubsystem
from bastd.actor import spazappearance
@@ -49,6 +50,7 @@ class App:
# Implementations for these will be filled in by internal libs.
accounts_v2: AccountV2Subsystem
cloud: CloudSubsystem
+ log_handler: efro.log.LogHandler
class State(Enum):
"""High level state the app can be in."""
@@ -384,7 +386,7 @@ class App:
# If there's a leftover log file, attempt to upload it to the
# master-server and/or get rid of it.
- _apputils.handle_leftover_log_file()
+ _apputils.handle_leftover_v1_cloud_log_file()
# Only do this stuff if our config file is healthy so we don't
# overwrite a broken one or whatnot and wipe out data.
diff --git a/assets/src/ba_data/python/ba/_appconfig.py b/assets/src/ba_data/python/ba/_appconfig.py
index 13270319..4fd28deb 100644
--- a/assets/src/ba_data/python/ba/_appconfig.py
+++ b/assets/src/ba_data/python/ba/_appconfig.py
@@ -128,12 +128,6 @@ def read_config() -> tuple[AppConfig, bool]:
shutil.copyfile(config_file_path, config_file_path + '.broken')
except Exception as exc2:
print('EXC copying broken config:', exc2)
- try:
- _ba.log('broken config contents:\n' +
- config_contents.replace('\000', ''),
- to_stdout=False)
- except Exception as exc2:
- print('EXC logging broken config contents:', exc2)
config = AppConfig()
# Now attempt to read one of our 'prev' backup copies.
diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py
index e1d5d626..d7c2cfe9 100644
--- a/assets/src/ba_data/python/ba/_apputils.py
+++ b/assets/src/ba_data/python/ba/_apputils.py
@@ -50,7 +50,7 @@ def should_submit_debug_info() -> bool:
return _ba.app.config.get('Submit Debug Info', True)
-def handle_log() -> None:
+def handle_v1_cloud_log() -> None:
"""Called on debug log prints.
When this happens, we can upload our log to the server
@@ -74,7 +74,7 @@ def handle_log() -> None:
activityname = 'unavailable'
info = {
- 'log': _ba.getlog(),
+ 'log': _ba.get_v1_cloud_log(),
'version': app.version,
'build': app.build_number,
'userAgentString': app.user_agent_string,
@@ -108,7 +108,7 @@ def handle_log() -> None:
def _reset() -> None:
app.log_upload_timer_started = False
if app.log_have_new:
- handle_log()
+ handle_v1_cloud_log()
if not _ba.is_log_full():
with _ba.Context('ui'):
@@ -118,14 +118,15 @@ def handle_log() -> None:
suppress_format_warning=True)
-def handle_leftover_log_file() -> None:
- """Handle an un-uploaded log from a previous run."""
+def handle_leftover_v1_cloud_log_file() -> None:
+ """Handle an un-uploaded v1-cloud-log from a previous run."""
try:
import json
from ba._net import master_server_post
- if os.path.exists(_ba.get_log_file_path()):
- with open(_ba.get_log_file_path(), encoding='utf-8') as infile:
+ if os.path.exists(_ba.get_v1_cloud_log_file_path()):
+ with open(_ba.get_v1_cloud_log_file_path(),
+ encoding='utf-8') as infile:
info = json.loads(infile.read())
infile.close()
do_send = should_submit_debug_info()
@@ -136,7 +137,7 @@ def handle_leftover_log_file() -> None:
# lets kill it.
if data is not None:
try:
- os.remove(_ba.get_log_file_path())
+ os.remove(_ba.get_v1_cloud_log_file_path())
except FileNotFoundError:
# Saw this in the wild. The file just existed
# a moment ago but I suppose something could have
@@ -146,7 +147,7 @@ def handle_leftover_log_file() -> None:
master_server_post('bsLog', info, response)
else:
# If they don't want logs uploaded just kill it.
- os.remove(_ba.get_log_file_path())
+ os.remove(_ba.get_v1_cloud_log_file_path())
except Exception:
from ba import _error
_error.print_exception('Error handling leftover log file.')
diff --git a/assets/src/ba_data/python/ba/_asyncio.py b/assets/src/ba_data/python/ba/_asyncio.py
index afb3adc4..3639d2af 100644
--- a/assets/src/ba_data/python/ba/_asyncio.py
+++ b/assets/src/ba_data/python/ba/_asyncio.py
@@ -18,7 +18,7 @@ import os
if TYPE_CHECKING:
import ba
-# Our timer and event loop for the ballistica game thread.
+# Our timer and event loop for the ballistica logic thread.
_asyncio_timer: ba.Timer | None = None
_asyncio_event_loop: asyncio.AbstractEventLoop | None = None
diff --git a/assets/src/ba_data/python/ba/_bootstrap.py b/assets/src/ba_data/python/ba/_bootstrap.py
index 490f64f5..325e4b70 100644
--- a/assets/src/ba_data/python/ba/_bootstrap.py
+++ b/assets/src/ba_data/python/ba/_bootstrap.py
@@ -5,14 +5,14 @@ from __future__ import annotations
import os
import sys
-import signal
-import threading
from typing import TYPE_CHECKING
+from efro.log import setup_logging, LogLevel
import _ba
if TYPE_CHECKING:
- from typing import Any, TextIO, Callable
+ from typing import Any
+ from efro.log import LogEntry
_g_did_bootstrap = False # pylint: disable=invalid-name
@@ -20,25 +20,32 @@ _g_did_bootstrap = False # pylint: disable=invalid-name
def bootstrap() -> None:
"""Run bootstrapping logic.
- This is the very first userland code that runs.
+ This is the very first ballistica code that runs (aside from imports).
It sets up low level environment bits and creates the app instance.
"""
+
global _g_did_bootstrap # pylint: disable=global-statement, invalid-name
if _g_did_bootstrap:
raise RuntimeError('Bootstrap has already been called.')
_g_did_bootstrap = True
- # The first thing we set up is capturing/redirecting Python
- # stdout/stderr so we can at least debug problems on systems where
- # native stdout/stderr is not easily accessible (looking at you, Android).
- sys.stdout = _Redirect(sys.stdout, _ba.print_stdout) # type: ignore
- sys.stderr = _Redirect(sys.stderr, _ba.print_stderr) # type: ignore
+ # The first thing we do is set up our logging system and feed
+ # Python's stdout/stderr into it. Then we can at least debug problems
+ # on systems where native stdout/stderr is not easily accessible
+ # such as Android.
+ log_handler = setup_logging(log_path=None,
+ level=LogLevel.DEBUG,
+ suppress_non_root_debug=True,
+ log_stdout_stderr=True,
+ cache_size_limit=1024 * 1024)
+
+ log_handler.add_callback(_on_log)
env = _ba.env()
# Give a soft warning if we're being used with a different binary
# version than we expect.
- expected_build = 20798
+ expected_build = 20877
running_build: int = env['build_number']
if running_build != expected_build:
print(
@@ -48,16 +55,11 @@ def bootstrap() -> None:
f' This might cause the app to error or misbehave.',
file=sys.stderr)
- # Tell Python to not handle SIGINT itself (it normally generates
- # KeyboardInterrupts which make a mess; we want to intercept them
- # for simple clean exit). We capture interrupts per-platform in
- # the C++ layer.
- # Note: I tried creating a handler in Python but it seemed to often have
- # a delay of up to a second before getting called. (not a huge deal
- # but I'm picky).
- signal.signal(signal.SIGINT, signal.SIG_DFL) # Do default handling.
+ # In bootstrap_monolithic.py we told Python not to handle SIGINT itself
+ # (because that must be done in the main thread). Now we finish the
+ # job by adding our own handler to replace it.
- # ..though it turns out we need to set up our C signal handling AFTER
+ # Note: I've found we need to set up our C signal handling AFTER
# we've told Python to disable its own; otherwise (on Mac at least) it
# wipes out our existing C handler.
_ba.setup_sigint()
@@ -91,101 +93,83 @@ def bootstrap() -> None:
os.environ['SSL_CERT_FILE'] = os.environ['REQUESTS_CA_BUNDLE'] = (
certifi.where())
- # FIXME: I think we should init Python in the main thread, which should
- # also avoid these issues. (and also might help us play better with
- # Python debuggers?)
+ # On Windows I'm seeing the following error creating asyncio loops in
+ # background threads with the default proactor setup:
+ # ValueError: set_wakeup_fd only works in main thread of the main
+ # interpreter
+ # So let's explicitly request selector loops.
+ # Interestingly this error only started showing up once I moved
+ # Python init to the main thread; previously the various asyncio
+ # bg thread loops were working fine (maybe something caused them
+ # to default to selector in that case?..
+ if sys.platform == 'win32':
+ import asyncio
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
- # Gloriously hacky workaround here:
- # Our 'main' Python thread is the game thread (not the app's main
- # thread) which means it has a small stack compared to the main
- # thread (at least on apple). Sadly it turns out this causes the
- # debug build of Python to blow its stack immediately when doing
- # some big imports.
- # Normally we'd just give the game thread the same stack size as
- # the main thread and that'd be the end of it. However
- # we're using std::threads which it turns out have no way to set
- # the stack size (as of fall '19). Grumble.
- #
- # However python threads *can* take custom stack sizes.
- # (and it appears they might use the main thread's by default?..)
- # ...so as a workaround in the debug version, we can run problematic
- # heavy imports here in another thread and all is well.
- # If we ever see stack overflows in our release build we'll have
- # to take more drastic measures like switching from std::threads
- # to pthreads.
-
- if debug_build:
-
- # noinspection PyUnresolvedReferences
- def _thread_func() -> None:
- # pylint: disable=unused-import
- import json
- import urllib.request
-
- testthread = threading.Thread(target=_thread_func)
- testthread.start()
- testthread.join()
- del testthread
-
- # Clear out the standard quit/exit messages since they don't work for us.
# pylint: disable=c-extension-no-member
if not TYPE_CHECKING:
import __main__
+
+ # Clear out the standard quit/exit messages since they don't
+ # work for us.
del __main__.__builtins__.quit
del __main__.__builtins__.exit
+ # Also replace standard interactive help with our simplified
+ # one which is more friendly to cloud/in-game console situations.
+ __main__.__builtins__.help = _CustomHelper()
+
# Now spin up our App instance and store it on both _ba and ba.
from ba._app import App
import ba
_ba.app = ba.app = App()
+ _ba.app.log_handler = log_handler
-class _Redirect:
+class _CustomHelper:
+ """Replacement 'help' that behaves better for our setup."""
- def __init__(self, original: TextIO, call: Callable[[str], None]) -> None:
- self._lock = threading.Lock()
- self._linebits: list[str] = []
- self._original = original
- self._call = call
- self._pending_ship = False
+ def __repr__(self) -> str:
+ return 'Type help(object) for help about object.'
- def write(self, sval: Any) -> None:
- """Override standard write call."""
+ def __call__(self, *args: Any, **kwds: Any) -> Any:
+ # We get an ugly error importing pydoc on our embedded
+ # platforms due to _sysconfigdata_xxx.py not being present
+ # (but then things mostly work). Let's get the ugly error out
+ # of the way explicitly.
+ import sysconfig
+ try:
+ # This errors once but seems to run cleanly after, so let's
+ # get the error out of the way.
+ sysconfig.get_path('stdlib')
+ except ModuleNotFoundError:
+ pass
- self._call(sval)
+ import pydoc
+ # Disable pager and interactive help since neither works well
+ # with our funky multi-threaded setup or in-game/cloud consoles.
+ # Let's just do simple text dumps.
+ pydoc.pager = pydoc.plainpager
+ if not args and not kwds:
+ print('Interactive help is not available in this environment.\n'
+ 'Type help(object) for help about object.')
+ return None
+ return pydoc.help(*args, **kwds)
- # Now do logging:
- # Add it to our accumulated line.
- # If the message ends in a newline, we can ship it
- # immediately as a log entry. Otherwise, schedule a ship
- # next cycle (if it hasn't yet at that point) so that we
- # can accumulate subsequent prints.
- # (so stuff like print('foo', 123, 'bar') will ship as one entry)
- with self._lock:
- self._linebits.append(sval)
- if sval.endswith('\n'):
- self._shiplog()
- else:
- _ba.pushcall(self._shiplog,
- from_other_thread=True,
- suppress_other_thread_warning=True)
- def _shiplog(self) -> None:
- with self._lock:
- line = ''.join(self._linebits)
- if not line:
- return
- self._linebits = []
+def _on_log(entry: LogEntry) -> None:
- # Log messages aren't expected to have trailing newlines.
- if line.endswith('\n'):
- line = line[:-1]
- _ba.log(line, to_stdout=False)
+ # Just forward this along to the engine to display in the in-game console,
+ # in the Android log, etc.
+ _ba.display_log(
+ name=entry.name,
+ level=entry.level.name,
+ message=entry.message,
+ )
- def flush(self) -> None:
- """Flush the file."""
- self._original.flush()
-
- def isatty(self) -> bool:
- """Are we a terminal?"""
- return self._original.isatty()
+ # We also want to feed some logs to the old V1-cloud-log system.
+ # Let's go with anything warning or higher as well as the stdout/stderr
+ # log messages that ba.app.log_handler creates for us.
+ if entry.level.value >= LogLevel.WARNING.value or entry.name in ('stdout',
+ 'stderr'):
+ _ba.v1_cloud_log(entry.message)
diff --git a/assets/src/ba_data/python/ba/_coopgame.py b/assets/src/ba_data/python/ba/_coopgame.py
index ecae427b..6e380d84 100644
--- a/assets/src/ba_data/python/ba/_coopgame.py
+++ b/assets/src/ba_data/python/ba/_coopgame.py
@@ -55,19 +55,6 @@ class CoopGameActivity(GameActivity[PlayerType, TeamType]):
# Preload achievement images in case we get some.
_ba.timer(2.0, WeakCall(self._preload_achievements))
- # Let's ask the server for a 'time-to-beat' value.
- levelname = self._get_coop_level_name()
- campaign = self.session.campaign
- assert campaign is not None
- config_str = (str(len(self.players)) + 'p' + campaign.getlevel(
- self.settings_raw['name']).get_score_version_string().replace(
- ' ', '_'))
- _ba.get_scores_to_beat(levelname, config_str,
- WeakCall(self._on_got_scores_to_beat))
-
- def _on_got_scores_to_beat(self, scores: list[dict[str, Any]]) -> None:
- pass
-
def _show_standard_scores_to_beat_ui(self,
scores: list[dict[str, Any]]) -> None:
from efro.util import asserttype
diff --git a/assets/src/ba_data/python/ba/_error.py b/assets/src/ba_data/python/ba/_error.py
index bb82a78a..5e6aba42 100644
--- a/assets/src/ba_data/python/ba/_error.py
+++ b/assets/src/ba_data/python/ba/_error.py
@@ -125,6 +125,11 @@ class WidgetNotFoundError(NotFoundError):
"""
+# TODO: Should integrate some sort of context printing into our
+# log handling so we can just use logging.exception() and kill these
+# two functions.
+
+
def print_exception(*args: Any, **keywds: Any) -> None:
"""Print info about an exception along with pertinent context state.
diff --git a/assets/src/ba_data/python/ba/_hooks.py b/assets/src/ba_data/python/ba/_hooks.py
index 9d103449..ab7e36cd 100644
--- a/assets/src/ba_data/python/ba/_hooks.py
+++ b/assets/src/ba_data/python/ba/_hooks.py
@@ -28,7 +28,7 @@ def finish_bootstrapping() -> None:
assert _ba.in_logic_thread()
# Kick off our asyncio event handling, allowing us to use coroutines
- # in our game thread alongside our internal event handling.
+ # in our logic thread alongside our internal event handling.
# setup_asyncio()
# Ok, bootstrapping is done; time to get the show started.
diff --git a/assets/src/ba_data/python/ba/_meta.py b/assets/src/ba_data/python/ba/_meta.py
index 40f75619..1faca382 100644
--- a/assets/src/ba_data/python/ba/_meta.py
+++ b/assets/src/ba_data/python/ba/_meta.py
@@ -192,13 +192,13 @@ class MetadataSubsystem:
color=(1, 0, 0))
_ba.playsound(_ba.getsound('error'))
if results.warnings:
- _ba.log(textwrap.indent('\n'.join(results.warnings),
- 'Warning (meta-scan): '),
- to_server=False)
+ allwarnings = textwrap.indent('\n'.join(results.warnings),
+ 'Warning (meta-scan): ')
+ logging.warning(allwarnings)
if results.errors:
- _ba.log(
- textwrap.indent('\n'.join(results.errors),
- 'Error (meta-scan): '))
+ allerrors = textwrap.indent('\n'.join(results.errors),
+ 'Error (meta-scan): ')
+ logging.error(allerrors)
# Let the game know we're done.
assert self._scan_complete_cb is not None
diff --git a/assets/src/ba_data/python/ba/_playlist.py b/assets/src/ba_data/python/ba/_playlist.py
index 1550934c..5518601a 100644
--- a/assets/src/ba_data/python/ba/_playlist.py
+++ b/assets/src/ba_data/python/ba/_playlist.py
@@ -5,6 +5,7 @@
from __future__ import annotations
import copy
+import logging
from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
@@ -29,7 +30,6 @@ def filter_playlist(playlist: PlaylistType,
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements
- import _ba
from ba._map import get_filtered_map_name
from ba._store import get_unowned_maps, get_unowned_game_types
from ba._general import getclass
@@ -140,8 +140,8 @@ def filter_playlist(playlist: PlaylistType,
entry['settings'][setting.name] = setting.default
goodlist.append(entry)
except ImportError as exc:
- _ba.log(f'Import failed while scanning playlist \'{name}\': {exc}',
- to_server=False)
+ logging.warning('Import failed while scanning playlist \'%s\': %s',
+ name, exc)
except Exception:
from ba import _error
_error.print_exception()
diff --git a/assets/src/ba_data/python/ba/_plugin.py b/assets/src/ba_data/python/ba/_plugin.py
index c4702045..d05cdbe9 100644
--- a/assets/src/ba_data/python/ba/_plugin.py
+++ b/assets/src/ba_data/python/ba/_plugin.py
@@ -4,6 +4,7 @@
from __future__ import annotations
+import logging
from typing import TYPE_CHECKING
from dataclasses import dataclass
@@ -127,8 +128,7 @@ class PluginSubsystem:
subs=[('${PLUGIN}', plugkey),
('${ERROR}', str(exc))]),
color=(1, 0, 0))
- _ba.log(f"Error loading plugin class '{plugkey}': {exc}",
- to_server=False)
+ logging.exception("Error loading plugin class '%s'", plugkey)
continue
try:
plugin = cls()
@@ -155,10 +155,8 @@ class PluginSubsystem:
color=(1, 1, 0),
)
plugnames = ', '.join(disappeared_plugs)
- _ba.log(
- f'{len(disappeared_plugs)} plugin(s) no longer found:'
- f' {plugnames}.',
- to_server=False)
+ logging.warning('%d plugin(s) no longer found: %s.',
+ len(disappeared_plugs), plugnames)
for goneplug in disappeared_plugs:
del _ba.app.config['Plugins'][goneplug]
_ba.app.config.commit()
diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py
index ebc7f20d..8c8ed981 100644
--- a/assets/src/ba_data/python/ba/_servermode.py
+++ b/assets/src/ba_data/python/ba/_servermode.py
@@ -5,6 +5,7 @@ from __future__ import annotations
import sys
import time
+import logging
from typing import TYPE_CHECKING
from efro.terminal import Clr
@@ -334,11 +335,11 @@ class ServerController:
if self._first_run:
curtimestr = time.strftime('%c')
- _ba.log(
+ startupmsg = (
f'{Clr.BLD}{Clr.BLU}{_ba.appnameupper()} {app.version}'
f' ({app.build_number})'
- f' entering server-mode {curtimestr}{Clr.RST}',
- to_server=False)
+ f' entering server-mode {curtimestr}{Clr.RST}')
+ logging.info(startupmsg)
if sessiontype is FreeForAllSession:
appcfg['Free-for-All Playlist Selection'] = self._playlist_name
diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py
index d5b47820..fdf99803 100644
--- a/assets/src/ba_data/python/ba/internal.py
+++ b/assets/src/ba_data/python/ba/internal.py
@@ -9,16 +9,16 @@ defensively) in mods.
from __future__ import annotations
from _ba import (
- get_scores_to_beat, show_online_score_ui, set_ui_input_device,
- is_party_icon_visible, getinputdevice, add_clean_frame_callback,
- unlock_all_input, increment_analytics_count, set_debug_speed_exponent,
- get_special_widget, get_qrcode_texture, get_string_height,
- get_string_width, show_app_invite, appnameupper, lock_all_input,
- open_file_externally, fade_screen, appname, have_incentivized_ad,
- has_video_ads, workspaces_in_use, set_party_icon_always_visible,
- connect_to_party, get_game_port, end_host_scanning, host_scan_cycle,
- charstr, get_public_party_enabled, get_public_party_max_size,
- set_public_party_name, set_public_party_max_size, set_authenticate_clients,
+ show_online_score_ui, set_ui_input_device, is_party_icon_visible,
+ getinputdevice, add_clean_frame_callback, unlock_all_input,
+ increment_analytics_count, set_debug_speed_exponent, get_special_widget,
+ get_qrcode_texture, get_string_height, get_string_width, show_app_invite,
+ appnameupper, lock_all_input, open_file_externally, fade_screen, appname,
+ have_incentivized_ad, has_video_ads, workspaces_in_use,
+ set_party_icon_always_visible, connect_to_party, get_game_port,
+ end_host_scanning, host_scan_cycle, charstr, get_public_party_enabled,
+ get_public_party_max_size, set_public_party_name,
+ set_public_party_max_size, set_authenticate_clients,
set_public_party_enabled, reset_random_player_names, new_host_session,
get_foreground_host_session, get_local_active_input_devices_count,
get_ui_input_device, is_in_replay, set_replay_speed_exponent,
@@ -78,7 +78,6 @@ from ba._internal import (
sign_out_v1, sign_in_v1, mark_config_dirty)
__all__ = [
- 'get_scores_to_beat',
'show_online_score_ui',
'set_ui_input_device',
'is_party_icon_visible',
diff --git a/assets/src/ba_data/python/bastd/activity/coopjoin.py b/assets/src/ba_data/python/bastd/activity/coopjoin.py
index 3e60af76..b8cc8af5 100644
--- a/assets/src/ba_data/python/bastd/activity/coopjoin.py
+++ b/assets/src/ba_data/python/bastd/activity/coopjoin.py
@@ -10,7 +10,7 @@ import ba
from ba.internal import JoinActivity
if TYPE_CHECKING:
- from typing import Any, Sequence
+ pass
class CoopJoinActivity(JoinActivity):
@@ -24,17 +24,6 @@ class CoopJoinActivity(JoinActivity):
session = self.session
assert isinstance(session, ba.CoopSession)
- # Let's show a list of scores-to-beat for 1 player at least.
- assert session.campaign is not None
- level_name_full = (session.campaign.name + ':' +
- session.campaign_level_name)
- config_str = ('1p' + session.campaign.getlevel(
- session.campaign_level_name).get_score_version_string().replace(
- ' ', '_'))
- ba.internal.get_scores_to_beat(
- level_name_full, config_str,
- ba.WeakCall(self._on_got_scores_to_beat))
-
def on_transition_in(self) -> None:
from bastd.actor.controlsguide import ControlsGuide
from bastd.actor.text import Text
@@ -53,143 +42,61 @@ class CoopJoinActivity(JoinActivity):
position=(0, -95)).autoretain()
ControlsGuide(delay=1.0).autoretain()
- def _on_got_scores_to_beat(self,
- scores: list[dict[str, Any]] | None) -> None:
- # pylint: disable=too-many-locals
- # pylint: disable=too-many-statements
- from efro.util import asserttype
- from bastd.actor.text import Text
+ ba.pushcall(self._show_remaining_achievements)
- # Sort by originating date so that the most recent is first.
- if scores is not None:
- scores.sort(reverse=True,
- key=lambda score: asserttype(score['time'], int))
+ def _show_remaining_achievements(self) -> None:
+ from bastd.actor.text import Text
# We only show achievements and challenges for CoopGameActivities.
session = self.session
assert isinstance(session, ba.CoopSession)
gameinstance = session.get_current_game_instance()
- if isinstance(gameinstance, ba.CoopGameActivity):
- score_type = gameinstance.get_score_type()
- if scores is not None:
- achievement_challenges = [
- a for a in scores if a['type'] == 'achievement_challenge'
- ]
- score_challenges = [
- a for a in scores if a['type'] == 'score_challenge'
- ]
- else:
- achievement_challenges = score_challenges = []
+ if not isinstance(gameinstance, ba.CoopGameActivity):
+ return
- delay = 1.0
- vpos = -140.0
- spacing = 25
- delay_inc = 0.1
+ delay = 1.0
+ vpos = -140.0
- def _add_t(
- text: str | ba.Lstr,
- h_offs: float = 0.0,
- scale: float = 1.0,
- color: Sequence[float] = (1.0, 1.0, 1.0, 0.46)
- ) -> None:
- Text(text,
- scale=scale * 0.76,
- h_align=Text.HAlign.LEFT,
+ # Now list our remaining achievements for this level.
+ assert self.session.campaign is not None
+ assert isinstance(self.session, ba.CoopSession)
+ levelname = (self.session.campaign.name + ':' +
+ self.session.campaign_level_name)
+ ts_h_offs = 60
+
+ if not (ba.app.demo_mode or ba.app.arcade_mode):
+ achievements = [
+ a for a in ba.app.ach.achievements_for_coop_level(levelname)
+ if not a.complete
+ ]
+ have_achievements = bool(achievements)
+ achievements = [a for a in achievements if not a.complete]
+ vrmode = ba.app.vr_mode
+ if have_achievements:
+ Text(ba.Lstr(resource='achievementsRemainingText'),
+ host_only=True,
+ position=(ts_h_offs - 10, vpos),
+ transition=Text.Transition.FADE_IN,
+ scale=1.1 * 0.76,
h_attach=Text.HAttach.LEFT,
v_attach=Text.VAttach.TOP,
- transition=Text.Transition.FADE_IN,
- transition_delay=delay,
- color=color,
- position=(60 + h_offs, vpos)).autoretain()
-
- if score_challenges:
- _add_t(ba.Lstr(value='${A}:',
- subs=[('${A}',
- ba.Lstr(resource='scoreChallengesText'))
- ]),
- scale=1.1)
- delay += delay_inc
- vpos -= spacing
- for chal in score_challenges:
- _add_t(str(chal['value'] if score_type == 'points' else ba.
- timestring(int(chal['value']) * 10,
- timeformat=ba.TimeFormat.MILLISECONDS
- ).evaluate()) + ' (1 player)',
- h_offs=30,
- color=(0.9, 0.7, 1.0, 0.8))
- delay += delay_inc
- vpos -= 0.6 * spacing
- _add_t(chal['player'],
- h_offs=40,
- color=(0.8, 1, 0.8, 0.6),
- scale=0.8)
- delay += delay_inc
- vpos -= 1.2 * spacing
- vpos -= 0.5 * spacing
-
- if achievement_challenges:
- _add_t(ba.Lstr(
- value='${A}:',
- subs=[('${A}',
- ba.Lstr(resource='achievementChallengesText'))]),
- scale=1.1)
- delay += delay_inc
- vpos -= spacing
- for chal in achievement_challenges:
- _add_t(str(chal['value']),
- h_offs=30,
- color=(0.9, 0.7, 1.0, 0.8))
- delay += delay_inc
- vpos -= 0.6 * spacing
- _add_t(chal['player'],
- h_offs=40,
- color=(0.8, 1, 0.8, 0.6),
- scale=0.8)
- delay += delay_inc
- vpos -= 1.2 * spacing
- vpos -= 0.5 * spacing
-
- # Now list our remaining achievements for this level.
- assert self.session.campaign is not None
- assert isinstance(self.session, ba.CoopSession)
- levelname = (self.session.campaign.name + ':' +
- self.session.campaign_level_name)
- ts_h_offs = 60
-
- if not (ba.app.demo_mode or ba.app.arcade_mode):
- achievements = [
- a
- for a in ba.app.ach.achievements_for_coop_level(levelname)
- if not a.complete
- ]
- have_achievements = bool(achievements)
- achievements = [a for a in achievements if not a.complete]
- vrmode = ba.app.vr_mode
- if have_achievements:
- Text(ba.Lstr(resource='achievementsRemainingText'),
+ color=(1, 1, 1.2, 1) if vrmode else (0.8, 0.8, 1, 1),
+ shadow=1.0,
+ flatness=1.0 if vrmode else 0.6,
+ transition_delay=delay).autoretain()
+ hval = ts_h_offs + 50
+ vpos -= 35
+ for ach in achievements:
+ delay += 0.05
+ ach.create_display(hval, vpos, delay, style='in_game')
+ vpos -= 55
+ if not achievements:
+ Text(ba.Lstr(resource='noAchievementsRemainingText'),
host_only=True,
- position=(ts_h_offs - 10, vpos),
+ position=(ts_h_offs + 15, vpos + 10),
transition=Text.Transition.FADE_IN,
- scale=1.1 * 0.76,
+ scale=0.7,
h_attach=Text.HAttach.LEFT,
v_attach=Text.VAttach.TOP,
- color=(1, 1, 1.2, 1) if vrmode else (0.8, 0.8, 1, 1),
- shadow=1.0,
- flatness=1.0 if vrmode else 0.6,
- transition_delay=delay).autoretain()
- hval = ts_h_offs + 50
- vpos -= 35
- for ach in achievements:
- delay += 0.05
- ach.create_display(hval, vpos, delay, style='in_game')
- vpos -= 55
- if not achievements:
- Text(ba.Lstr(resource='noAchievementsRemainingText'),
- host_only=True,
- position=(ts_h_offs + 15, vpos + 10),
- transition=Text.Transition.FADE_IN,
- scale=0.7,
- h_attach=Text.HAttach.LEFT,
- v_attach=Text.VAttach.TOP,
- color=(1, 1, 1, 0.5),
- transition_delay=delay + 0.5).autoretain()
+ color=(1, 1, 1, 0.5),
+ transition_delay=delay + 0.5).autoretain()
diff --git a/assets/src/ba_data/python/bastd/game/easteregghunt.py b/assets/src/ba_data/python/bastd/game/easteregghunt.py
index 3372522d..1dc4de02 100644
--- a/assets/src/ba_data/python/bastd/game/easteregghunt.py
+++ b/assets/src/ba_data/python/bastd/game/easteregghunt.py
@@ -44,7 +44,10 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
name = 'Easter Egg Hunt'
description = 'Gather eggs!'
- available_settings = [ba.BoolSetting('Pro Mode', default=False)]
+ available_settings = [
+ ba.BoolSetting('Pro Mode', default=False),
+ ba.BoolSetting('Epic Mode', default=False),
+ ]
scoreconfig = ba.ScoreConfig(label='Score', scoretype=ba.ScoreType.POINTS)
# We're currently hard-coded for one map.
@@ -70,6 +73,7 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
self.egg_tex_3 = ba.gettexture('eggTex3')
self._collect_sound = ba.getsound('powerup01')
self._pro_mode = settings.get('Pro Mode', False)
+ self._epic_mode = settings.get('Epic Mode', False)
self._max_eggs = 1.0
self.egg_material = ba.Material()
self.egg_material.add_actions(
@@ -81,7 +85,9 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
self._bots: SpazBotSet | None = None
# Base class overrides
- self.default_music = ba.MusicType.FORWARD_MARCH
+ self.slow_motion = self._epic_mode
+ self.default_music = (ba.MusicType.EPIC if self._epic_mode else
+ ba.MusicType.FORWARD_MARCH)
def on_team_join(self, team: Team) -> None:
if self.has_begun():
diff --git a/assets/src/ba_data/python/bastd/game/football.py b/assets/src/ba_data/python/bastd/game/football.py
index 263f8e3e..2faed91f 100644
--- a/assets/src/ba_data/python/bastd/game/football.py
+++ b/assets/src/ba_data/python/bastd/game/football.py
@@ -335,6 +335,8 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
scoreconfig = ba.ScoreConfig(scoretype=ba.ScoreType.MILLISECONDS,
version='B')
+ default_music = ba.MusicType.FOOTBALL
+
# FIXME: Need to update co-op games to use getscoreconfig.
def get_score_type(self) -> str:
return 'time'
diff --git a/ballisticacore-cmake/.idea/dictionaries/ericf.xml b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
index 160953f7..21c6ae55 100644
--- a/ballisticacore-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticacore-cmake/.idea/dictionaries/ericf.xml
@@ -41,7 +41,9 @@
airborn
alext
alibaba
+ allerrors
allocs
+ allwarnings
alot
alphaimg
alphapixels
@@ -67,6 +69,7 @@
appnameupper
appspot
appstate
+ apptime
argsjoined
argstr
armcap
@@ -119,6 +122,7 @@
bdea
benning
bezanson
+ bgdynamics
bgra
bigendian
bilinear
@@ -226,10 +230,12 @@
classdict
classline
cleanupcheck
+ clearsign
clientid
clientinfo
clienttobasn
clipcount
+ cmakelist
cmath
cmds
cmdvals
@@ -697,6 +703,7 @@
leaderboard
leaderboards
lenval
+ levelno
lgui
lhalf
libbz
@@ -848,6 +855,7 @@
netcode
netplay
nettest
+ networkwrite
newactivity
newchild
newimg
@@ -1239,6 +1247,7 @@
startpos
startsplits
starttime
+ startupmsg
startx
starty
statestr
@@ -1258,6 +1267,7 @@
strdup
stringi
stringified
+ stringifying
strlen
strs
strtof
diff --git a/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml b/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
index ffa57a65..bccdbc35 100644
--- a/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
+++ b/ballisticacore-cmake/.idea/inspectionProfiles/Project_Default.xml
@@ -58,6 +58,7 @@
+
diff --git a/ballisticacore-cmake/CMakeLists.txt b/ballisticacore-cmake/CMakeLists.txt
index 0f58aa0a..77deaf38 100644
--- a/ballisticacore-cmake/CMakeLists.txt
+++ b/ballisticacore-cmake/CMakeLists.txt
@@ -210,6 +210,40 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/app/app_flavor_vr.h
${BA_SRC_ROOT}/ballistica/app/stress_test.cc
${BA_SRC_ROOT}/ballistica/app/stress_test.h
+ ${BA_SRC_ROOT}/ballistica/assets/assets.cc
+ ${BA_SRC_ROOT}/ballistica/assets/assets.h
+ ${BA_SRC_ROOT}/ballistica/assets/assets_server.cc
+ ${BA_SRC_ROOT}/ballistica/assets/assets_server.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/asset_component.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/asset_component.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/collide_model.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/collide_model.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/cube_map_texture.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/cube_map_texture.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/data.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/model.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/model.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/sound.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/sound.h
+ ${BA_SRC_ROOT}/ballistica/assets/component/texture.cc
+ ${BA_SRC_ROOT}/ballistica/assets/component/texture.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/asset_component_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/asset_component_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/collide_model_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/collide_model_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/data_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/data_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/model_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/model_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/model_renderer_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/sound_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/sound_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/texture_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/texture_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/texture_preload_data.cc
+ ${BA_SRC_ROOT}/ballistica/assets/data/texture_preload_data.h
+ ${BA_SRC_ROOT}/ballistica/assets/data/texture_renderer_data.h
${BA_SRC_ROOT}/ballistica/audio/al_sys.cc
${BA_SRC_ROOT}/ballistica/audio/al_sys.h
${BA_SRC_ROOT}/ballistica/audio/audio.cc
@@ -298,43 +332,6 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/dynamics/part.h
${BA_SRC_ROOT}/ballistica/dynamics/rigid_body.cc
${BA_SRC_ROOT}/ballistica/dynamics/rigid_body.h
- ${BA_SRC_ROOT}/ballistica/game/account.cc
- ${BA_SRC_ROOT}/ballistica/game/account.h
- ${BA_SRC_ROOT}/ballistica/game/client_controller_interface.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_set.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_set.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client_udp.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_client_udp.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host.h
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host_udp.cc
- ${BA_SRC_ROOT}/ballistica/game/connection/connection_to_host_udp.h
- ${BA_SRC_ROOT}/ballistica/game/friend_score_set.h
- ${BA_SRC_ROOT}/ballistica/game/game.cc
- ${BA_SRC_ROOT}/ballistica/game/game.h
- ${BA_SRC_ROOT}/ballistica/game/game_stream.cc
- ${BA_SRC_ROOT}/ballistica/game/game_stream.h
- ${BA_SRC_ROOT}/ballistica/game/host_activity.cc
- ${BA_SRC_ROOT}/ballistica/game/host_activity.h
- ${BA_SRC_ROOT}/ballistica/game/player.cc
- ${BA_SRC_ROOT}/ballistica/game/player.h
- ${BA_SRC_ROOT}/ballistica/game/player_spec.cc
- ${BA_SRC_ROOT}/ballistica/game/player_spec.h
- ${BA_SRC_ROOT}/ballistica/game/score_to_beat.h
- ${BA_SRC_ROOT}/ballistica/game/session/client_session.cc
- ${BA_SRC_ROOT}/ballistica/game/session/client_session.h
- ${BA_SRC_ROOT}/ballistica/game/session/host_session.cc
- ${BA_SRC_ROOT}/ballistica/game/session/host_session.h
- ${BA_SRC_ROOT}/ballistica/game/session/net_client_session.cc
- ${BA_SRC_ROOT}/ballistica/game/session/net_client_session.h
- ${BA_SRC_ROOT}/ballistica/game/session/replay_client_session.cc
- ${BA_SRC_ROOT}/ballistica/game/session/replay_client_session.h
- ${BA_SRC_ROOT}/ballistica/game/session/session.cc
- ${BA_SRC_ROOT}/ballistica/game/session/session.h
${BA_SRC_ROOT}/ballistica/generic/base64.cc
${BA_SRC_ROOT}/ballistica/generic/base64.h
${BA_SRC_ROOT}/ballistica/generic/buffer.h
@@ -453,9 +450,41 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/input/input.h
${BA_SRC_ROOT}/ballistica/input/remote_app.cc
${BA_SRC_ROOT}/ballistica/input/remote_app.h
- ${BA_SRC_ROOT}/ballistica/input/std_input_module.cc
- ${BA_SRC_ROOT}/ballistica/input/std_input_module.h
${BA_SRC_ROOT}/ballistica/internal/app_internal.h
+ ${BA_SRC_ROOT}/ballistica/logic/client_controller_interface.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_set.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_set.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_client.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_client.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_client_udp.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_client_udp.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host.h
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host_udp.cc
+ ${BA_SRC_ROOT}/ballistica/logic/connection/connection_to_host_udp.h
+ ${BA_SRC_ROOT}/ballistica/logic/friend_score_set.h
+ ${BA_SRC_ROOT}/ballistica/logic/host_activity.cc
+ ${BA_SRC_ROOT}/ballistica/logic/host_activity.h
+ ${BA_SRC_ROOT}/ballistica/logic/logic.cc
+ ${BA_SRC_ROOT}/ballistica/logic/logic.h
+ ${BA_SRC_ROOT}/ballistica/logic/player.cc
+ ${BA_SRC_ROOT}/ballistica/logic/player.h
+ ${BA_SRC_ROOT}/ballistica/logic/player_spec.cc
+ ${BA_SRC_ROOT}/ballistica/logic/player_spec.h
+ ${BA_SRC_ROOT}/ballistica/logic/session/client_session.cc
+ ${BA_SRC_ROOT}/ballistica/logic/session/client_session.h
+ ${BA_SRC_ROOT}/ballistica/logic/session/host_session.cc
+ ${BA_SRC_ROOT}/ballistica/logic/session/host_session.h
+ ${BA_SRC_ROOT}/ballistica/logic/session/net_client_session.cc
+ ${BA_SRC_ROOT}/ballistica/logic/session/net_client_session.h
+ ${BA_SRC_ROOT}/ballistica/logic/session/replay_client_session.cc
+ ${BA_SRC_ROOT}/ballistica/logic/session/replay_client_session.h
+ ${BA_SRC_ROOT}/ballistica/logic/session/session.cc
+ ${BA_SRC_ROOT}/ballistica/logic/session/session.h
+ ${BA_SRC_ROOT}/ballistica/logic/v1_account.cc
+ ${BA_SRC_ROOT}/ballistica/logic/v1_account.h
${BA_SRC_ROOT}/ballistica/math/matrix44f.cc
${BA_SRC_ROOT}/ballistica/math/matrix44f.h
${BA_SRC_ROOT}/ballistica/math/point2d.h
@@ -466,44 +495,10 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/math/vector3f.cc
${BA_SRC_ROOT}/ballistica/math/vector3f.h
${BA_SRC_ROOT}/ballistica/math/vector4f.h
- ${BA_SRC_ROOT}/ballistica/media/component/collide_model.cc
- ${BA_SRC_ROOT}/ballistica/media/component/collide_model.h
- ${BA_SRC_ROOT}/ballistica/media/component/cube_map_texture.cc
- ${BA_SRC_ROOT}/ballistica/media/component/cube_map_texture.h
- ${BA_SRC_ROOT}/ballistica/media/component/data.cc
- ${BA_SRC_ROOT}/ballistica/media/component/data.h
- ${BA_SRC_ROOT}/ballistica/media/component/media_component.cc
- ${BA_SRC_ROOT}/ballistica/media/component/media_component.h
- ${BA_SRC_ROOT}/ballistica/media/component/model.cc
- ${BA_SRC_ROOT}/ballistica/media/component/model.h
- ${BA_SRC_ROOT}/ballistica/media/component/sound.cc
- ${BA_SRC_ROOT}/ballistica/media/component/sound.h
- ${BA_SRC_ROOT}/ballistica/media/component/texture.cc
- ${BA_SRC_ROOT}/ballistica/media/component/texture.h
- ${BA_SRC_ROOT}/ballistica/media/data/collide_model_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/collide_model_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/data_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/data_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/media_component_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/media_component_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/model_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/model_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/model_renderer_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/sound_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/sound_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/texture_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/texture_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/texture_preload_data.cc
- ${BA_SRC_ROOT}/ballistica/media/data/texture_preload_data.h
- ${BA_SRC_ROOT}/ballistica/media/data/texture_renderer_data.h
- ${BA_SRC_ROOT}/ballistica/media/media.cc
- ${BA_SRC_ROOT}/ballistica/media/media.h
- ${BA_SRC_ROOT}/ballistica/media/media_server.cc
- ${BA_SRC_ROOT}/ballistica/media/media_server.h
${BA_SRC_ROOT}/ballistica/networking/network_reader.cc
${BA_SRC_ROOT}/ballistica/networking/network_reader.h
- ${BA_SRC_ROOT}/ballistica/networking/network_write_module.cc
- ${BA_SRC_ROOT}/ballistica/networking/network_write_module.h
+ ${BA_SRC_ROOT}/ballistica/networking/network_writer.cc
+ ${BA_SRC_ROOT}/ballistica/networking/network_writer.h
${BA_SRC_ROOT}/ballistica/networking/networking.cc
${BA_SRC_ROOT}/ballistica/networking/networking.h
${BA_SRC_ROOT}/ballistica/networking/networking_sys.h
@@ -519,6 +514,8 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/platform/platform.h
${BA_SRC_ROOT}/ballistica/platform/sdl/sdl_app.cc
${BA_SRC_ROOT}/ballistica/platform/sdl/sdl_app.h
+ ${BA_SRC_ROOT}/ballistica/platform/stdio_console.cc
+ ${BA_SRC_ROOT}/ballistica/platform/stdio_console.h
${BA_SRC_ROOT}/ballistica/platform/windows/platform_windows.cc
${BA_SRC_ROOT}/ballistica/platform/windows/platform_windows.h
${BA_SRC_ROOT}/ballistica/python/class/python_class.cc
@@ -557,14 +554,14 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/python/class/python_class_widget.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_app.cc
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_app.h
+ ${BA_SRC_ROOT}/ballistica/python/methods/python_methods_assets.cc
+ ${BA_SRC_ROOT}/ballistica/python/methods/python_methods_assets.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_gameplay.cc
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_gameplay.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_graphics.cc
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_graphics.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_input.cc
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_input.h
- ${BA_SRC_ROOT}/ballistica/python/methods/python_methods_media.cc
- ${BA_SRC_ROOT}/ballistica/python/methods/python_methods_media.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_networking.cc
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_networking.h
${BA_SRC_ROOT}/ballistica/python/methods/python_methods_system.cc
@@ -638,6 +635,10 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/scene/node/time_display_node.h
${BA_SRC_ROOT}/ballistica/scene/scene.cc
${BA_SRC_ROOT}/ballistica/scene/scene.h
+ ${BA_SRC_ROOT}/ballistica/scene/scene_stream.cc
+ ${BA_SRC_ROOT}/ballistica/scene/scene_stream.h
+ ${BA_SRC_ROOT}/ballistica/scene/v1/scene_v1.cc
+ ${BA_SRC_ROOT}/ballistica/scene/v1/scene_v1.h
${BA_SRC_ROOT}/ballistica/ui/console.cc
${BA_SRC_ROOT}/ballistica/ui/console.h
${BA_SRC_ROOT}/ballistica/ui/root_ui.cc
diff --git a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj
index 06cae3fd..8f4b7c5a 100644
--- a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj
+++ b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj
@@ -201,6 +201,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -289,43 +323,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -444,9 +441,41 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -457,44 +486,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -510,6 +505,8 @@
+
+
@@ -548,14 +545,14 @@
+
+
-
-
@@ -629,6 +626,10 @@
+
+
+
+
diff --git a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters
index 0db00d48..4430ba75 100644
--- a/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters
+++ b/ballisticacore-windows/Generic/BallisticaCoreGeneric.vcxproj.filters
@@ -37,6 +37,108 @@
ballistica\app
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
ballistica\audio
@@ -301,117 +403,6 @@
ballistica\dynamics
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
ballistica\generic
@@ -766,15 +757,111 @@
ballistica\input
-
- ballistica\input
-
-
- ballistica\input
-
ballistica\internal
+
+ ballistica\logic
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
ballistica\math
@@ -805,118 +892,16 @@
ballistica\math
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media
-
-
- ballistica\media
-
-
- ballistica\media
-
-
- ballistica\media
-
ballistica\networking
ballistica\networking
-
+
ballistica\networking
-
+
ballistica\networking
@@ -964,6 +949,12 @@
ballistica\platform\sdl
+
+ ballistica\platform
+
+
+ ballistica\platform
+
ballistica\platform\windows
@@ -1078,6 +1069,12 @@
ballistica\python\methods
+
+ ballistica\python\methods
+
+
+ ballistica\python\methods
+
ballistica\python\methods
@@ -1096,12 +1093,6 @@
ballistica\python\methods
-
- ballistica\python\methods
-
-
- ballistica\python\methods
-
ballistica\python\methods
@@ -1321,6 +1312,18 @@
ballistica\scene
+
+ ballistica\scene
+
+
+ ballistica\scene
+
+
+ ballistica\scene\v1
+
+
+ ballistica\scene\v1
+
ballistica\ui
@@ -1646,15 +1649,15 @@
+
+
+
-
-
-
@@ -1665,10 +1668,10 @@
+
+
+
-
-
-
@@ -1680,6 +1683,7 @@
+
diff --git a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj
index ccbacee1..f1654fcf 100644
--- a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj
+++ b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj
@@ -196,6 +196,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -284,43 +318,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -439,9 +436,41 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -452,44 +481,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -505,6 +500,8 @@
+
+
@@ -543,14 +540,14 @@
+
+
-
-
@@ -624,6 +621,10 @@
+
+
+
+
diff --git a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters
index 0db00d48..4430ba75 100644
--- a/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters
+++ b/ballisticacore-windows/Headless/BallisticaCoreHeadless.vcxproj.filters
@@ -37,6 +37,108 @@
ballistica\app
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\component
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
+
+ ballistica\assets\data
+
ballistica\audio
@@ -301,117 +403,6 @@
ballistica\dynamics
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game\connection
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
-
- ballistica\game\session
-
ballistica\generic
@@ -766,15 +757,111 @@
ballistica\input
-
- ballistica\input
-
-
- ballistica\input
-
ballistica\internal
+
+ ballistica\logic
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic\connection
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic\session
+
+
+ ballistica\logic
+
+
+ ballistica\logic
+
ballistica\math
@@ -805,118 +892,16 @@
ballistica\math
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\component
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media\data
-
-
- ballistica\media
-
-
- ballistica\media
-
-
- ballistica\media
-
-
- ballistica\media
-
ballistica\networking
ballistica\networking
-
+
ballistica\networking
-
+
ballistica\networking
@@ -964,6 +949,12 @@
ballistica\platform\sdl
+
+ ballistica\platform
+
+
+ ballistica\platform
+
ballistica\platform\windows
@@ -1078,6 +1069,12 @@
ballistica\python\methods
+
+ ballistica\python\methods
+
+
+ ballistica\python\methods
+
ballistica\python\methods
@@ -1096,12 +1093,6 @@
ballistica\python\methods
-
- ballistica\python\methods
-
-
- ballistica\python\methods
-
ballistica\python\methods
@@ -1321,6 +1312,18 @@
ballistica\scene
+
+ ballistica\scene
+
+
+ ballistica\scene
+
+
+ ballistica\scene\v1
+
+
+ ballistica\scene\v1
+
ballistica\ui
@@ -1646,15 +1649,15 @@
+
+
+
-
-
-
@@ -1665,10 +1668,10 @@
+
+
+
-
-
-
@@ -1680,6 +1683,7 @@
+
diff --git a/src/ballistica/app/app.h b/src/ballistica/app/app.h
index c3d3546c..754d42e1 100644
--- a/src/ballistica/app/app.h
+++ b/src/ballistica/app/app.h
@@ -13,24 +13,15 @@
namespace ballistica {
-// The first thing the engine does is allocate an instance of this as g_globals.
-// As much as possible, previously static/global values should be moved to here,
-// ideally as a temporary measure until they can be placed as non-static members
-// in the proper classes.
-// Any use of non-trivial global/static values such as class instances should be
-// avoided since it can introduce ambiguities during init and teardown.
-// For more explanation, see the 'Static and Global Variables' section in the
-// Google C++ Style Guide.
+// The first thing the engine does is allocate an instance of this as g_app.
class App {
public:
App(int argc, char** argv);
- /// Program argument count (on applicable platforms).
+ // The following are misc values that should be migrated to applicable
+ // subsystem classes.
int argc{};
-
- /// Program argument values (on applicable platforms).
char** argv{};
-
bool threads_paused{};
std::unordered_map node_types;
std::unordered_map node_types_by_id;
@@ -41,10 +32,10 @@ class App {
std::vector pausable_threads;
TouchInput* touch_input{};
std::string console_startup_messages;
- std::mutex log_mutex;
- std::string log;
- bool put_log{};
- bool log_full{};
+ std::mutex v1_cloud_log_mutex;
+ std::string v1_cloud_log;
+ bool did_put_v1_cloud_log{};
+ bool v1_cloud_log_full{};
int master_server_source{0};
int session_count{};
bool shutting_down{};
diff --git a/src/ballistica/app/app_config.cc b/src/ballistica/app/app_config.cc
index b529ec9f..cf6f0b23 100644
--- a/src/ballistica/app/app_config.cc
+++ b/src/ballistica/app/app_config.cc
@@ -8,8 +8,6 @@
namespace ballistica {
-void AppConfig::Init() { new AppConfig(); }
-
auto AppConfig::Entry::FloatValue() const -> float {
throw Exception("not a float entry");
}
@@ -137,12 +135,7 @@ class AppConfig::BoolEntry : public AppConfig::Entry {
bool default_value_{};
};
-AppConfig::AppConfig() {
- // (We're a singleton).
- assert(g_app_config == nullptr);
- g_app_config = this;
- SetupEntries();
-}
+AppConfig::AppConfig() { SetupEntries(); }
// Clion think all calls of this are unreachable.
#pragma clang diagnostic push
diff --git a/src/ballistica/app/app_config.h b/src/ballistica/app/app_config.h
index 6e3303e7..9a970b4a 100644
--- a/src/ballistica/app/app_config.h
+++ b/src/ballistica/app/app_config.h
@@ -13,7 +13,7 @@ namespace ballistica {
// This class wrangles user config values for the app.
// The underlying config data currently lives in the Python layer,
-// so at the moment these calls are only usable from the game thread,
+// so at the moment these calls are only usable from the logic thread,
// but that may change in the future.
class AppConfig {
public:
@@ -94,7 +94,6 @@ class AppConfig {
std::string name_;
};
- static void Init();
AppConfig();
// Given specific ids, returns resolved values (fastest access).
diff --git a/src/ballistica/app/app_flavor.cc b/src/ballistica/app/app_flavor.cc
index 37d59fc7..70614020 100644
--- a/src/ballistica/app/app_flavor.cc
+++ b/src/ballistica/app/app_flavor.cc
@@ -4,11 +4,11 @@
#include "ballistica/app/stress_test.h"
#include "ballistica/core/thread.h"
-#include "ballistica/game/game.h"
#include "ballistica/graphics/graphics_server.h"
#include "ballistica/graphics/renderer.h"
#include "ballistica/input/device/touch_input.h"
#include "ballistica/input/input.h"
+#include "ballistica/logic/logic.h"
#include "ballistica/networking/network_reader.h"
#include "ballistica/networking/networking.h"
#include "ballistica/networking/telnet_server.h"
@@ -18,20 +18,30 @@ namespace ballistica {
AppFlavor::AppFlavor(Thread* thread)
: thread_(thread), stress_test_(std::make_unique()) {
- // assert(g_app_flavor == nullptr);
- // g_app_flavor = this;
-
// We modify some app behavior when run under the server manager.
auto* envval = getenv("BA_SERVER_WRAPPER_MANAGED");
server_wrapper_managed_ = (envval && strcmp(envval, "1") == 0);
}
void AppFlavor::PostInit() {
- // If we've got a nice themed hardware cursor, show it.
- // Otherwise, hide the hardware cursor; we'll draw it in software.
- // (need to run this in postinit because SDL/etc. may not be inited yet
- // as of AppFlavor::AppFlavor()).
- g_platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor());
+ // Sanity check: make sure asserts are stripped out of release builds
+ // (NDEBUG should do this).
+#if !BA_DEBUG_BUILD
+#ifndef NDEBUG
+#error Expected NDEBUG to be defined for release builds.
+#endif // NDEBUG
+ assert(true);
+#endif // !BA_DEBUG_BUILD
+
+ g_app->user_agent_string = g_platform->GetUserAgentString();
+
+ // Figure out where our data is and chdir there.
+ g_platform->SetupDataDirectory();
+
+ // Run these just to make sure these dirs exist.
+ // (otherwise they might not get made if nothing writes to them).
+ g_platform->GetConfigDirectory();
+ g_platform->GetUserPythonDirectory();
}
auto AppFlavor::ManagesEventLoop() const -> bool {
@@ -186,7 +196,7 @@ void AppFlavor::OnResume() {
// Also let the Python layer do what it needs to
// (starting/stopping music, etc.).
g_python->PushObjCall(Python::ObjID::kHandleAppResumeCall);
- g_game->PushOnAppResumeCall();
+ g_logic->PushOnAppResumeCall();
g_graphics->SetGyroEnabled(true);
@@ -201,7 +211,7 @@ void AppFlavor::OnResume() {
// If we've been completely backgrounded,
// send a menu-press command to the game; this will
// bring up a pause menu if we're in the game/etc.
- g_game->PushMainMenuPressCall(nullptr);
+ g_logic->PushMainMenuPressCall(nullptr);
}
}
@@ -268,11 +278,7 @@ void AppFlavor::PushNetworkSetupCall(int port, int telnet_port,
const std::string& telnet_password) {
thread()->PushCall([port, telnet_port, enable_telnet, telnet_password] {
assert(InMainThread());
- // Kick these off if they don't exist.
- // (do we want to support changing ports on existing ones?)
- if (g_network_reader == nullptr) {
- new NetworkReader(port);
- }
+ g_network_reader->SetPort(port);
if (g_app->telnet_server == nullptr && enable_telnet) {
new TelnetServer(telnet_port);
assert(g_app->telnet_server);
@@ -291,15 +297,6 @@ void AppFlavor::PushPurchaseAckCall(const std::string& purchase,
[purchase, order_id] { g_platform->PurchaseAck(purchase, order_id); });
}
-void AppFlavor::PushGetScoresToBeatCall(const std::string& level,
- const std::string& config,
- void* py_callback) {
- thread()->PushCall([level, config, py_callback] {
- assert(InMainThread());
- g_platform->GetScoresToBeat(level, config, py_callback);
- });
-}
-
void AppFlavor::PushPurchaseCall(const std::string& item) {
thread()->PushCall([item] {
assert(InMainThread());
@@ -366,10 +363,31 @@ void AppFlavor::PushResetAchievementsCall() {
thread()->PushCall([] { g_platform->ResetAchievements(); });
}
-void AppFlavor::OnBootstrapComplete() {
+void AppFlavor::OnAppStart() {
assert(InMainThread());
assert(g_input);
+ // If we're running in a terminal, print some info.
+ // if (g_platform->is_stdin_a_terminal()) {
+ {
+ char buffer[256];
+ if (g_buildconfig.headless_build()) {
+ snprintf(buffer, sizeof(buffer), "BallisticaCore Headless %s build %d.",
+ kAppVersion, kAppBuildNumber);
+ } else {
+ snprintf(buffer, sizeof(buffer), "BallisticaCore %s build %d.",
+ kAppVersion, kAppBuildNumber);
+ }
+ Log(LogLevel::kInfo, buffer);
+ }
+ // }
+
+ // If we've got a nice themed hardware cursor, show it.
+ // Otherwise, hide the hardware cursor; we'll draw it in software.
+ // (need to run this in postinit because SDL/etc. may not be inited yet
+ // as of AppFlavor::AppFlavor()).
+ g_platform->SetHardwareCursorVisible(g_buildconfig.hardware_cursor());
+
if (!HeadlessMode()) {
// On desktop systems we just assume keyboard input exists and add it
// immediately.
diff --git a/src/ballistica/app/app_flavor.h b/src/ballistica/app/app_flavor.h
index 14688fb4..fb1f013a 100644
--- a/src/ballistica/app/app_flavor.h
+++ b/src/ballistica/app/app_flavor.h
@@ -93,7 +93,7 @@ class AppFlavor {
return server_wrapper_managed_;
}
- virtual auto OnBootstrapComplete() -> void;
+ virtual auto OnAppStart() -> void;
// Deferred calls that can be made from other threads.
@@ -108,9 +108,6 @@ class AppFlavor {
const std::string& game_version, int64_t score)
-> void;
auto PushAchievementReportCall(const std::string& achievement) -> void;
- auto PushGetScoresToBeatCall(const std::string& level,
- const std::string& config, void* py_callback)
- -> void;
auto PushOpenURLCall(const std::string& url) -> void;
auto PushStringEditCall(const std::string& name, const std::string& value,
int max_chars) -> void;
diff --git a/src/ballistica/app/app_flavor_vr.cc b/src/ballistica/app/app_flavor_vr.cc
index 129d8b51..4fa5f7a6 100644
--- a/src/ballistica/app/app_flavor_vr.cc
+++ b/src/ballistica/app/app_flavor_vr.cc
@@ -4,9 +4,9 @@
#include "ballistica/app/app_flavor_vr.h"
#include "ballistica/core/thread.h"
-#include "ballistica/game/game.h"
#include "ballistica/graphics/graphics_server.h"
#include "ballistica/graphics/renderer.h"
+#include "ballistica/logic/logic.h"
namespace ballistica {
@@ -87,7 +87,7 @@ auto AppFlavorVR::VRSetHands(const VRHandsState& state) -> void {
renderer->VRSetHands(state);
// ALSO ship it off to the game/ui thread to actually handle input from it.
- g_game->PushVRHandsState(state);
+ g_logic->PushVRHandsState(state);
}
auto AppFlavorVR::VRDrawEye(int eye, float yaw, float pitch, float roll,
diff --git a/src/ballistica/app/stress_test.cc b/src/ballistica/app/stress_test.cc
index 0dbea11a..dd63eb23 100644
--- a/src/ballistica/app/stress_test.cc
+++ b/src/ballistica/app/stress_test.cc
@@ -76,13 +76,13 @@ void StressTest::Update() {
uint32_t texture_count = 0;
uint32_t sound_count = 0;
uint32_t node_count = 0;
- if (g_media) {
- model_count = g_media->total_model_count();
- collide_model_count = g_media->total_collide_model_count();
- texture_count = g_media->total_texture_count();
- sound_count = g_media->total_sound_count();
+ if (g_assets) {
+ model_count = g_assets->total_model_count();
+ collide_model_count = g_assets->total_collide_model_count();
+ texture_count = g_assets->total_texture_count();
+ sound_count = g_assets->total_sound_count();
}
- assert(g_game);
+ assert(g_logic);
std::string mem_usage = g_platform->GetMemUsageInfo();
fprintf(stress_test_stats_file_, "%d,%.1f,%d,%d,%d,%d,%d,%s\n",
static_cast_check_fit(GetRealTime()), avg, node_count,
diff --git a/src/ballistica/media/media.cc b/src/ballistica/assets/assets.cc
similarity index 79%
rename from src/ballistica/media/media.cc
rename to src/ballistica/assets/assets.cc
index b0e280d5..8bcc5ee1 100644
--- a/src/ballistica/media/media.cc
+++ b/src/ballistica/assets/assets.cc
@@ -1,33 +1,33 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
#if !BA_OSTYPE_WINDOWS
#include
#endif
+#include "ballistica/assets/assets_server.h"
+#include "ballistica/assets/component/collide_model.h"
+#include "ballistica/assets/component/data.h"
+#include "ballistica/assets/component/model.h"
+#include "ballistica/assets/component/texture.h"
+#include "ballistica/assets/data/sound_data.h"
#include "ballistica/audio/audio_server.h"
#include "ballistica/core/thread.h"
-#include "ballistica/game/game.h"
#include "ballistica/generic/timer.h"
#include "ballistica/graphics/graphics_server.h"
#include "ballistica/graphics/text/text_packer.h"
-#include "ballistica/media/component/collide_model.h"
-#include "ballistica/media/component/data.h"
-#include "ballistica/media/component/model.h"
-#include "ballistica/media/component/texture.h"
-#include "ballistica/media/data/sound_data.h"
-#include "ballistica/media/media_server.h"
+#include "ballistica/logic/logic.h"
#include "ballistica/python/python_sys.h"
namespace ballistica {
-// Debug printing.
+// Debug printing:
#define BA_SHOW_LOADS_UNLOADS 0
#define SHOW_PRUNING_INFO 0
-// Standard prune time for unused media: 10 minutes (1000ms * 60 * 10).
-#define STANDARD_MEDIA_PRUNE_TIME 600000
+// Standard prune time for unused assets: 10 minutes (1000ms * 60 * 10).
+#define STANDARD_ASSET_PRUNE_TIME 600000
// More aggressive prune time for dynamically-generated text-textures: 10
// seconds.
@@ -35,59 +35,53 @@ namespace ballistica {
#define QR_TEXTURE_PRUNE_TIME 10000
-// How long we should spend loading media in each runPendingLoads() call.
+// How long we should spend loading assets in each runPendingLoads() call.
#define PENDING_LOAD_PROCESS_TIME 5
-void Media::Init() {
- // Just create our singleton.
- assert(g_media == nullptr);
- g_media = new Media();
-}
-
-Media::Media() {
- media_paths_.emplace_back("ba_data");
+Assets::Assets() {
+ asset_paths_.emplace_back("ba_data");
for (bool& have_pending_load : have_pending_loads_) {
have_pending_load = false;
}
}
-void Media::LoadSystemTexture(SystemTextureID id, const char* name) {
- assert(media_lists_locked_);
+void Assets::LoadSystemTexture(SystemTextureID id, const char* name) {
+ assert(asset_lists_locked_);
system_textures_.push_back(GetTextureData(name));
assert(system_textures_.size() == static_cast(id) + 1);
}
-void Media::LoadSystemCubeMapTexture(SystemCubeMapTextureID id,
- const char* name) {
- assert(media_lists_locked_);
+void Assets::LoadSystemCubeMapTexture(SystemCubeMapTextureID id,
+ const char* name) {
+ assert(asset_lists_locked_);
system_cube_map_textures_.push_back(GetCubeMapTextureData(name));
assert(system_cube_map_textures_.size() == static_cast(id) + 1);
}
-void Media::LoadSystemSound(SystemSoundID id, const char* name) {
+void Assets::LoadSystemSound(SystemSoundID id, const char* name) {
system_sounds_.push_back(GetSoundData(name));
assert(system_sounds_.size() == static_cast(id) + 1);
}
-void Media::LoadSystemData(SystemDataID id, const char* name) {
+void Assets::LoadSystemData(SystemDataID id, const char* name) {
system_datas_.push_back(GetDataData(name));
assert(system_datas_.size() == static_cast(id) + 1);
}
-void Media::LoadSystemModel(SystemModelID id, const char* name) {
+void Assets::LoadSystemModel(SystemModelID id, const char* name) {
system_models_.push_back(GetModelData(name));
assert(system_models_.size() == static_cast(id) + 1);
}
-void Media::LoadSystemMedia() {
+void Assets::LoadSystemAssets() {
assert(InLogicThread());
- assert(g_audio_server && g_media_server && g_graphics_server);
+ assert(g_audio_server && g_assets_server && g_graphics_server);
assert(g_graphics_server
&& g_graphics_server->texture_compression_types_are_set());
assert(g_graphics && g_graphics_server->texture_quality_set());
// Just grab the lock once for all this stuff for efficiency.
- MediaListsLock lock;
+ AssetListLock lock;
// System textures:
LoadSystemTexture(SystemTextureID::kUIAtlas, "uiAtlas");
@@ -286,26 +280,24 @@ void Media::LoadSystemMedia() {
LoadSystemModel(SystemModelID::kWing, "wing");
// Hooray!
- system_media_loaded_ = true;
+ system_assets_loaded_ = true;
}
-Media::~Media() = default;
-
-void Media::PrintLoadInfo() {
+void Assets::PrintLoadInfo() {
std::string s;
char buffer[256];
int num = 1;
// Need to lock lists while iterating over them.
- MediaListsLock lock;
- s = "Media load results: (all times in milliseconds):\n";
+ AssetListLock lock;
+ s = "Assets load results: (all times in milliseconds):\n";
snprintf(buffer, sizeof(buffer), " %-50s %10s %10s", "FILE",
"PRELOAD_TIME", "LOAD_TIME");
s += buffer;
- Log(s, true, false);
+ Log(LogLevel::kInfo, s);
millisecs_t total_preload_time = 0;
millisecs_t total_load_time = 0;
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : models_) {
millisecs_t preload_time = i.second->preload_time();
millisecs_t load_time = i.second->load_time();
@@ -315,10 +307,10 @@ void Media::PrintLoadInfo() {
i.second->GetName().c_str(),
static_cast_check_fit(preload_time),
static_cast_check_fit(load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
num++;
}
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : collide_models_) {
millisecs_t preload_time = i.second->preload_time();
millisecs_t load_time = i.second->load_time();
@@ -328,10 +320,10 @@ void Media::PrintLoadInfo() {
i.second->GetName().c_str(),
static_cast_check_fit(preload_time),
static_cast_check_fit(load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
num++;
}
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : sounds_) {
millisecs_t preload_time = i.second->preload_time();
millisecs_t load_time = i.second->load_time();
@@ -341,10 +333,10 @@ void Media::PrintLoadInfo() {
i.second->GetName().c_str(),
static_cast_check_fit(preload_time),
static_cast_check_fit(load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
num++;
}
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : datas_) {
millisecs_t preload_time = i.second->preload_time();
millisecs_t load_time = i.second->load_time();
@@ -354,10 +346,10 @@ void Media::PrintLoadInfo() {
i.second->GetName().c_str(),
static_cast_check_fit(preload_time),
static_cast_check_fit(load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
num++;
}
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : textures_) {
millisecs_t preload_time = i.second->preload_time();
millisecs_t load_time = i.second->load_time();
@@ -367,7 +359,7 @@ void Media::PrintLoadInfo() {
i.second->file_name_full().c_str(),
static_cast_check_fit(preload_time),
static_cast_check_fit(load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
num++;
}
snprintf(buffer, sizeof(buffer),
@@ -375,99 +367,100 @@ void Media::PrintLoadInfo() {
"(feeding data to OpenGL, etc): %i",
static_cast(total_preload_time),
static_cast(total_load_time));
- Log(buffer, true, false);
+ Log(LogLevel::kInfo, buffer);
}
-void Media::MarkAllMediaForLoad() {
+void Assets::MarkAllAssetsForLoad() {
assert(InLogicThread());
// Need to keep lists locked while iterating over them.
- MediaListsLock m_lock;
+ AssetListLock m_lock;
for (auto&& i : textures_) {
if (!i.second->preloaded()) {
- MediaComponentData::LockGuard lock(i.second.get());
- have_pending_loads_[static_cast(MediaType::kTexture)] = true;
+ AssetComponentData::LockGuard lock(i.second.get());
+ have_pending_loads_[static_cast(AssetType::kTexture)] = true;
MarkComponentForLoad(i.second.get());
}
}
for (auto&& i : text_textures_) {
if (!i.second->preloaded()) {
- MediaComponentData::LockGuard lock(i.second.get());
- have_pending_loads_[static_cast(MediaType::kTexture)] = true;
+ AssetComponentData::LockGuard lock(i.second.get());
+ have_pending_loads_[static_cast(AssetType::kTexture)] = true;
MarkComponentForLoad(i.second.get());
}
}
for (auto&& i : qr_textures_) {
if (!i.second->preloaded()) {
- MediaComponentData::LockGuard lock(i.second.get());
- have_pending_loads_[static_cast(MediaType::kTexture)] = true;
+ AssetComponentData::LockGuard lock(i.second.get());
+ have_pending_loads_[static_cast(AssetType::kTexture)] = true;
MarkComponentForLoad(i.second.get());
}
}
for (auto&& i : models_) {
if (!i.second->preloaded()) {
- MediaComponentData::LockGuard lock(i.second.get());
- have_pending_loads_[static_cast(MediaType::kModel)] = true;
+ AssetComponentData::LockGuard lock(i.second.get());
+ have_pending_loads_[static_cast(AssetType::kModel)] = true;
MarkComponentForLoad(i.second.get());
}
}
}
// Call this from the graphics thread to immediately unload all
-// media used by it. (for when GL context gets lost, etc).
-void Media::UnloadRendererBits(bool do_textures, bool do_models) {
+// assets used by it. (for when GL context gets lost, etc).
+void Assets::UnloadRendererBits(bool do_textures, bool do_models) {
assert(InGraphicsThread());
// need to keep lists locked while iterating over them..
- MediaListsLock m_lock;
+ AssetListLock m_lock;
if (do_textures) {
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto&& i : textures_) {
- MediaComponentData::LockGuard lock(i.second.get());
+ AssetComponentData::LockGuard lock(i.second.get());
i.second->Unload(true);
}
for (auto&& i : text_textures_) {
- MediaComponentData::LockGuard lock(i.second.get());
+ AssetComponentData::LockGuard lock(i.second.get());
i.second->Unload(true);
}
for (auto&& i : qr_textures_) {
- MediaComponentData::LockGuard lock(i.second.get());
+ AssetComponentData::LockGuard lock(i.second.get());
i.second->Unload(true);
}
}
if (do_models) {
for (auto&& i : models_) {
- MediaComponentData::LockGuard lock(i.second.get());
+ AssetComponentData::LockGuard lock(i.second.get());
i.second->Unload(true);
}
}
}
-auto Media::GetModelData(const std::string& file_name)
+auto Assets::GetModelData(const std::string& file_name)
-> Object::Ref {
return GetComponentData(file_name, &models_);
}
-auto Media::GetSoundData(const std::string& file_name)
+auto Assets::GetSoundData(const std::string& file_name)
-> Object::Ref {
return GetComponentData(file_name, &sounds_);
}
-auto Media::GetDataData(const std::string& file_name) -> Object::Ref {
+auto Assets::GetDataData(const std::string& file_name)
+ -> Object::Ref {
return GetComponentData(file_name, &datas_);
}
-auto Media::GetCollideModelData(const std::string& file_name)
+auto Assets::GetCollideModelData(const std::string& file_name)
-> Object::Ref {
return GetComponentData(file_name, &collide_models_);
}
template
-auto Media::GetComponentData(
+auto Assets::GetComponentData(
const std::string& file_name,
std::unordered_map >* c_list)
-> Object::Ref {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
auto i = c_list->find(file_name);
if (i != c_list->end()) {
return Object::Ref(i->second.get());
@@ -475,8 +468,8 @@ auto Media::GetComponentData(
auto d(Object::New(file_name));
(*c_list)[file_name] = d;
{
- MediaComponentData::LockGuard lock(d.get());
- have_pending_loads_[static_cast(d->GetMediaType())] = true;
+ AssetComponentData::LockGuard lock(d.get());
+ have_pending_loads_[static_cast(d->GetAssetType())] = true;
MarkComponentForLoad(d.get());
}
d->set_last_used_time(GetRealTime());
@@ -484,9 +477,9 @@ auto Media::GetComponentData(
}
}
-auto Media::GetTextureData(TextPacker* packer) -> Object::Ref {
+auto Assets::GetTextureData(TextPacker* packer) -> Object::Ref {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
const std::string& hash(packer->hash());
auto i = text_textures_.find(hash);
if (i != text_textures_.end()) {
@@ -495,8 +488,8 @@ auto Media::GetTextureData(TextPacker* packer) -> Object::Ref {
auto d(Object::New(packer));
text_textures_[hash] = d;
{
- MediaComponentData::LockGuard lock(d.get());
- have_pending_loads_[static_cast(d->GetMediaType())] = true;
+ AssetComponentData::LockGuard lock(d.get());
+ have_pending_loads_[static_cast(d->GetAssetType())] = true;
MarkComponentForLoad(d.get());
}
d->set_last_used_time(GetRealTime());
@@ -504,10 +497,10 @@ auto Media::GetTextureData(TextPacker* packer) -> Object::Ref {
}
}
-auto Media::GetTextureDataQRCode(const std::string& url)
+auto Assets::GetTextureDataQRCode(const std::string& url)
-> Object::Ref {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
auto i = qr_textures_.find(url);
if (i != qr_textures_.end()) {
return Object::Ref(i->second.get());
@@ -515,8 +508,8 @@ auto Media::GetTextureDataQRCode(const std::string& url)
auto d(Object::New(url));
qr_textures_[url] = d;
{
- MediaComponentData::LockGuard lock(d.get());
- have_pending_loads_[static_cast(d->GetMediaType())] = true;
+ AssetComponentData::LockGuard lock(d.get());
+ have_pending_loads_[static_cast(d->GetAssetType())] = true;
MarkComponentForLoad(d.get());
}
d->set_last_used_time(GetRealTime());
@@ -526,10 +519,10 @@ auto Media::GetTextureDataQRCode(const std::string& url)
// Eww can't recycle GetComponent here since we need extra stuff (tex-type arg)
// ..should fix.
-auto Media::GetCubeMapTextureData(const std::string& file_name)
+auto Assets::GetCubeMapTextureData(const std::string& file_name)
-> Object::Ref {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
auto i = textures_.find(file_name);
if (i != textures_.end()) {
return Object::Ref(i->second.get());
@@ -538,8 +531,8 @@ auto Media::GetCubeMapTextureData(const std::string& file_name)
TextureMinQuality::kLow));
textures_[file_name] = d;
{
- MediaComponentData::LockGuard lock(d.get());
- have_pending_loads_[static_cast(d->GetMediaType())] = true;
+ AssetComponentData::LockGuard lock(d.get());
+ have_pending_loads_[static_cast(d->GetAssetType())] = true;
MarkComponentForLoad(d.get());
}
d->set_last_used_time(GetRealTime());
@@ -549,10 +542,10 @@ auto Media::GetCubeMapTextureData(const std::string& file_name)
// Eww; can't recycle GetComponent here since we need extra stuff (quality
// settings, etc). Should fix.
-auto Media::GetTextureData(const std::string& file_name)
+auto Assets::GetTextureData(const std::string& file_name)
-> Object::Ref {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
auto i = textures_.find(file_name);
if (i != textures_.end()) {
return Object::Ref(i->second.get());
@@ -594,8 +587,8 @@ auto Media::GetTextureData(const std::string& file_name)
auto d(Object::New(file_name, TextureType::k2D, min_quality));
textures_[file_name] = d;
{
- MediaComponentData::LockGuard lock(d.get());
- have_pending_loads_[static_cast(d->GetMediaType())] = true;
+ AssetComponentData::LockGuard lock(d.get());
+ have_pending_loads_[static_cast(d->GetAssetType())] = true;
MarkComponentForLoad(d.get());
}
d->set_last_used_time(GetRealTime());
@@ -603,7 +596,7 @@ auto Media::GetTextureData(const std::string& file_name)
}
}
-void Media::MarkComponentForLoad(MediaComponentData* c) {
+void Assets::MarkComponentForLoad(AssetComponentData* c) {
assert(InLogicThread());
assert(c->locked());
@@ -614,111 +607,110 @@ void Media::MarkComponentForLoad(MediaComponentData* c) {
// once it makes it back to us we can delete the ref (in
// ClearPendingLoadsDoneList)
- auto media_ptr = new Object::Ref(c);
- g_media_server->thread()->PushRunnable(
- Object::NewDeferred(media_ptr));
+ auto asset_ref_ptr = new Object::Ref(c);
+ g_assets_server->PushPendingPreload(asset_ref_ptr);
}
#pragma clang diagnostic push
#pragma ide diagnostic ignored "UnreachableCode"
#pragma ide diagnostic ignored "ConstantFunctionResult"
-auto Media::GetModelPendingLoadCount() -> int {
- if (!have_pending_loads_[static_cast(MediaType::kModel)]) {
+auto Assets::GetModelPendingLoadCount() -> int {
+ if (!have_pending_loads_[static_cast(AssetType::kModel)]) {
return 0;
}
- MediaListsLock lock;
- int total = GetComponentPendingLoadCount(&models_, MediaType::kModel);
+ AssetListLock lock;
+ int total = GetComponentPendingLoadCount(&models_, AssetType::kModel);
if (total == 0) {
// When fully loaded, stop counting.
- have_pending_loads_[static_cast(MediaType::kModel)] = false;
+ have_pending_loads_[static_cast(AssetType::kModel)] = false;
}
return total;
}
-auto Media::GetTexturePendingLoadCount() -> int {
- if (!have_pending_loads_[static_cast(MediaType::kTexture)]) {
+auto Assets::GetTexturePendingLoadCount() -> int {
+ if (!have_pending_loads_[static_cast(AssetType::kTexture)]) {
return 0;
}
- MediaListsLock lock;
+ AssetListLock lock;
int total =
- (GetComponentPendingLoadCount(&textures_, MediaType::kTexture)
- + GetComponentPendingLoadCount(&text_textures_, MediaType::kTexture)
- + GetComponentPendingLoadCount(&qr_textures_, MediaType::kTexture));
+ (GetComponentPendingLoadCount(&textures_, AssetType::kTexture)
+ + GetComponentPendingLoadCount(&text_textures_, AssetType::kTexture)
+ + GetComponentPendingLoadCount(&qr_textures_, AssetType::kTexture));
if (total == 0) {
// When fully loaded, stop counting.
- have_pending_loads_[static_cast(MediaType::kTexture)] = false;
+ have_pending_loads_[static_cast(AssetType::kTexture)] = false;
}
return total;
}
-auto Media::GetSoundPendingLoadCount() -> int {
- if (!have_pending_loads_[static_cast(MediaType::kSound)]) {
+auto Assets::GetSoundPendingLoadCount() -> int {
+ if (!have_pending_loads_[static_cast(AssetType::kSound)]) {
return 0;
}
- MediaListsLock lock;
- int total = GetComponentPendingLoadCount(&sounds_, MediaType::kSound);
+ AssetListLock lock;
+ int total = GetComponentPendingLoadCount(&sounds_, AssetType::kSound);
if (total == 0) {
// When fully loaded, stop counting.
- have_pending_loads_[static_cast(MediaType::kSound)] = false;
+ have_pending_loads_[static_cast(AssetType::kSound)] = false;
}
return total;
}
-auto Media::GetDataPendingLoadCount() -> int {
- if (!have_pending_loads_[static_cast(MediaType::kData)]) {
+auto Assets::GetDataPendingLoadCount() -> int {
+ if (!have_pending_loads_[static_cast(AssetType::kData)]) {
return 0;
}
- MediaListsLock lock;
- int total = GetComponentPendingLoadCount(&datas_, MediaType::kData);
+ AssetListLock lock;
+ int total = GetComponentPendingLoadCount(&datas_, AssetType::kData);
if (total == 0) {
// When fully loaded, stop counting.
- have_pending_loads_[static_cast(MediaType::kData)] = false;
+ have_pending_loads_[static_cast(AssetType::kData)] = false;
}
return total;
}
-auto Media::GetCollideModelPendingLoadCount() -> int {
- if (!have_pending_loads_[static_cast(MediaType::kCollideModel)]) {
+auto Assets::GetCollideModelPendingLoadCount() -> int {
+ if (!have_pending_loads_[static_cast(AssetType::kCollideModel)]) {
return 0;
}
- MediaListsLock lock;
+ AssetListLock lock;
int total =
- GetComponentPendingLoadCount(&collide_models_, MediaType::kCollideModel);
+ GetComponentPendingLoadCount(&collide_models_, AssetType::kCollideModel);
if (total == 0) {
// When fully loaded, stop counting.
- have_pending_loads_[static_cast(MediaType::kCollideModel)] = false;
+ have_pending_loads_[static_cast(AssetType::kCollideModel)] = false;
}
return total;
}
#pragma clang diagnostic pop
-auto Media::GetGraphicalPendingLoadCount() -> int {
- // Each of these calls lock the media-lists so we don't.
+auto Assets::GetGraphicalPendingLoadCount() -> int {
+ // Each of these calls lock the asset-lists so we don't.
return GetModelPendingLoadCount() + GetTexturePendingLoadCount();
}
-auto Media::GetPendingLoadCount() -> int {
- // Each of these calls lock the media-lists so we don't.
+auto Assets::GetPendingLoadCount() -> int {
+ // Each of these calls lock the asset-lists so we don't.
return GetModelPendingLoadCount() + GetTexturePendingLoadCount()
+ GetDataPendingLoadCount() + GetSoundPendingLoadCount()
+ GetCollideModelPendingLoadCount();
}
template
-auto Media::GetComponentPendingLoadCount(
- std::unordered_map >* t_list, MediaType type)
+auto Assets::GetComponentPendingLoadCount(
+ std::unordered_map >* t_list, AssetType type)
-> int {
assert(InLogicThread());
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
int c = 0;
for (auto&& i : (*t_list)) {
if (i.second.exists()) {
if (i.second->TryLock()) {
- MediaComponentData::LockGuard lock(
- i.second.get(), MediaComponentData::LockGuard::Type::kInheritLock);
+ AssetComponentData::LockGuard lock(
+ i.second.get(), AssetComponentData::LockGuard::Type::kInheritLock);
if (!i.second->loaded()) {
c++;
}
@@ -731,26 +723,26 @@ auto Media::GetComponentPendingLoadCount(
}
// Runs the pending loads that need to run from the audio thread.
-auto Media::RunPendingAudioLoads() -> bool {
+auto Assets::RunPendingAudioLoads() -> bool {
assert(InAudioThread());
return RunPendingLoadList(&pending_loads_sounds_);
}
// Runs the pending loads that need to run from the graphics thread.
-auto Media::RunPendingGraphicsLoads() -> bool {
+auto Assets::RunPendingGraphicsLoads() -> bool {
assert(InGraphicsThread());
return RunPendingLoadList(&pending_loads_graphics_);
}
// Runs the pending loads that run in the main thread. Also clears the list of
// done loads.
-auto Media::RunPendingLoadsLogicThread() -> bool {
+auto Assets::RunPendingLoadsLogicThread() -> bool {
assert(InLogicThread());
return RunPendingLoadList(&pending_loads_other_);
}
template
-auto Media::RunPendingLoadList(std::vector*>* c_list) -> bool {
+auto Assets::RunPendingLoadList(std::vector*>* c_list) -> bool {
bool flush = false;
millisecs_t starttime = GetRealTime();
@@ -818,40 +810,40 @@ auto Media::RunPendingLoadList(std::vector*>* c_list) -> bool {
}
}
- // if we dumped anything on the pending loads done list, shake the game thread
- // to tell it to kill the reference..
+ // if we dumped anything on the pending loads done list, shake the logic
+ // thread to tell it to kill the reference..
if (!l_finished.empty()) {
- assert(g_game);
- g_game->PushHavePendingLoadsDoneCall();
+ assert(g_logic);
+ g_logic->PushHavePendingLoadsDoneCall();
}
return (!l.empty());
}
-void Media::Prune(int level) {
+void Assets::Prune(int level) {
assert(InLogicThread());
millisecs_t current_time = GetRealTime();
// need lists locked while accessing/modifying them
- MediaListsLock lock;
+ AssetListLock lock;
// we can specify level for more aggressive pruning (during memory warnings
// and whatnot)
- millisecs_t standard_media_prune_time = STANDARD_MEDIA_PRUNE_TIME;
+ millisecs_t standard_asset_prune_time = STANDARD_ASSET_PRUNE_TIME;
millisecs_t text_texture_prune_time = TEXT_TEXTURE_PRUNE_TIME;
millisecs_t qr_texture_prune_time = QR_TEXTURE_PRUNE_TIME;
switch (level) {
case 1:
- standard_media_prune_time = 120000; // 2 min
+ standard_asset_prune_time = 120000; // 2 min
text_texture_prune_time = 1000; // 1 sec
qr_texture_prune_time = 1000; // 1 sec
break;
case 2:
- standard_media_prune_time = 30000; // 30 sec
+ standard_asset_prune_time = 30000; // 30 sec
text_texture_prune_time = 1000; // 1 sec
qr_texture_prune_time = 1000; // 1 sec
break;
case 3:
- standard_media_prune_time = 5000; // 5 sec
+ standard_asset_prune_time = 5000; // 5 sec
text_texture_prune_time = 1000; // 1 sec
qr_texture_prune_time = 1000; // 1 sec
break;
@@ -859,11 +851,11 @@ void Media::Prune(int level) {
break;
}
- std::vector*> graphics_thread_unloads;
- std::vector*> audio_thread_unloads;
+ std::vector*> graphics_thread_unloads;
+ std::vector*> audio_thread_unloads;
#if SHOW_PRUNING_INFO
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
int old_texture_count = textures_.size();
int old_text_texture_count = text_textures_.size();
int old_qr_texture_count = qr_textures_.size();
@@ -873,13 +865,13 @@ void Media::Prune(int level) {
#endif // SHOW_PRUNING_INFO
// prune textures..
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = textures_.begin(); i != textures_.end();) {
TextureData* texture_data = i->second.get();
// attempt to prune if there are no references remaining except our own and
// its been a while since it was used
if (current_time - texture_data->last_used_time()
- > standard_media_prune_time
+ > standard_asset_prune_time
&& (texture_data->object_strong_ref_count() <= 1)) {
// if its preloaded/loaded we need to ask the graphics thread to unload it
// first
@@ -887,7 +879,7 @@ void Media::Prune(int level) {
// allocate a reference to keep this texture_data alive while the unload
// is happening
graphics_thread_unloads.push_back(
- new Object::Ref(texture_data));
+ new Object::Ref(texture_data));
auto i_next = i;
i_next++;
textures_.erase(i);
@@ -901,7 +893,7 @@ void Media::Prune(int level) {
// prune text-textures more aggressively since we may generate lots of them
// FIXME - we may want to prune based on total number of these instead of
// time..
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = text_textures_.begin(); i != text_textures_.end();) {
TextureData* texture_data = i->second.get();
// attempt to prune if there are no references remaining except our own and
@@ -914,7 +906,7 @@ void Media::Prune(int level) {
// allocate a reference to keep this texture_data alive while the unload
// is happening
graphics_thread_unloads.push_back(
- new Object::Ref(texture_data));
+ new Object::Ref(texture_data));
auto i_next = i;
i_next++;
text_textures_.erase(i);
@@ -926,7 +918,7 @@ void Media::Prune(int level) {
}
// prune textures
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = qr_textures_.begin(); i != qr_textures_.end();) {
TextureData* texture_data = i->second.get();
// attempt to prune if there are no references remaining except our own and
@@ -939,7 +931,7 @@ void Media::Prune(int level) {
// allocate a reference to keep this texture_data alive while the unload
// is happening
graphics_thread_unloads.push_back(
- new Object::Ref(texture_data));
+ new Object::Ref(texture_data));
auto i_next = i;
i_next++;
qr_textures_.erase(i);
@@ -951,12 +943,12 @@ void Media::Prune(int level) {
}
// prune models..
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = models_.begin(); i != models_.end();) {
ModelData* model_data = i->second.get();
// attempt to prune if there are no references remaining except our own and
// its been a while since it was used
- if (current_time - model_data->last_used_time() > standard_media_prune_time
+ if (current_time - model_data->last_used_time() > standard_asset_prune_time
&& (model_data->object_strong_ref_count() <= 1)) {
// if its preloaded/loaded we need to ask the graphics thread to unload it
// first
@@ -964,7 +956,7 @@ void Media::Prune(int level) {
// allocate a reference to keep this model_data alive while the unload
// is happening
graphics_thread_unloads.push_back(
- new Object::Ref(model_data));
+ new Object::Ref(model_data));
auto i_next = i;
i_next++;
models_.erase(i);
@@ -976,16 +968,16 @@ void Media::Prune(int level) {
}
// Prune collide-models.
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = collide_models_.begin(); i != collide_models_.end();) {
CollideModelData* collide_model_data = i->second.get();
// attempt to prune if there are no references remaining except our own and
- // its been a while since it was used (unlike other media we never prune
+ // its been a while since it was used (unlike other assets we never prune
// these if there's still references to them
if (current_time - collide_model_data->last_used_time()
- > standard_media_prune_time
+ > standard_asset_prune_time
&& (collide_model_data->object_strong_ref_count() <= 1)) {
- // we can unload it immediately since that happens in the game thread...
+ // we can unload it immediately since that happens in the logic thread...
collide_model_data->Unload();
auto i_next = i;
++i_next;
@@ -1001,13 +993,13 @@ void Media::Prune(int level) {
// sounds are still in active use by OpenAL and ensure references exist for
// them somewhere while that is the case
if (explicit_bool(false)) {
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
for (auto i = sounds_.begin(); i != sounds_.end();) {
SoundData* sound_data = i->second.get();
// Attempt to prune if there are no references remaining except our own
// and its been a while since it was used.
if (current_time - sound_data->last_used_time()
- > standard_media_prune_time
+ > standard_asset_prune_time
&& (sound_data->object_strong_ref_count() <= 1)) {
// If its preloaded/loaded we need to ask the graphics thread to unload
// it first.
@@ -1015,7 +1007,7 @@ void Media::Prune(int level) {
// Allocate a reference to keep this sound_data alive while the unload
// is happening.
audio_thread_unloads.push_back(
- new Object::Ref(sound_data));
+ new Object::Ref(sound_data));
auto i_next = i;
i_next++;
sounds_.erase(i);
@@ -1035,7 +1027,7 @@ void Media::Prune(int level) {
}
#if SHOW_PRUNING_INFO
- assert(media_lists_locked_);
+ assert(asset_lists_locked_);
if (textures_.size() != old_texture_count) {
Log("Textures pruned from " + std::to_string(old_texture_count) + " to "
+ std::to_string(textures_.size()));
@@ -1063,7 +1055,7 @@ void Media::Prune(int level) {
#endif // SHOW_PRUNING_INFO
}
-auto Media::FindMediaFile(FileType type, const std::string& name)
+auto Assets::FindAssetFile(FileType type, const std::string& name)
-> std::string {
std::string file_out;
@@ -1133,9 +1125,9 @@ auto Media::FindMediaFile(FileType type, const std::string& name)
break;
}
- const std::vector& media_paths_used = media_paths_;
+ const std::vector& asset_paths_used = asset_paths_;
- for (auto&& i : media_paths_used) {
+ for (auto&& i : asset_paths_used) {
struct BA_STAT stats {};
file_out = i + "/" + prefix + name + ext; // NOLINT
int result;
@@ -1159,27 +1151,29 @@ auto Media::FindMediaFile(FileType type, const std::string& name)
// We wanna fail gracefully for some types.
if (type == FileType::kSound && name != "blank") {
- Log("Unable to load audio: '" + name + "'; trying fallback...");
- return FindMediaFile(type, "blank");
+ Log(LogLevel::kError,
+ "Unable to load audio: '" + name + "'; trying fallback...");
+ return FindAssetFile(type, "blank");
} else if (type == FileType::kTexture && name != "white") {
- Log("Unable to load texture: '" + name + "'; trying fallback...");
- return FindMediaFile(type, "white");
+ Log(LogLevel::kError,
+ "Unable to load texture: '" + name + "'; trying fallback...");
+ return FindAssetFile(type, "white");
}
- throw Exception("Can't find media: \"" + name + "\"");
+ throw Exception("Can't find asset: \"" + name + "\"");
// return file_out;
}
-void Media::AddPendingLoad(Object::Ref* c) {
- switch ((**c).GetMediaType()) {
- case MediaType::kTexture:
- case MediaType::kModel: {
+void Assets::AddPendingLoad(Object::Ref* c) {
+ switch ((**c).GetAssetType()) {
+ case AssetType::kTexture:
+ case AssetType::kModel: {
// Tell the graphics thread there's pending loads...
std::scoped_lock lock(pending_load_list_mutex_);
pending_loads_graphics_.push_back(c);
break;
}
- case MediaType::kSound: {
+ case AssetType::kSound: {
// Tell the audio thread there's pending loads.
{
std::scoped_lock lock(pending_load_list_mutex_);
@@ -1189,69 +1183,56 @@ void Media::AddPendingLoad(Object::Ref* c) {
break;
}
default: {
- // Tell the game thread there's pending loads.
+ // Tell the logic thread there's pending loads.
{
std::scoped_lock lock(pending_load_list_mutex_);
pending_loads_other_.push_back(c);
}
- g_game->PushHavePendingLoadsCall();
+ g_logic->PushHavePendingLoadsCall();
break;
}
}
}
-void Media::ClearPendingLoadsDoneList() {
+void Assets::ClearPendingLoadsDoneList() {
assert(InLogicThread());
std::scoped_lock lock(pending_load_list_mutex_);
// Our explicitly-allocated reference pointer has made it back to us here in
- // the game thread.
+ // the logic thread.
// We can now kill the reference knowing that it's safe for this component
// to die at any time (anyone needing it to be alive now should be holding a
// reference themselves).
- for (Object::Ref* i : pending_loads_done_) {
+ for (Object::Ref* i : pending_loads_done_) {
delete i;
}
pending_loads_done_.clear();
}
-void Media::PreloadRunnable::Run() {
- assert(InMediaThread());
-
- // add our pointer to one of the preload lists and shake our preload thread to
- // wake it up
- if ((**c).GetMediaType() == MediaType::kSound) {
- g_media_server->pending_preloads_audio_.push_back(c);
- } else {
- g_media_server->pending_preloads_.push_back(c);
- }
- g_media_server->process_timer_->SetLength(0);
-}
-
-void Media::AddPackage(const std::string& name, const std::string& path) {
+void Assets::AddPackage(const std::string& name, const std::string& path) {
// we don't protect package-path access so make sure its always from here..
assert(InLogicThread());
#if BA_DEBUG_BUILD
if (packages_.find(name) != packages_.end()) {
- Log("WARNING: adding duplicate package: '" + name + "'");
+ Log(LogLevel::kWarning, "adding duplicate package: '" + name + "'");
}
#endif // BA_DEBUG_BUILD
packages_[name] = path;
}
-Media::MediaListsLock::MediaListsLock() {
+Assets::AssetListLock::AssetListLock() {
BA_DEBUG_FUNCTION_TIMER_BEGIN();
- g_media->media_lists_mutex_.lock();
- assert(!g_media->media_lists_locked_);
- g_media->media_lists_locked_ = true;
+ g_assets->asset_lists_mutex_.lock();
+ assert(!g_assets->asset_lists_locked_);
+ g_assets->asset_lists_locked_ = true;
BA_DEBUG_FUNCTION_TIMER_END_THREAD(20);
}
-Media::MediaListsLock::~MediaListsLock() {
- assert(g_media->media_lists_locked_);
- g_media->media_lists_locked_ = false;
- g_media->media_lists_mutex_.unlock();
+Assets::AssetListLock::~AssetListLock() {
+ assert(g_assets->asset_lists_locked_);
+ g_assets->asset_lists_locked_ = false;
+ g_assets->asset_lists_mutex_.unlock();
}
} // namespace ballistica
diff --git a/src/ballistica/media/media.h b/src/ballistica/assets/assets.h
similarity index 65%
rename from src/ballistica/media/media.h
rename to src/ballistica/assets/assets.h
index bdb3cd8a..a23bcefe 100644
--- a/src/ballistica/media/media.h
+++ b/src/ballistica/assets/assets.h
@@ -1,29 +1,26 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_MEDIA_H_
-#define BALLISTICA_MEDIA_MEDIA_H_
+#ifndef BALLISTICA_ASSETS_ASSETS_H_
+#define BALLISTICA_ASSETS_ASSETS_H_
#include
#include
#include
#include
-#include "ballistica/core/context.h"
#include "ballistica/core/object.h"
-#include "ballistica/generic/runnable.h"
namespace ballistica {
-/// Global media wrangling class.
-class Media {
+/// Global assets wrangling class.
+class Assets {
public:
- static void Init();
- ~Media();
+ Assets();
- /// Handy function to try to return a bit of media from a std::unordered_map
+ /// Handy function to try to return an asset from a std::unordered_map
/// of weak-refs, loading/adding it if need be.
template
- static auto GetMedia(
+ static auto GetAsset(
std::unordered_map >* list,
const std::string& name, Scene* scene) -> Object::Ref {
assert(InLogicThread());
@@ -43,10 +40,10 @@ class Media {
}
}
- void AddPackage(const std::string& name, const std::string& path);
- void Prune(int level = 0);
+ auto AddPackage(const std::string& name, const std::string& path) -> void;
+ auto Prune(int level = 0) -> void;
- /// Finish loading any media that has been preloaded but still needs to be
+ /// Finish loading any assets that have been preloaded but still need to be
/// loaded by the proper thread.
auto RunPendingLoadsLogicThread() -> bool;
@@ -55,26 +52,25 @@ class Media {
/// Return true if graphics loads remain to be done.
auto RunPendingGraphicsLoads() -> bool;
- void ClearPendingLoadsDoneList();
+ auto ClearPendingLoadsDoneList() -> void;
template
auto RunPendingLoadList(std::vector*>* cList) -> bool;
/// This function takes a newly allocated pointer which
/// is deleted once the load is completed.
- void AddPendingLoad(Object::Ref* c);
- struct PreloadRunnable;
+ auto AddPendingLoad(Object::Ref* c) -> void;
enum class FileType { kModel, kCollisionModel, kTexture, kSound, kData };
- auto FindMediaFile(FileType fileType, const std::string& file_in)
+ auto FindAssetFile(FileType fileType, const std::string& file_in)
-> std::string;
/// Unload renderer-specific bits only (gl display lists, etc) - used when
/// recreating/adjusting the renderer.
- void UnloadRendererBits(bool textures, bool models);
+ auto UnloadRendererBits(bool textures, bool models) -> void;
- /// Should be called from the game thread after UnloadRendererBits();
- /// kicks off bg loads for all existing unloaded media.
- void MarkAllMediaForLoad();
- void PrintLoadInfo();
+ /// Should be called from the logic thread after UnloadRendererBits();
+ /// kicks off bg loads for all existing unloaded assets.
+ auto MarkAllAssetsForLoad() -> void;
+ auto PrintLoadInfo() -> void;
auto GetModelPendingLoadCount() -> int;
auto GetTexturePendingLoadCount() -> int;
@@ -89,13 +85,13 @@ class Media {
auto GetPendingLoadCount() -> int;
/// You must hold one of these locks while calling Get*Data() below.
- class MediaListsLock {
+ class AssetListLock {
public:
- MediaListsLock();
- ~MediaListsLock();
+ AssetListLock();
+ ~AssetListLock();
};
- /// Load/cache media (make sure you hold a MediaListsLock).
+ /// Load/cache assets (make sure you hold a AssetListLock).
auto GetTextureData(const std::string& file_name) -> Object::Ref;
auto GetTextureData(TextPacker* packer) -> Object::Ref;
auto GetTextureDataQRCode(const std::string& file_name)
@@ -110,32 +106,32 @@ class Media {
// Get system assets.
auto GetTexture(SystemTextureID id) -> TextureData* {
- BA_PRECONDITION_FATAL(system_media_loaded_); // Revert to assert later.
+ BA_PRECONDITION_FATAL(system_assets_loaded_); // Revert to assert later.
assert(InLogicThread());
assert(static_cast(id) < system_textures_.size());
return system_textures_[static_cast(id)].get();
}
auto GetCubeMapTexture(SystemCubeMapTextureID id) -> TextureData* {
- BA_PRECONDITION_FATAL(system_media_loaded_); // Revert to assert later.
+ BA_PRECONDITION_FATAL(system_assets_loaded_); // Revert to assert later.
assert(InLogicThread());
assert(static_cast(id) < system_cube_map_textures_.size());
return system_cube_map_textures_[static_cast(id)].get();
}
auto GetSound(SystemSoundID id) -> SoundData* {
- BA_PRECONDITION_FATAL(system_media_loaded_); // Revert to assert later.
+ BA_PRECONDITION_FATAL(system_assets_loaded_); // Revert to assert later.
assert(InLogicThread());
assert(static_cast(id) < system_sounds_.size());
return system_sounds_[static_cast(id)].get();
}
auto GetModel(SystemModelID id) -> ModelData* {
- BA_PRECONDITION_FATAL(system_media_loaded_); // Revert to assert later.
+ BA_PRECONDITION_FATAL(system_assets_loaded_); // Revert to assert later.
assert(InLogicThread());
assert(static_cast(id) < system_models_.size());
return system_models_[static_cast(id)].get();
}
- /// Load up hard-coded media for interface, etc.
- void LoadSystemMedia();
+ /// Load up hard-coded assets for interface, etc.
+ auto LoadSystemAssets() -> void;
auto total_model_count() const -> uint32_t {
return static_cast(models_.size());
@@ -150,24 +146,19 @@ class Media {
auto total_collide_model_count() const -> uint32_t {
return static_cast(collide_models_.size());
}
- struct PreloadRunnable : public Runnable {
- explicit PreloadRunnable(Object::Ref* c_in) : c(c_in) {}
- void Run() override;
- Object::Ref* c;
- };
private:
- Media();
- static void MarkComponentForLoad(MediaComponentData* c);
- void LoadSystemTexture(SystemTextureID id, const char* name);
- void LoadSystemCubeMapTexture(SystemCubeMapTextureID id, const char* name);
- void LoadSystemSound(SystemSoundID id, const char* name);
- void LoadSystemData(SystemDataID id, const char* name);
- void LoadSystemModel(SystemModelID id, const char* name);
+ static auto MarkComponentForLoad(AssetComponentData* c) -> void;
+ auto LoadSystemTexture(SystemTextureID id, const char* name) -> void;
+ auto LoadSystemCubeMapTexture(SystemCubeMapTextureID id, const char* name)
+ -> void;
+ auto LoadSystemSound(SystemSoundID id, const char* name) -> void;
+ auto LoadSystemData(SystemDataID id, const char* name) -> void;
+ auto LoadSystemModel(SystemModelID id, const char* name) -> void;
template
auto GetComponentPendingLoadCount(
- std::unordered_map >* t_list, MediaType type)
+ std::unordered_map >* t_list, AssetType type)
-> int;
template
@@ -176,26 +167,26 @@ class Media {
std::unordered_map >* c_list)
-> Object::Ref;
- std::vector media_paths_;
- bool have_pending_loads_[static_cast(MediaType::kLast)]{};
+ std::vector asset_paths_;
+ bool have_pending_loads_[static_cast(AssetType::kLast)]{};
std::unordered_map packages_;
- // For use by MediaListsLock; don't manually acquire
- std::mutex media_lists_mutex_;
+ // For use by AssetListLock; don't manually acquire
+ std::mutex asset_lists_mutex_;
- // Will be true while a MediaListsLock exists. Good to debug-verify this
- // during any media list access.
- bool media_lists_locked_{};
+ // Will be true while a AssetListLock exists. Good to debug-verify this
+ // during any asset list access.
+ bool asset_lists_locked_{};
- // 'hard-wired' internal media
- bool system_media_loaded_{};
+ // 'hard-wired' internal assets
+ bool system_assets_loaded_{};
std::vector > system_textures_;
std::vector > system_cube_map_textures_;
std::vector > system_sounds_;
std::vector > system_datas_;
std::vector > system_models_;
- // All existing media by filename (including internal).
+ // All existing assets by filename (including internal).
std::unordered_map > textures_;
std::unordered_map > text_textures_;
std::unordered_map > qr_textures_;
@@ -207,13 +198,13 @@ class Media {
// Components that have been preloaded but need to be loaded.
std::mutex pending_load_list_mutex_;
- std::vector*> pending_loads_graphics_;
- std::vector*> pending_loads_sounds_;
- std::vector*> pending_loads_datas_;
- std::vector*> pending_loads_other_;
- std::vector*> pending_loads_done_;
+ std::vector*> pending_loads_graphics_;
+ std::vector*> pending_loads_sounds_;
+ std::vector*> pending_loads_datas_;
+ std::vector*> pending_loads_other_;
+ std::vector*> pending_loads_done_;
};
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_MEDIA_H_
+#endif // BALLISTICA_ASSETS_ASSETS_H_
diff --git a/src/ballistica/media/media_server.cc b/src/ballistica/assets/assets_server.cc
similarity index 68%
rename from src/ballistica/media/media_server.cc
rename to src/ballistica/assets/assets_server.cc
index 5592b1b6..81168ff9 100644
--- a/src/ballistica/media/media_server.cc
+++ b/src/ballistica/assets/assets_server.cc
@@ -1,34 +1,54 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/media_server.h"
+#include "ballistica/assets/assets_server.h"
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/data/asset_component_data.h"
#include "ballistica/core/thread.h"
#include "ballistica/generic/huffman.h"
#include "ballistica/generic/timer.h"
#include "ballistica/generic/utils.h"
#include "ballistica/graphics/graphics_server.h"
-#include "ballistica/media/data/media_component_data.h"
-#include "ballistica/media/media.h"
namespace ballistica {
-MediaServer::MediaServer(Thread* thread)
- : thread_(thread),
- writing_replay_(false),
- replay_message_bytes_(0),
- replays_broken_(false),
- replay_out_file_(nullptr) {
- assert(g_media_server == nullptr);
- g_media_server = this;
+AssetsServer::AssetsServer() {
+ // We're a singleton; make sure we don't already exist.
+ assert(g_assets_server == nullptr);
- // get our thread to give us periodic processing time...
- process_timer_ = this->thread()->NewTimer(
- 1000, true, NewLambdaRunnable([this] { Process(); }));
+ // Spin up our thread.
+ thread_ = new Thread(ThreadTag::kAssets);
+ g_app->pausable_threads.push_back(thread_);
}
-MediaServer::~MediaServer() = default;
+auto AssetsServer::OnAppStart() -> void {
+ thread_->PushCallSynchronous([this] { OnAppStartInThread(); });
+}
-void MediaServer::PushBeginWriteReplayCall() {
+auto AssetsServer::OnAppStartInThread() -> void {
+ assert(InAssetsThread());
+ // get our thread to give us periodic processing time...
+ process_timer_ =
+ thread()->NewTimer(1000, true, NewLambdaRunnable([this] { Process(); }));
+}
+
+auto AssetsServer::PushPendingPreload(
+ Object::Ref* asset_ref_ptr) -> void {
+ thread()->PushCall([this, asset_ref_ptr] {
+ assert(InAssetsThread());
+
+ // Add our pointer to one of the preload lists and shake our preload thread
+ // to wake it up
+ if ((**asset_ref_ptr).GetAssetType() == AssetType::kSound) {
+ pending_preloads_audio_.push_back(asset_ref_ptr);
+ } else {
+ pending_preloads_.push_back(asset_ref_ptr);
+ }
+ process_timer_->SetLength(0);
+ });
+}
+
+void AssetsServer::PushBeginWriteReplayCall() {
thread()->PushCall([this] {
if (replays_broken_) {
return;
@@ -37,7 +57,8 @@ void MediaServer::PushBeginWriteReplayCall() {
// we only allow writing one replay at once; make sure that's actually the
// case
if (writing_replay_) {
- Log("MediaServer got BeginWriteReplayCall while already writing");
+ Log(LogLevel::kError,
+ "AssetsServer got BeginWriteReplayCall while already writing");
WriteReplayMessages();
if (replay_out_file_) {
fclose(replay_out_file_);
@@ -56,7 +77,8 @@ void MediaServer::PushBeginWriteReplayCall() {
replay_bytes_written_ = 0;
if (!replay_out_file_) {
- Log("ERROR: unable to open output-stream file: '" + file_path + "'");
+ Log(LogLevel::kError,
+ "unable to open output-stream file: '" + file_path + "'");
} else {
// write file id and protocol-version
// NOTE - we always write replays in our host protocol version
@@ -67,19 +89,20 @@ void MediaServer::PushBeginWriteReplayCall() {
|| (fwrite(&version, sizeof(version), 1, replay_out_file_) != 1)) {
fclose(replay_out_file_);
replay_out_file_ = nullptr;
- Log("error writing replay file header: "
- + g_platform->GetErrnoString());
+ Log(LogLevel::kError, "error writing replay file header: "
+ + g_platform->GetErrnoString());
}
replay_bytes_written_ = 5;
}
// trigger our process timer to go off immediately
// (we may need to wake it up)
- g_media_server->process_timer_->SetLength(0);
+ g_assets_server->process_timer_->SetLength(0);
});
}
-void MediaServer::PushAddMessageToReplayCall(const std::vector& data) {
+void AssetsServer::PushAddMessageToReplayCall(
+ const std::vector& data) {
thread()->PushCall([this, data] {
if (replays_broken_) {
return;
@@ -87,7 +110,8 @@ void MediaServer::PushAddMessageToReplayCall(const std::vector& data) {
// sanity check..
if (!writing_replay_) {
- Log("MediaServer got AddMessageToReplayCall while not writing replay");
+ Log(LogLevel::kError,
+ "AssetsServer got AddMessageToReplayCall while not writing replay");
replays_broken_ = true;
return;
}
@@ -97,7 +121,8 @@ void MediaServer::PushAddMessageToReplayCall(const std::vector& data) {
// if we've got too much data built up (lets go with 10 megs for now),
// abort
if (replay_message_bytes_ > 10000000) {
- Log("replay output buffer exceeded 10 megs; aborting replay");
+ Log(LogLevel::kError,
+ "replay output buffer exceeded 10 megs; aborting replay");
fclose(replay_out_file_);
replay_out_file_ = nullptr;
replay_message_bytes_ = 0;
@@ -110,7 +135,7 @@ void MediaServer::PushAddMessageToReplayCall(const std::vector& data) {
});
}
-void MediaServer::PushEndWriteReplayCall() {
+void AssetsServer::PushEndWriteReplayCall() {
thread()->PushCall([this] {
if (replays_broken_) {
return;
@@ -118,7 +143,7 @@ void MediaServer::PushEndWriteReplayCall() {
// sanity check..
if (!writing_replay_) {
- Log("_finishWritingReplay called while not writing");
+ Log(LogLevel::kError, "_finishWritingReplay called while not writing");
replays_broken_ = true;
return;
}
@@ -134,7 +159,7 @@ void MediaServer::PushEndWriteReplayCall() {
});
}
-void MediaServer::WriteReplayMessages() {
+void AssetsServer::WriteReplayMessages() {
if (replay_out_file_) {
for (auto&& i : replay_messages_) {
std::vector data_compressed = g_utils->huffman()->compress(i);
@@ -155,7 +180,8 @@ void MediaServer::WriteReplayMessages() {
if (fwrite(&len8, 1, 1, replay_out_file_) != 1) {
fclose(replay_out_file_);
replay_out_file_ = nullptr;
- Log("error writing replay file: " + g_platform->GetErrnoString());
+ Log(LogLevel::kError,
+ "error writing replay file: " + g_platform->GetErrnoString());
return;
}
}
@@ -166,14 +192,16 @@ void MediaServer::WriteReplayMessages() {
if (fwrite(&len16, 2, 1, replay_out_file_) != 1) {
fclose(replay_out_file_);
replay_out_file_ = nullptr;
- Log("error writing replay file: " + g_platform->GetErrnoString());
+ Log(LogLevel::kError,
+ "error writing replay file: " + g_platform->GetErrnoString());
return;
}
} else {
if (fwrite(&len32, 4, 1, replay_out_file_) != 1) {
fclose(replay_out_file_);
replay_out_file_ = nullptr;
- Log("error writing replay file: " + g_platform->GetErrnoString());
+ Log(LogLevel::kError,
+ "error writing replay file: " + g_platform->GetErrnoString());
return;
}
}
@@ -184,7 +212,8 @@ void MediaServer::WriteReplayMessages() {
if (result != 1) {
fclose(replay_out_file_);
replay_out_file_ = nullptr;
- Log("error writing replay file: " + g_platform->GetErrnoString());
+ Log(LogLevel::kError,
+ "error writing replay file: " + g_platform->GetErrnoString());
return;
}
replay_bytes_written_ += data_compressed.size() + 2;
@@ -194,10 +223,10 @@ void MediaServer::WriteReplayMessages() {
}
}
-void MediaServer::Process() {
+void AssetsServer::Process() {
// make sure we don't do any loading until we know what kind/quality of
// textures we'll be loading
- if (!g_media || !g_graphics_server
+ if (!g_assets || !g_graphics_server
|| !g_graphics_server->texture_compression_types_are_set() // NOLINT
|| !g_graphics_server->texture_quality_set()) {
return;
@@ -209,12 +238,12 @@ void MediaServer::Process() {
if (!pending_preloads_.empty()) {
(**pending_preloads_.back()).Preload();
// pass the ref-pointer along to the load queue
- g_media->AddPendingLoad(pending_preloads_.back());
+ g_assets->AddPendingLoad(pending_preloads_.back());
pending_preloads_.pop_back();
} else if (!pending_preloads_audio_.empty()) {
(**pending_preloads_audio_.back()).Preload();
// pass the ref-pointer along to the load queue
- g_media->AddPendingLoad(pending_preloads_audio_.back());
+ g_assets->AddPendingLoad(pending_preloads_audio_.back());
pending_preloads_audio_.pop_back();
}
diff --git a/src/ballistica/assets/assets_server.h b/src/ballistica/assets/assets_server.h
new file mode 100644
index 00000000..e9be2e6a
--- /dev/null
+++ b/src/ballistica/assets/assets_server.h
@@ -0,0 +1,42 @@
+// Released under the MIT License. See LICENSE for details.
+
+#ifndef BALLISTICA_ASSETS_ASSETS_SERVER_H_
+#define BALLISTICA_ASSETS_ASSETS_SERVER_H_
+
+#include
+#include
+
+#include "ballistica/core/object.h"
+
+namespace ballistica {
+
+class AssetsServer {
+ public:
+ AssetsServer();
+ auto OnAppStart() -> void;
+ auto PushBeginWriteReplayCall() -> void;
+ auto PushEndWriteReplayCall() -> void;
+ auto PushAddMessageToReplayCall(const std::vector& data) -> void;
+ auto PushPendingPreload(Object::Ref* asset_ref_ptr)
+ -> void;
+ auto thread() const -> Thread* { return thread_; }
+
+ private:
+ auto OnAppStartInThread() -> void;
+ void Process();
+ void WriteReplayMessages();
+ Thread* thread_{};
+ FILE* replay_out_file_{};
+ size_t replay_bytes_written_{};
+ bool writing_replay_{};
+ bool replays_broken_{};
+ std::list > replay_messages_;
+ size_t replay_message_bytes_{};
+ Timer* process_timer_{};
+ std::vector*> pending_preloads_;
+ std::vector*> pending_preloads_audio_;
+};
+
+} // namespace ballistica
+
+#endif // BALLISTICA_ASSETS_ASSETS_SERVER_H_
diff --git a/src/ballistica/media/component/media_component.cc b/src/ballistica/assets/component/asset_component.cc
similarity index 60%
rename from src/ballistica/media/component/media_component.cc
rename to src/ballistica/assets/component/asset_component.cc
index 049aedf9..9e7ace5e 100644
--- a/src/ballistica/media/component/media_component.cc
+++ b/src/ballistica/assets/component/asset_component.cc
@@ -1,16 +1,16 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/media_component.h"
+#include "ballistica/assets/component/asset_component.h"
#include "ballistica/python/python_sys.h"
#include "ballistica/scene/scene.h"
namespace ballistica {
-MediaComponent::MediaComponent(std::string name, Scene* scene)
+AssetComponent::AssetComponent(std::string name, Scene* scene)
: name_(std::move(name)), scene_(scene) {}
-auto MediaComponent::GetPyRef(bool new_ref) -> PyObject* {
+auto AssetComponent::GetPyRef(bool new_ref) -> PyObject* {
if (!py_object_) {
// if we have no python object, create it
py_object_ = CreatePyObject();
@@ -22,11 +22,11 @@ auto MediaComponent::GetPyRef(bool new_ref) -> PyObject* {
return py_object_;
}
-auto MediaComponent::GetObjectDescription() const -> std::string {
- return "";
+auto AssetComponent::GetObjectDescription() const -> std::string {
+ return "";
}
-void MediaComponent::ClearPyObject() {
+void AssetComponent::ClearPyObject() {
assert(py_object_ != nullptr);
py_object_ = nullptr;
}
diff --git a/src/ballistica/media/component/media_component.h b/src/ballistica/assets/component/asset_component.h
similarity index 82%
rename from src/ballistica/media/component/media_component.h
rename to src/ballistica/assets/component/asset_component.h
index 84887de1..335f39c0 100644
--- a/src/ballistica/media/component/media_component.h
+++ b/src/ballistica/assets/component/asset_component.h
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_MEDIA_COMPONENT_H_
-#define BALLISTICA_MEDIA_COMPONENT_MEDIA_COMPONENT_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_ASSET_COMPONENT_H_
+#define BALLISTICA_ASSETS_COMPONENT_ASSET_COMPONENT_H_
#include
@@ -10,9 +10,9 @@
namespace ballistica {
-class MediaComponent : public Object {
+class AssetComponent : public Object {
public:
- MediaComponent(std::string name, Scene* scene);
+ AssetComponent(std::string name, Scene* scene);
auto name() const -> std::string { return name_; }
// Returns true if this texture was created in the UI context.
@@ -41,7 +41,7 @@ class MediaComponent : public Object {
}
protected:
- virtual auto GetMediaComponentTypeName() const -> std::string = 0;
+ virtual auto GetAssetComponentTypeName() const -> std::string = 0;
// Create a python representation of this object.
virtual auto CreatePyObject() -> PyObject* = 0;
@@ -60,4 +60,4 @@ class MediaComponent : public Object {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_MEDIA_COMPONENT_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_ASSET_COMPONENT_H_
diff --git a/src/ballistica/media/component/collide_model.cc b/src/ballistica/assets/component/collide_model.cc
similarity index 67%
rename from src/ballistica/media/component/collide_model.cc
rename to src/ballistica/assets/component/collide_model.cc
index d24731b4..99435d4f 100644
--- a/src/ballistica/media/component/collide_model.cc
+++ b/src/ballistica/assets/component/collide_model.cc
@@ -1,24 +1,24 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/collide_model.h"
+#include "ballistica/assets/component/collide_model.h"
-#include "ballistica/game/game_stream.h"
#include "ballistica/python/class/python_class_collide_model.h"
#include "ballistica/scene/scene.h"
+#include "ballistica/scene/scene_stream.h"
namespace ballistica {
CollideModel::CollideModel(const std::string& name, Scene* scene)
- : MediaComponent(name, scene), dead_(false) {
+ : AssetComponent(name, scene), dead_(false) {
assert(InLogicThread());
if (scene) {
- if (GameStream* os = scene->GetGameStream()) {
+ if (SceneStream* os = scene->GetSceneStream()) {
os->AddCollideModel(this);
}
}
{
- Media::MediaListsLock lock;
- collide_model_data_ = g_media->GetCollideModelData(name);
+ Assets::AssetListLock lock;
+ collide_model_data_ = g_assets->GetCollideModelData(name);
}
assert(collide_model_data_.exists());
}
@@ -30,7 +30,7 @@ void CollideModel::MarkDead() {
return;
}
if (Scene* s = scene()) {
- if (GameStream* os = s->GetGameStream()) {
+ if (SceneStream* os = s->GetSceneStream()) {
os->RemoveCollideModel(this);
}
}
diff --git a/src/ballistica/media/component/collide_model.h b/src/ballistica/assets/component/collide_model.h
similarity index 63%
rename from src/ballistica/media/component/collide_model.h
rename to src/ballistica/assets/component/collide_model.h
index 7b8fa1e8..09671fa3 100644
--- a/src/ballistica/media/component/collide_model.h
+++ b/src/ballistica/assets/component/collide_model.h
@@ -1,18 +1,18 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_COLLIDE_MODEL_H_
-#define BALLISTICA_MEDIA_COMPONENT_COLLIDE_MODEL_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_COLLIDE_MODEL_H_
+#define BALLISTICA_ASSETS_COMPONENT_COLLIDE_MODEL_H_
#include
-#include "ballistica/media/component/media_component.h"
-#include "ballistica/media/data/collide_model_data.h"
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/component/asset_component.h"
+#include "ballistica/assets/data/collide_model_data.h"
namespace ballistica {
// user-facing collide_model class
-class CollideModel : public MediaComponent {
+class CollideModel : public AssetComponent {
public:
CollideModel(const std::string& name, Scene* scene);
~CollideModel() override;
@@ -23,7 +23,7 @@ class CollideModel : public MediaComponent {
auto collide_model_data() const -> CollideModelData* {
return collide_model_data_.get();
}
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "CollideModel";
}
void MarkDead();
@@ -38,4 +38,4 @@ class CollideModel : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_COLLIDE_MODEL_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_COLLIDE_MODEL_H_
diff --git a/src/ballistica/media/component/cube_map_texture.cc b/src/ballistica/assets/component/cube_map_texture.cc
similarity index 59%
rename from src/ballistica/media/component/cube_map_texture.cc
rename to src/ballistica/assets/component/cube_map_texture.cc
index 6116bf58..6af4d80b 100644
--- a/src/ballistica/media/component/cube_map_texture.cc
+++ b/src/ballistica/assets/component/cube_map_texture.cc
@@ -1,19 +1,19 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/cube_map_texture.h"
+#include "ballistica/assets/component/cube_map_texture.h"
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
namespace ballistica {
CubeMapTexture::CubeMapTexture(const std::string& name, Scene* scene)
- : MediaComponent(name, scene) {
+ : AssetComponent(name, scene) {
assert(InLogicThread());
// cant currently add these to scenes so nothing to do here..
{
- Media::MediaListsLock lock;
- texture_data_ = g_media->GetCubeMapTextureData(name);
+ Assets::AssetListLock lock;
+ texture_data_ = g_assets->GetCubeMapTextureData(name);
}
assert(texture_data_.exists());
}
diff --git a/src/ballistica/media/component/cube_map_texture.h b/src/ballistica/assets/component/cube_map_texture.h
similarity index 59%
rename from src/ballistica/media/component/cube_map_texture.h
rename to src/ballistica/assets/component/cube_map_texture.h
index c72e4623..db5ed159 100644
--- a/src/ballistica/media/component/cube_map_texture.h
+++ b/src/ballistica/assets/component/cube_map_texture.h
@@ -1,17 +1,17 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_CUBE_MAP_TEXTURE_H_
-#define BALLISTICA_MEDIA_COMPONENT_CUBE_MAP_TEXTURE_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_CUBE_MAP_TEXTURE_H_
+#define BALLISTICA_ASSETS_COMPONENT_CUBE_MAP_TEXTURE_H_
#include
-#include "ballistica/media/component/media_component.h"
-#include "ballistica/media/data/texture_data.h"
+#include "ballistica/assets/component/asset_component.h"
+#include "ballistica/assets/data/texture_data.h"
namespace ballistica {
// user-facing texture class
-class CubeMapTexture : public MediaComponent {
+class CubeMapTexture : public AssetComponent {
public:
CubeMapTexture(const std::string& name, Scene* s);
@@ -19,7 +19,7 @@ class CubeMapTexture : public MediaComponent {
// note that a texture's data can change over time as different
// versions are spooled in/out/etc
auto GetTextureData() const -> TextureData* { return texture_data_.get(); }
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "CubeMapTexture";
}
@@ -29,4 +29,4 @@ class CubeMapTexture : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_CUBE_MAP_TEXTURE_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_CUBE_MAP_TEXTURE_H_
diff --git a/src/ballistica/media/component/data.cc b/src/ballistica/assets/component/data.cc
similarity index 66%
rename from src/ballistica/media/component/data.cc
rename to src/ballistica/assets/component/data.cc
index cf3dec87..17b23702 100644
--- a/src/ballistica/media/component/data.cc
+++ b/src/ballistica/assets/component/data.cc
@@ -1,25 +1,25 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/data.h"
+#include "ballistica/assets/component/data.h"
-#include "ballistica/game/game_stream.h"
#include "ballistica/python/class/python_class_data.h"
#include "ballistica/scene/scene.h"
+#include "ballistica/scene/scene_stream.h"
namespace ballistica {
Data::Data(const std::string& name, Scene* scene)
- : MediaComponent(name, scene), dead_(false) {
+ : AssetComponent(name, scene), dead_(false) {
assert(InLogicThread());
if (scene) {
- if (GameStream* os = scene->GetGameStream()) {
+ if (SceneStream* os = scene->GetSceneStream()) {
os->AddData(this);
}
}
{
- Media::MediaListsLock lock;
- data_data_ = g_media->GetDataData(name);
+ Assets::AssetListLock lock;
+ data_data_ = g_assets->GetDataData(name);
}
assert(data_data_.exists());
}
@@ -31,7 +31,7 @@ void Data::MarkDead() {
return;
}
if (Scene* s = scene()) {
- if (GameStream* os = s->GetGameStream()) {
+ if (SceneStream* os = s->GetSceneStream()) {
os->RemoveData(this);
}
}
diff --git a/src/ballistica/media/component/data.h b/src/ballistica/assets/component/data.h
similarity index 62%
rename from src/ballistica/media/component/data.h
rename to src/ballistica/assets/component/data.h
index 30e926a2..fe3e917d 100644
--- a/src/ballistica/media/component/data.h
+++ b/src/ballistica/assets/component/data.h
@@ -1,22 +1,22 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_DATA_H_
-#define BALLISTICA_MEDIA_COMPONENT_DATA_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_DATA_H_
+#define BALLISTICA_ASSETS_COMPONENT_DATA_H_
#include
#include
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/component/asset_component.h"
+#include "ballistica/assets/data/asset_component_data.h"
+#include "ballistica/assets/data/data_data.h"
#include "ballistica/ballistica.h"
#include "ballistica/core/object.h"
-#include "ballistica/media/component/media_component.h"
-#include "ballistica/media/data/data_data.h"
-#include "ballistica/media/data/media_component_data.h"
-#include "ballistica/media/media.h"
namespace ballistica {
// user-facing data class
-class Data : public MediaComponent {
+class Data : public AssetComponent {
public:
Data(const std::string& name, Scene* scene);
~Data() override;
@@ -25,7 +25,7 @@ class Data : public MediaComponent {
// note that a data's data can change over time as different
// versions are spooled in/out/etc.
auto data_data() const -> DataData* { return data_data_.get(); }
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "Data";
}
void MarkDead();
@@ -40,4 +40,4 @@ class Data : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_DATA_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_DATA_H_
diff --git a/src/ballistica/media/component/model.cc b/src/ballistica/assets/component/model.cc
similarity index 66%
rename from src/ballistica/media/component/model.cc
rename to src/ballistica/assets/component/model.cc
index 77b60aef..196ebbf6 100644
--- a/src/ballistica/media/component/model.cc
+++ b/src/ballistica/assets/component/model.cc
@@ -1,25 +1,25 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/model.h"
+#include "ballistica/assets/component/model.h"
-#include "ballistica/game/game_stream.h"
#include "ballistica/python/class/python_class_model.h"
#include "ballistica/scene/scene.h"
+#include "ballistica/scene/scene_stream.h"
namespace ballistica {
Model::Model(const std::string& name, Scene* scene)
- : MediaComponent(name, scene), dead_(false) {
+ : AssetComponent(name, scene), dead_(false) {
assert(InLogicThread());
if (scene) {
- if (GameStream* os = scene->GetGameStream()) {
+ if (SceneStream* os = scene->GetSceneStream()) {
os->AddModel(this);
}
}
{
- Media::MediaListsLock lock;
- model_data_ = g_media->GetModelData(name);
+ Assets::AssetListLock lock;
+ model_data_ = g_assets->GetModelData(name);
}
assert(model_data_.exists());
}
@@ -31,7 +31,7 @@ void Model::MarkDead() {
return;
}
if (Scene* s = scene()) {
- if (GameStream* os = s->GetGameStream()) {
+ if (SceneStream* os = s->GetSceneStream()) {
os->RemoveModel(this);
}
}
diff --git a/src/ballistica/media/component/model.h b/src/ballistica/assets/component/model.h
similarity index 59%
rename from src/ballistica/media/component/model.h
rename to src/ballistica/assets/component/model.h
index c7a8968b..239813a0 100644
--- a/src/ballistica/media/component/model.h
+++ b/src/ballistica/assets/component/model.h
@@ -1,23 +1,23 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_MODEL_H_
-#define BALLISTICA_MEDIA_COMPONENT_MODEL_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_MODEL_H_
+#define BALLISTICA_ASSETS_COMPONENT_MODEL_H_
#include
#include
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/component/asset_component.h"
+#include "ballistica/assets/data/asset_component_data.h"
+#include "ballistica/assets/data/model_data.h"
+#include "ballistica/assets/data/model_renderer_data.h"
#include "ballistica/ballistica.h"
#include "ballistica/core/object.h"
-#include "ballistica/media/component/media_component.h"
-#include "ballistica/media/data/media_component_data.h"
-#include "ballistica/media/data/model_data.h"
-#include "ballistica/media/data/model_renderer_data.h"
-#include "ballistica/media/media.h"
namespace ballistica {
// user-facing model class
-class Model : public MediaComponent {
+class Model : public AssetComponent {
public:
Model(const std::string& name, Scene* scene);
~Model() override;
@@ -26,7 +26,7 @@ class Model : public MediaComponent {
// note that a model's data can change over time as different
// versions are spooled in/out/etc
auto model_data() const -> ModelData* { return model_data_.get(); }
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "Model";
}
void MarkDead();
@@ -41,4 +41,4 @@ class Model : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_MODEL_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_MODEL_H_
diff --git a/src/ballistica/media/component/sound.cc b/src/ballistica/assets/component/sound.cc
similarity index 61%
rename from src/ballistica/media/component/sound.cc
rename to src/ballistica/assets/component/sound.cc
index babf5200..9c76aba2 100644
--- a/src/ballistica/media/component/sound.cc
+++ b/src/ballistica/assets/component/sound.cc
@@ -1,26 +1,26 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/sound.h"
+#include "ballistica/assets/component/sound.h"
-#include "ballistica/game/game_stream.h"
-#include "ballistica/media/data/sound_data.h"
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/data/sound_data.h"
#include "ballistica/python/class/python_class_sound.h"
#include "ballistica/scene/scene.h"
+#include "ballistica/scene/scene_stream.h"
namespace ballistica {
Sound::Sound(const std::string& name, Scene* scene)
- : MediaComponent(name, scene) {
+ : AssetComponent(name, scene) {
assert(InLogicThread());
if (scene) {
- if (GameStream* os = scene->GetGameStream()) {
+ if (SceneStream* os = scene->GetSceneStream()) {
os->AddSound(this);
}
}
{
- Media::MediaListsLock lock;
- sound_data_ = g_media->GetSoundData(name);
+ Assets::AssetListLock lock;
+ sound_data_ = g_assets->GetSoundData(name);
}
assert(sound_data_.exists());
}
@@ -30,7 +30,7 @@ Sound::~Sound() { MarkDead(); }
void Sound::MarkDead() {
if (dead_) return;
if (Scene* s = scene()) {
- if (GameStream* os = s->GetGameStream()) {
+ if (SceneStream* os = s->GetSceneStream()) {
os->RemoveSound(this);
}
}
diff --git a/src/ballistica/media/component/sound.h b/src/ballistica/assets/component/sound.h
similarity index 68%
rename from src/ballistica/media/component/sound.h
rename to src/ballistica/assets/component/sound.h
index e712cced..ff0295b7 100644
--- a/src/ballistica/media/component/sound.h
+++ b/src/ballistica/assets/component/sound.h
@@ -1,16 +1,16 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_SOUND_H_
-#define BALLISTICA_MEDIA_COMPONENT_SOUND_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_SOUND_H_
+#define BALLISTICA_ASSETS_COMPONENT_SOUND_H_
#include
#include
-#include "ballistica/media/component/media_component.h"
+#include "ballistica/assets/component/asset_component.h"
namespace ballistica {
-class Sound : public MediaComponent {
+class Sound : public AssetComponent {
public:
Sound(const std::string& name, Scene* scene);
~Sound() override;
@@ -19,7 +19,7 @@ class Sound : public MediaComponent {
// Note that a sound's data can change over time as different
// versions are spooled in/out/etc.
auto GetSoundData() const -> SoundData* { return sound_data_.get(); }
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "Sound";
}
void MarkDead();
@@ -34,4 +34,4 @@ class Sound : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_SOUND_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_SOUND_H_
diff --git a/src/ballistica/media/component/texture.cc b/src/ballistica/assets/component/texture.cc
similarity index 64%
rename from src/ballistica/media/component/texture.cc
rename to src/ballistica/assets/component/texture.cc
index 6a8c31d0..52994fdb 100644
--- a/src/ballistica/media/component/texture.cc
+++ b/src/ballistica/assets/component/texture.cc
@@ -1,37 +1,37 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/component/texture.h"
+#include "ballistica/assets/component/texture.h"
-#include "ballistica/game/game_stream.h"
#include "ballistica/graphics/renderer.h"
#include "ballistica/python/class/python_class_texture.h"
#include "ballistica/scene/scene.h"
+#include "ballistica/scene/scene_stream.h"
namespace ballistica {
Texture::Texture(const std::string& name, Scene* scene)
- : MediaComponent(name, scene), dead_(false) {
+ : AssetComponent(name, scene), dead_(false) {
assert(InLogicThread());
// Add to the provided scene to get a numeric ID.
if (scene) {
- if (GameStream* os = scene->GetGameStream()) {
+ if (SceneStream* os = scene->GetSceneStream()) {
os->AddTexture(this);
}
}
{
- Media::MediaListsLock lock;
- texture_data_ = g_media->GetTextureData(name);
+ Assets::AssetListLock lock;
+ texture_data_ = g_assets->GetTextureData(name);
}
assert(texture_data_.exists());
}
// qrcode version
-Texture::Texture(const std::string& qr_url) : MediaComponent(qr_url, nullptr) {
+Texture::Texture(const std::string& qr_url) : AssetComponent(qr_url, nullptr) {
assert(InLogicThread());
{
- Media::MediaListsLock lock;
- texture_data_ = g_media->GetTextureDataQRCode(qr_url);
+ Assets::AssetListLock lock;
+ texture_data_ = g_assets->GetTextureDataQRCode(qr_url);
}
assert(texture_data_.exists());
}
@@ -43,7 +43,7 @@ void Texture::MarkDead() {
return;
}
if (Scene* s = scene()) {
- if (GameStream* os = s->GetGameStream()) {
+ if (SceneStream* os = s->GetSceneStream()) {
os->RemoveTexture(this);
}
}
diff --git a/src/ballistica/media/component/texture.h b/src/ballistica/assets/component/texture.h
similarity index 67%
rename from src/ballistica/media/component/texture.h
rename to src/ballistica/assets/component/texture.h
index d03ed2e5..892767ee 100644
--- a/src/ballistica/media/component/texture.h
+++ b/src/ballistica/assets/component/texture.h
@@ -1,17 +1,17 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_COMPONENT_TEXTURE_H_
-#define BALLISTICA_MEDIA_COMPONENT_TEXTURE_H_
+#ifndef BALLISTICA_ASSETS_COMPONENT_TEXTURE_H_
+#define BALLISTICA_ASSETS_COMPONENT_TEXTURE_H_
#include
-#include "ballistica/media/component/media_component.h"
-#include "ballistica/media/data/texture_data.h"
+#include "ballistica/assets/component/asset_component.h"
+#include "ballistica/assets/data/texture_data.h"
namespace ballistica {
// User-facing texture class.
-class Texture : public MediaComponent {
+class Texture : public AssetComponent {
public:
Texture(const std::string& name, Scene* scene);
explicit Texture(const std::string& qr_url);
@@ -21,7 +21,7 @@ class Texture : public MediaComponent {
// Note that a texture's data can change over time as different
// versions are spooled in/out/etc.
auto texture_data() const -> TextureData* { return texture_data_.get(); }
- auto GetMediaComponentTypeName() const -> std::string override {
+ auto GetAssetComponentTypeName() const -> std::string override {
return "Texture";
}
void MarkDead();
@@ -36,4 +36,4 @@ class Texture : public MediaComponent {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_COMPONENT_TEXTURE_H_
+#endif // BALLISTICA_ASSETS_COMPONENT_TEXTURE_H_
diff --git a/src/ballistica/media/data/media_component_data.cc b/src/ballistica/assets/data/asset_component_data.cc
similarity index 84%
rename from src/ballistica/media/data/media_component_data.cc
rename to src/ballistica/assets/data/asset_component_data.cc
index ed5f79c6..bb7e96ed 100644
--- a/src/ballistica/media/data/media_component_data.cc
+++ b/src/ballistica/assets/data/asset_component_data.cc
@@ -1,25 +1,25 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/media_component_data.h"
+#include "ballistica/assets/data/asset_component_data.h"
namespace ballistica {
-MediaComponentData::MediaComponentData() {
+AssetComponentData::AssetComponentData() {
assert(InLogicThread());
- assert(g_media);
+ assert(g_assets);
last_used_time_ = GetRealTime();
}
-MediaComponentData::~MediaComponentData() {
+AssetComponentData::~AssetComponentData() {
// at the moment whoever owns the last reference to us
// needs to make sure to unload us before we die..
// I feel like there should be a more elegant solution to that.
- assert(g_media);
+ assert(g_assets);
assert(!locked());
assert(!loaded());
}
-void MediaComponentData::Preload(bool already_locked) {
+void AssetComponentData::Preload(bool already_locked) {
LockGuard lock(this, already_locked ? LockGuard::Type::kDontLock
: LockGuard::Type::kLock);
if (!preloaded_) {
@@ -35,7 +35,7 @@ void MediaComponentData::Preload(bool already_locked) {
}
}
-void MediaComponentData::Load(bool already_locked) {
+void AssetComponentData::Load(bool already_locked) {
LockGuard lock(this, already_locked ? LockGuard::Type::kDontLock
: LockGuard::Type::kLock);
if (!preloaded_) {
@@ -57,7 +57,7 @@ void MediaComponentData::Load(bool already_locked) {
}
}
-void MediaComponentData::Unload(bool already_locked) {
+void AssetComponentData::Unload(bool already_locked) {
LockGuard lock(this, already_locked ? LockGuard::Type::kDontLock
: LockGuard::Type::kLock);
@@ -80,7 +80,7 @@ void MediaComponentData::Unload(bool already_locked) {
}
}
-MediaComponentData::LockGuard::LockGuard(MediaComponentData* data, Type type)
+AssetComponentData::LockGuard::LockGuard(AssetComponentData* data, Type type)
: data_(data) {
switch (type) {
case kLock: {
@@ -100,7 +100,7 @@ MediaComponentData::LockGuard::LockGuard(MediaComponentData* data, Type type)
}
}
-MediaComponentData::LockGuard::~LockGuard() {
+AssetComponentData::LockGuard::~LockGuard() {
if (holds_lock_) {
data_->Unlock();
}
diff --git a/src/ballistica/media/data/media_component_data.h b/src/ballistica/assets/data/asset_component_data.h
similarity index 88%
rename from src/ballistica/media/data/media_component_data.h
rename to src/ballistica/assets/data/asset_component_data.h
index 7ab99e25..4a2f91e8 100644
--- a/src/ballistica/media/data/media_component_data.h
+++ b/src/ballistica/assets/data/asset_component_data.h
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_MEDIA_COMPONENT_DATA_H_
-#define BALLISTICA_MEDIA_DATA_MEDIA_COMPONENT_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_ASSET_COMPONENT_DATA_H_
+#define BALLISTICA_ASSETS_DATA_ASSET_COMPONENT_DATA_H_
#include
#include
@@ -11,17 +11,17 @@
namespace ballistica {
-/// Base class for loadable media components.
-class MediaComponentData : public Object {
+/// Base class for loadable asset components.
+class AssetComponentData : public Object {
public:
- MediaComponentData();
- ~MediaComponentData() override;
+ AssetComponentData();
+ ~AssetComponentData() override;
void Preload(bool already_locked = false);
void Load(bool already_locked = false);
void Unload(bool already_locked = false);
auto preloaded() const -> bool { return preloaded_; }
auto loaded() const -> bool { return preloaded_ && loaded_; }
- virtual auto GetMediaType() const -> MediaType = 0;
+ virtual auto GetAssetType() const -> AssetType = 0;
// Return name or another identifier. For debugging purposes.
virtual auto GetName() const -> std::string { return "invalid"; }
@@ -35,14 +35,14 @@ class MediaComponentData : public Object {
class LockGuard {
public:
enum Type { kLock, kInheritLock, kDontLock };
- explicit LockGuard(MediaComponentData* data, Type type = kLock);
+ explicit LockGuard(AssetComponentData* data, Type type = kLock);
~LockGuard();
// Does this guard hold a lock?
auto holds_lock() const -> bool { return holds_lock_; }
private:
- MediaComponentData* data_ = nullptr;
+ AssetComponentData* data_ = nullptr;
bool holds_lock_ = false;
};
@@ -128,9 +128,9 @@ class MediaComponentData : public Object {
bool preloaded_ = false;
bool loaded_ = false;
std::mutex mutex_;
- BA_DISALLOW_CLASS_COPIES(MediaComponentData);
+ BA_DISALLOW_CLASS_COPIES(AssetComponentData);
};
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_MEDIA_COMPONENT_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_ASSET_COMPONENT_DATA_H_
diff --git a/src/ballistica/media/data/collide_model_data.cc b/src/ballistica/assets/data/collide_model_data.cc
similarity index 95%
rename from src/ballistica/media/data/collide_model_data.cc
rename to src/ballistica/assets/data/collide_model_data.cc
index 6a19aeac..763a6d23 100644
--- a/src/ballistica/media/data/collide_model_data.cc
+++ b/src/ballistica/assets/data/collide_model_data.cc
@@ -1,15 +1,15 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/collide_model_data.h"
+#include "ballistica/assets/data/collide_model_data.h"
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
namespace ballistica {
CollideModelData::CollideModelData(const std::string& file_name_in)
: file_name_(file_name_in) {
file_name_full_ =
- g_media->FindMediaFile(Media::FileType::kCollisionModel, file_name_in);
+ g_assets->FindAssetFile(Assets::FileType::kCollisionModel, file_name_in);
valid_ = true;
}
diff --git a/src/ballistica/media/data/collide_model_data.h b/src/ballistica/assets/data/collide_model_data.h
similarity index 71%
rename from src/ballistica/media/data/collide_model_data.h
rename to src/ballistica/assets/data/collide_model_data.h
index 3e3223d3..0dba9bfd 100644
--- a/src/ballistica/media/data/collide_model_data.h
+++ b/src/ballistica/assets/data/collide_model_data.h
@@ -1,26 +1,26 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_COLLIDE_MODEL_DATA_H_
-#define BALLISTICA_MEDIA_DATA_COLLIDE_MODEL_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_COLLIDE_MODEL_DATA_H_
+#define BALLISTICA_ASSETS_DATA_COLLIDE_MODEL_DATA_H_
#include
#include
-#include "ballistica/media/data/media_component_data.h"
+#include "ballistica/assets/data/asset_component_data.h"
#include "ode/ode.h"
namespace ballistica {
// Loadable model for collision detection.
-class CollideModelData : public MediaComponentData {
+class CollideModelData : public AssetComponentData {
public:
CollideModelData() = default;
explicit CollideModelData(const std::string& file_name_in);
void DoPreload() override;
void DoLoad() override;
void DoUnload() override;
- auto GetMediaType() const -> MediaType override {
- return MediaType::kCollideModel;
+ auto GetAssetType() const -> AssetType override {
+ return AssetType::kCollideModel;
}
auto GetName() const -> std::string override {
if (!file_name_full_.empty()) {
@@ -44,4 +44,4 @@ class CollideModelData : public MediaComponentData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_COLLIDE_MODEL_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_COLLIDE_MODEL_DATA_H_
diff --git a/src/ballistica/media/data/data_data.cc b/src/ballistica/assets/data/data_data.cc
similarity index 81%
rename from src/ballistica/media/data/data_data.cc
rename to src/ballistica/assets/data/data_data.cc
index 360d0d14..0a509fc4 100644
--- a/src/ballistica/media/data/data_data.cc
+++ b/src/ballistica/assets/data/data_data.cc
@@ -1,8 +1,8 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/data_data.h"
+#include "ballistica/assets/data/data_data.h"
-#include "ballistica/media/media.h"
+#include "ballistica/assets/assets.h"
#include "ballistica/python/python.h"
#include "ballistica/python/python_sys.h"
@@ -10,7 +10,7 @@ namespace ballistica {
DataData::DataData(const std::string& file_name_in) : file_name_(file_name_in) {
file_name_full_ =
- g_media->FindMediaFile(Media::FileType::kData, file_name_in);
+ g_assets->FindAssetFile(Assets::FileType::kData, file_name_in);
valid_ = true;
}
@@ -20,8 +20,8 @@ void DataData::DoPreload() {
// in the following case:
// - asset thread grabs payload lock for Preload()
// - asset thread tries to grab GIL in Preload(); spins.
- // - meanwhile, something in game thread has called Load()
- // - game thread holds GIL by default and now spins waiting on payload lock.
+ // - meanwhile, something in logic thread has called Load()
+ // - logic thread holds GIL by default and now spins waiting on payload lock.
// - deadlock :-(
// ...so the new plan is to simply load the file into a string in Preload()
diff --git a/src/ballistica/media/data/data_data.h b/src/ballistica/assets/data/data_data.h
similarity index 75%
rename from src/ballistica/media/data/data_data.h
rename to src/ballistica/assets/data/data_data.h
index 11888623..57baa42b 100644
--- a/src/ballistica/media/data/data_data.h
+++ b/src/ballistica/assets/data/data_data.h
@@ -1,16 +1,16 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_DATA_DATA_H_
-#define BALLISTICA_MEDIA_DATA_DATA_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_DATA_DATA_H_
+#define BALLISTICA_ASSETS_DATA_DATA_DATA_H_
#include
-#include "ballistica/media/data/media_component_data.h"
+#include "ballistica/assets/data/asset_component_data.h"
#include "ballistica/python/python_ref.h"
namespace ballistica {
-class DataData : public MediaComponentData {
+class DataData : public AssetComponentData {
public:
DataData() = default;
explicit DataData(const std::string& file_name_in);
@@ -19,7 +19,7 @@ class DataData : public MediaComponentData {
void DoLoad() override;
void DoUnload() override;
- auto GetMediaType() const -> MediaType override { return MediaType::kData; }
+ auto GetAssetType() const -> AssetType override { return AssetType::kData; }
auto GetName() const -> std::string override {
if (!file_name_full_.empty()) {
return file_name_full_;
@@ -44,4 +44,4 @@ class DataData : public MediaComponentData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_DATA_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_DATA_DATA_H_
diff --git a/src/ballistica/media/data/model_data.cc b/src/ballistica/assets/data/model_data.cc
similarity index 96%
rename from src/ballistica/media/data/model_data.cc
rename to src/ballistica/assets/data/model_data.cc
index 637e4153..48e2cf99 100644
--- a/src/ballistica/media/data/model_data.cc
+++ b/src/ballistica/assets/data/model_data.cc
@@ -1,6 +1,6 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/model_data.h"
+#include "ballistica/assets/data/model_data.h"
#include "ballistica/graphics/graphics_server.h"
#include "ballistica/graphics/renderer.h"
@@ -10,7 +10,7 @@ namespace ballistica {
ModelData::ModelData(const std::string& file_name_in)
: file_name_(file_name_in) {
file_name_full_ =
- g_media->FindMediaFile(Media::FileType::kModel, file_name_in);
+ g_assets->FindAssetFile(Assets::FileType::kModel, file_name_in);
valid_ = true;
}
diff --git a/src/ballistica/media/data/model_data.h b/src/ballistica/assets/data/model_data.h
similarity index 81%
rename from src/ballistica/media/data/model_data.h
rename to src/ballistica/assets/data/model_data.h
index cb155c6c..e5388922 100644
--- a/src/ballistica/media/data/model_data.h
+++ b/src/ballistica/assets/data/model_data.h
@@ -1,24 +1,24 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_MODEL_DATA_H_
-#define BALLISTICA_MEDIA_DATA_MODEL_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_MODEL_DATA_H_
+#define BALLISTICA_ASSETS_DATA_MODEL_DATA_H_
#include
#include
-#include "ballistica/media/data/media_component_data.h"
-#include "ballistica/media/data/model_renderer_data.h"
+#include "ballistica/assets/data/asset_component_data.h"
+#include "ballistica/assets/data/model_renderer_data.h"
namespace ballistica {
-class ModelData : public MediaComponentData {
+class ModelData : public AssetComponentData {
public:
ModelData() = default;
explicit ModelData(const std::string& file_name_in);
void DoPreload() override;
void DoLoad() override;
void DoUnload() override;
- auto GetMediaType() const -> MediaType override { return MediaType::kModel; }
+ auto GetAssetType() const -> AssetType override { return AssetType::kModel; }
auto GetName() const -> std::string override {
if (!file_name_full_.empty()) {
return file_name_full_;
@@ -64,4 +64,4 @@ class ModelData : public MediaComponentData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_MODEL_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_MODEL_DATA_H_
diff --git a/src/ballistica/media/data/model_renderer_data.h b/src/ballistica/assets/data/model_renderer_data.h
similarity index 52%
rename from src/ballistica/media/data/model_renderer_data.h
rename to src/ballistica/assets/data/model_renderer_data.h
index ad23080a..4128e465 100644
--- a/src/ballistica/media/data/model_renderer_data.h
+++ b/src/ballistica/assets/data/model_renderer_data.h
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_MODEL_RENDERER_DATA_H_
-#define BALLISTICA_MEDIA_DATA_MODEL_RENDERER_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_MODEL_RENDERER_DATA_H_
+#define BALLISTICA_ASSETS_DATA_MODEL_RENDERER_DATA_H_
#include "ballistica/core/object.h"
@@ -11,11 +11,11 @@ namespace ballistica {
// this is provided by the renderer
class ModelRendererData : public Object {
public:
- auto GetDefaultOwnerThread() const -> ThreadIdentifier override {
- return ThreadIdentifier::kMain;
+ auto GetDefaultOwnerThread() const -> ThreadTag override {
+ return ThreadTag::kMain;
}
};
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_MODEL_RENDERER_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_MODEL_RENDERER_DATA_H_
diff --git a/src/ballistica/media/data/sound_data.cc b/src/ballistica/assets/data/sound_data.cc
similarity index 94%
rename from src/ballistica/media/data/sound_data.cc
rename to src/ballistica/assets/data/sound_data.cc
index e5c2ab40..5b257c0d 100644
--- a/src/ballistica/media/data/sound_data.cc
+++ b/src/ballistica/assets/data/sound_data.cc
@@ -1,6 +1,6 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/sound_data.h"
+#include "ballistica/assets/data/sound_data.h"
#if BA_ENABLE_AUDIO
#if BA_USE_TREMOR_VORBIS
@@ -10,8 +10,8 @@
#endif
#endif // BA_ENABLE_AUDIO
+#include "ballistica/assets/assets.h"
#include "ballistica/audio/audio_server.h"
-#include "ballistica/media/media.h"
#include "ballistica/python/python.h"
// Need to move away from OpenAL on Apple stuff.
@@ -56,8 +56,8 @@ static auto LoadOgg(const char* file_name, std::vector* buffer,
f = g_platform->FOpen(file_name, "rb");
if (f == nullptr) {
fallback = true;
- Log(std::string("Error: Can't open sound file '") + file_name
- + "' for reading...");
+ Log(LogLevel::kError, std::string("Can't open sound file '") + file_name
+ + "' for reading...");
// Attempt a fallback standin; if that doesn't work, throw in the towel.
file_name = "data/global/audio/blank.ogg";
@@ -77,7 +77,8 @@ static auto LoadOgg(const char* file_name, std::vector* buffer,
// Try opening the given file
if (ov_open_callbacks(f, &ogg_file, nullptr, 0, callbacks) != 0) {
- Log(std::string("Error decoding sound file '") + file_name + "'");
+ Log(LogLevel::kError,
+ std::string("Error decoding sound file '") + file_name + "'");
fclose(f);
@@ -199,8 +200,9 @@ static void LoadCachedOgg(const char* file_name, std::vector* buffer,
// with invalid formats of 0 once. Report and ignore if we see
// something like that.
if (*format != AL_FORMAT_MONO16 && *format != AL_FORMAT_STEREO16) {
- Log(std::string("Ignoring invalid audio cache of ") + file_name
- + " with format " + std::to_string(*format));
+ Log(LogLevel::kError, std::string("Ignoring invalid audio cache of ")
+ + file_name + " with format "
+ + std::to_string(*format));
} else {
return; // SUCCESS!!!!
}
@@ -248,7 +250,7 @@ SoundData::SoundData(const std::string& file_name_in)
#endif // BA_ENABLE_AUDIO
last_play_time_(0) {
file_name_full_ =
- g_media->FindMediaFile(Media::FileType::kSound, file_name_in);
+ g_assets->FindAssetFile(Assets::FileType::kSound, file_name_in);
valid_ = true;
}
diff --git a/src/ballistica/media/data/sound_data.h b/src/ballistica/assets/data/sound_data.h
similarity index 82%
rename from src/ballistica/media/data/sound_data.h
rename to src/ballistica/assets/data/sound_data.h
index f1bc3092..d24172de 100644
--- a/src/ballistica/media/data/sound_data.h
+++ b/src/ballistica/assets/data/sound_data.h
@@ -1,17 +1,17 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_SOUND_DATA_H_
-#define BALLISTICA_MEDIA_DATA_SOUND_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_SOUND_DATA_H_
+#define BALLISTICA_ASSETS_DATA_SOUND_DATA_H_
#include
#include
+#include "ballistica/assets/data/asset_component_data.h"
#include "ballistica/audio/al_sys.h"
-#include "ballistica/media/data/media_component_data.h"
namespace ballistica {
-class SoundData : public MediaComponentData {
+class SoundData : public AssetComponentData {
public:
SoundData() = default;
explicit SoundData(const std::string& file_name_in);
@@ -20,7 +20,7 @@ class SoundData : public MediaComponentData {
// FIXME: Should make sure the sound_data isn't in use before unloading it.
void DoUnload() override;
- auto GetMediaType() const -> MediaType override { return MediaType::kSound; }
+ auto GetAssetType() const -> AssetType override { return AssetType::kSound; }
auto GetName() const -> std::string override {
if (!file_name_full_.empty())
return file_name_full_;
@@ -55,4 +55,4 @@ class SoundData : public MediaComponentData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_SOUND_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_SOUND_DATA_H_
diff --git a/src/ballistica/media/data/texture_data.cc b/src/ballistica/assets/data/texture_data.cc
similarity index 98%
rename from src/ballistica/media/data/texture_data.cc
rename to src/ballistica/assets/data/texture_data.cc
index d931abfd..11aa82f7 100644
--- a/src/ballistica/media/data/texture_data.cc
+++ b/src/ballistica/assets/data/texture_data.cc
@@ -1,7 +1,9 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/texture_data.h"
+#include "ballistica/assets/data/texture_data.h"
+#include "ballistica/assets/data/texture_preload_data.h"
+#include "ballistica/assets/data/texture_renderer_data.h"
#include "ballistica/graphics/graphics.h"
#include "ballistica/graphics/graphics_server.h"
#include "ballistica/graphics/renderer.h"
@@ -9,8 +11,6 @@
#include "ballistica/graphics/texture/dds.h"
#include "ballistica/graphics/texture/ktx.h"
#include "ballistica/graphics/texture/pvr.h"
-#include "ballistica/media/data/texture_preload_data.h"
-#include "ballistica/media/data/texture_renderer_data.h"
#include "external/qr_code_generator/QrCode.hpp"
namespace ballistica {
@@ -43,7 +43,8 @@ TextureData::TextureData() = default;
TextureData::TextureData(const std::string& file_in, TextureType type_in,
TextureMinQuality min_quality_in)
: file_name_(file_in), type_(type_in), min_quality_(min_quality_in) {
- file_name_full_ = g_media->FindMediaFile(Media::FileType::kTexture, file_in);
+ file_name_full_ =
+ g_assets->FindAssetFile(Assets::FileType::kTexture, file_in);
valid_ = true;
}
diff --git a/src/ballistica/media/data/texture_data.h b/src/ballistica/assets/data/texture_data.h
similarity index 84%
rename from src/ballistica/media/data/texture_data.h
rename to src/ballistica/assets/data/texture_data.h
index 1083f101..e1ce22db 100644
--- a/src/ballistica/media/data/texture_data.h
+++ b/src/ballistica/assets/data/texture_data.h
@@ -1,17 +1,17 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_TEXTURE_DATA_H_
-#define BALLISTICA_MEDIA_DATA_TEXTURE_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_TEXTURE_DATA_H_
+#define BALLISTICA_ASSETS_DATA_TEXTURE_DATA_H_
#include
#include
-#include "ballistica/media/data/media_component_data.h"
+#include "ballistica/assets/data/asset_component_data.h"
namespace ballistica {
// Loadable texture media component.
-class TextureData : public MediaComponentData {
+class TextureData : public AssetComponentData {
public:
TextureData();
~TextureData() override;
@@ -28,8 +28,8 @@ class TextureData : public MediaComponentData {
auto GetNameFull() const -> std::string override { return file_name_full(); }
auto file_name() const -> const std::string& { return file_name_; }
auto file_name_full() const -> const std::string& { return file_name_full_; }
- auto GetMediaType() const -> MediaType override {
- return MediaType::kTexture;
+ auto GetAssetType() const -> AssetType override {
+ return AssetType::kTexture;
}
void DoPreload() override;
void DoLoad() override;
@@ -59,4 +59,4 @@ class TextureData : public MediaComponentData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_TEXTURE_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_TEXTURE_DATA_H_
diff --git a/src/ballistica/media/data/texture_preload_data.cc b/src/ballistica/assets/data/texture_preload_data.cc
similarity index 99%
rename from src/ballistica/media/data/texture_preload_data.cc
rename to src/ballistica/assets/data/texture_preload_data.cc
index 3f54a7d4..eda797fa 100644
--- a/src/ballistica/media/data/texture_preload_data.cc
+++ b/src/ballistica/assets/data/texture_preload_data.cc
@@ -1,13 +1,13 @@
// Released under the MIT License. See LICENSE for details.
-#include "ballistica/media/data/texture_preload_data.h"
+#include "ballistica/assets/data/texture_preload_data.h"
#if BA_OSTYPE_LINUX
#include
#endif
+#include "ballistica/assets/component/texture.h"
#include "ballistica/graphics/texture/ktx.h"
-#include "ballistica/media/component/texture.h"
namespace ballistica {
diff --git a/src/ballistica/media/data/texture_preload_data.h b/src/ballistica/assets/data/texture_preload_data.h
similarity index 86%
rename from src/ballistica/media/data/texture_preload_data.h
rename to src/ballistica/assets/data/texture_preload_data.h
index db0454df..03c9d5c4 100644
--- a/src/ballistica/media/data/texture_preload_data.h
+++ b/src/ballistica/assets/data/texture_preload_data.h
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_TEXTURE_PRELOAD_DATA_H_
-#define BALLISTICA_MEDIA_DATA_TEXTURE_PRELOAD_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_TEXTURE_PRELOAD_DATA_H_
+#define BALLISTICA_ASSETS_DATA_TEXTURE_PRELOAD_DATA_H_
#include "ballistica/ballistica.h"
@@ -37,4 +37,4 @@ class TexturePreloadData {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_TEXTURE_PRELOAD_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_TEXTURE_PRELOAD_DATA_H_
diff --git a/src/ballistica/media/data/texture_renderer_data.h b/src/ballistica/assets/data/texture_renderer_data.h
similarity index 65%
rename from src/ballistica/media/data/texture_renderer_data.h
rename to src/ballistica/assets/data/texture_renderer_data.h
index ca7a71de..f3467940 100644
--- a/src/ballistica/media/data/texture_renderer_data.h
+++ b/src/ballistica/assets/data/texture_renderer_data.h
@@ -1,7 +1,7 @@
// Released under the MIT License. See LICENSE for details.
-#ifndef BALLISTICA_MEDIA_DATA_TEXTURE_RENDERER_DATA_H_
-#define BALLISTICA_MEDIA_DATA_TEXTURE_RENDERER_DATA_H_
+#ifndef BALLISTICA_ASSETS_DATA_TEXTURE_RENDERER_DATA_H_
+#define BALLISTICA_ASSETS_DATA_TEXTURE_RENDERER_DATA_H_
namespace ballistica {
@@ -9,8 +9,8 @@ namespace ballistica {
// this is extended by the renderer
class TextureRendererData : public Object {
public:
- auto GetDefaultOwnerThread() const -> ThreadIdentifier override {
- return ThreadIdentifier::kMain;
+ auto GetDefaultOwnerThread() const -> ThreadTag override {
+ return ThreadTag::kMain;
}
// Create the renderer data but don't load it in yet.
@@ -24,4 +24,4 @@ class TextureRendererData : public Object {
} // namespace ballistica
-#endif // BALLISTICA_MEDIA_DATA_TEXTURE_RENDERER_DATA_H_
+#endif // BALLISTICA_ASSETS_DATA_TEXTURE_RENDERER_DATA_H_
diff --git a/src/ballistica/audio/al_sys.cc b/src/ballistica/audio/al_sys.cc
index 11518df6..c39a14d2 100644
--- a/src/ballistica/audio/al_sys.cc
+++ b/src/ballistica/audio/al_sys.cc
@@ -16,13 +16,14 @@ namespace ballistica {
void _check_al_error(const char* file, int line) {
if (g_audio_server->paused()) {
- Log(Utils::BaseName(file) + ":" + std::to_string(line)
- + ": Checking OpenAL error while paused.");
+ Log(LogLevel::kError, Utils::BaseName(file) + ":" + std::to_string(line)
+ + ": Checking OpenAL error while paused.");
}
ALenum al_err = alGetError();
if (al_err != AL_NO_ERROR) {
- Log(Utils::BaseName(file) + ":" + std::to_string(line)
- + ": OpenAL Error: " + GetALErrorString(al_err) + ";");
+ Log(LogLevel::kError, Utils::BaseName(file) + ":" + std::to_string(line)
+ + ": OpenAL Error: " + GetALErrorString(al_err)
+ + ";");
}
}
diff --git a/src/ballistica/audio/audio.cc b/src/ballistica/audio/audio.cc
index 95238edc..8f4fef9a 100644
--- a/src/ballistica/audio/audio.cc
+++ b/src/ballistica/audio/audio.cc
@@ -2,20 +2,14 @@
#include "ballistica/audio/audio.h"
+#include "ballistica/assets/data/sound_data.h"
#include "ballistica/audio/audio_server.h"
#include "ballistica/audio/audio_source.h"
#include "ballistica/core/thread.h"
-#include "ballistica/media/data/sound_data.h"
namespace ballistica {
-Audio::Audio() { assert(InLogicThread()); }
-
-void Audio::Init() {
- // Init our singleton.
- assert(g_audio == nullptr);
- g_audio = new Audio();
-}
+Audio::Audio() {}
void Audio::Reset() {
assert(InLogicThread());
diff --git a/src/ballistica/audio/audio.h b/src/ballistica/audio/audio.h
index 3a0b40d0..1cc1f000 100644
--- a/src/ballistica/audio/audio.h
+++ b/src/ballistica/audio/audio.h
@@ -15,14 +15,15 @@ namespace ballistica {
/// used by the game and/or other threads.
class Audio {
public:
- static void Init();
- void Reset();
+ Audio();
+ auto Reset() -> void;
- void SetVolumes(float music_volume, float sound_volume);
+ auto SetVolumes(float music_volume, float sound_volume) -> void;
- void SetListenerPosition(const Vector3f& p);
- void SetListenerOrientation(const Vector3f& forward, const Vector3f& up);
- void SetSoundPitch(float pitch);
+ auto SetListenerPosition(const Vector3f& p) -> void;
+ auto SetListenerOrientation(const Vector3f& forward, const Vector3f& up)
+ -> void;
+ auto SetSoundPitch(float pitch) -> void;
// Return a pointer to a locked sound source, or nullptr if they're all busy.
// The sound source will be reset to standard settings (no loop, fade 1, pos
@@ -41,9 +42,9 @@ class Audio {
auto IsSoundPlaying(uint32_t play_id) -> bool;
// Simple one-shot play functions.
- void PlaySound(SoundData* s, float volume = 1.0f);
- void PlaySoundAtPosition(SoundData* sound, float volume, float x, float y,
- float z);
+ auto PlaySound(SoundData* s, float volume = 1.0f) -> void;
+ auto PlaySoundAtPosition(SoundData* sound, float volume, float x, float y,
+ float z) -> void;
// Call this if you want to prevent repeated plays of the same sound. It'll
// tell you if the sound has been played recently. The one-shot sound-play
@@ -51,19 +52,17 @@ class Audio {
auto ShouldPlay(SoundData* s) -> bool;
// Hmm; shouldn't these be accessed through the Source class?
- void PushSourceFadeOutCall(uint32_t play_id, uint32_t time);
- void PushSourceStopSoundCall(uint32_t play_id);
+ auto PushSourceFadeOutCall(uint32_t play_id, uint32_t time) -> void;
+ auto PushSourceStopSoundCall(uint32_t play_id) -> void;
- void AddClientSource(AudioSource* source);
+ auto AddClientSource(AudioSource* source) -> void;
- void MakeSourceAvailable(AudioSource* source);
+ auto MakeSourceAvailable(AudioSource* source) -> void;
auto available_sources_mutex() -> std::mutex& {
return available_sources_mutex_;
}
private:
- Audio();
-
// Flat list of client sources indexed by id.
std::vector client_sources_;
diff --git a/src/ballistica/audio/audio_server.cc b/src/ballistica/audio/audio_server.cc
index 5e3f4727..511d8a97 100644
--- a/src/ballistica/audio/audio_server.cc
+++ b/src/ballistica/audio/audio_server.cc
@@ -3,17 +3,17 @@
#include "ballistica/audio/audio_server.h"
#include "ballistica/app/app.h"
+#include "ballistica/assets/assets.h"
+#include "ballistica/assets/data/sound_data.h"
#include "ballistica/audio/al_sys.h"
#include "ballistica/audio/audio.h"
#include "ballistica/audio/audio_source.h"
#include "ballistica/audio/audio_streamer.h"
#include "ballistica/audio/ogg_stream.h"
#include "ballistica/core/thread.h"
-#include "ballistica/game/game.h"
#include "ballistica/generic/timer.h"
+#include "ballistica/logic/logic.h"
#include "ballistica/math/vector3f.h"
-#include "ballistica/media/data/sound_data.h"
-#include "ballistica/media/media.h"
// Need to move away from OpenAL on Apple stuff.
#if __clang__
@@ -30,10 +30,10 @@ extern "C" void opensl_resume_playback();
extern std::string g_rift_audio_device_name;
#endif
-const int kAudioProcessIntervalNormal = 500;
-const int kAudioProcessIntervalFade = 50;
-const int kAudioProcessIntervalPendingLoad = 1;
-const bool kShowInUseSounds = false;
+const int kAudioProcessIntervalNormal{500};
+const int kAudioProcessIntervalFade{50};
+const int kAudioProcessIntervalPendingLoad{1};
+const bool kShowInUseSounds{};
int AudioServer::al_source_count_ = 0;
@@ -55,7 +55,7 @@ class AudioServer::ThreadSource : public Object {
// not be used.
ThreadSource(AudioServer* audio_thread, int id, bool* valid);
~ThreadSource() override;
- void Reset() {
+ auto Reset() -> void {
SetIsMusic(false);
SetPositional(true);
SetPosition(0, 0, 0);
@@ -66,18 +66,18 @@ class AudioServer::ThreadSource : public Object {
/// Set whether a sound is "music".
/// This influences which volume controls affect it.
- void SetIsMusic(bool m);
+ auto SetIsMusic(bool m) -> void;
/// Set whether a source is positional.
/// A non-positional source's position coords are always relative to the
/// listener - ie: 0, 0, 0 will always be centered.
- void SetPositional(bool p);
- void SetPosition(float x, float y, float z);
- void SetGain(float g);
- void SetFade(float f);
- void SetLooping(bool loop);
+ auto SetPositional(bool p) -> void;
+ auto SetPosition(float x, float y, float z) -> void;
+ auto SetGain(float g) -> void;
+ auto SetFade(float f) -> void;
+ auto SetLooping(bool loop) -> void;
auto Play(const Object::Ref* s) -> uint32_t;
- void Stop();
+ auto Stop() -> void;
auto play_count() -> uint32_t { return play_count_; }
auto is_streamed() const -> bool { return is_streamed_; }
auto current_is_music() const -> bool { return current_is_music_; }
@@ -86,41 +86,41 @@ class AudioServer::ThreadSource : public Object {
auto play_id() const -> uint32_t {
return (play_count_ << 16u) | (static_cast(id_) & 0xFFFFu);
}
- void UpdateAvailability();
- auto GetDefaultOwnerThread() const -> ThreadIdentifier override;
+ auto UpdateAvailability() -> void;
+ auto GetDefaultOwnerThread() const -> ThreadTag override;
auto client_source() const -> AudioSource* { return client_source_.get(); }
auto source_sound() const -> SoundData* {
return source_sound_ ? source_sound_->get() : nullptr;
}
- void UpdatePitch();
- void UpdateVolume();
- void ExecStop();
- void ExecPlay();
- void Update();
+ auto UpdatePitch() -> void;
+ auto UpdateVolume() -> void;
+ auto ExecStop() -> void;
+ auto ExecPlay() -> void;
+ auto Update() -> void;
private:
- bool looping_ = false;
+ bool looping_{};
std::unique_ptr client_source_;
- float fade_ = 1.0f;
- float gain_ = 1.0f;
- AudioServer* audio_thread_;
- bool valid_ = false;
- const Object::Ref* source_sound_ = nullptr;
- int id_;
- uint32_t play_count_ = 0;
- bool is_actually_playing_ = false;
- bool want_to_play_ = false;
+ float fade_{1.0f};
+ float gain_{1.0f};
+ AudioServer* audio_thread_{};
+ bool valid_{};
+ const Object::Ref* source_sound_{};
+ int id_{};
+ uint32_t play_count_{};
+ bool is_actually_playing_{};
+ bool want_to_play_{};
#if BA_ENABLE_AUDIO
- ALuint source_ = 0;
+ ALuint source_{};
#endif
- bool is_streamed_ = false;
+ bool is_streamed_{};
/// Whether we should be designated as "music" next time we play.
- bool is_music_ = false;
+ bool is_music_{};
/// Whether currently playing as music.
- bool current_is_music_ = false;
+ bool current_is_music_{};
#if BA_ENABLE_AUDIO
Object::Ref streamer_;
@@ -144,7 +144,7 @@ struct AudioServer::SoundFadeNode {
void AudioServer::SetPaused(bool pause) {
if (!paused_) {
if (!pause) {
- Log("Error: got audio unpause request when already unpaused.");
+ Log(LogLevel::kError, "Got audio unpause request when already unpaused.");
} else {
#if BA_OSTYPE_IOS_TVOS
// apple recommends this during audio-interruptions..
@@ -163,7 +163,7 @@ void AudioServer::SetPaused(bool pause) {
} else {
// unpause if requested..
if (pause) {
- Log("Error: Got audio pause request when already paused.");
+ Log(LogLevel::kError, "Got audio pause request when already paused.");
} else {
#if BA_OSTYPE_IOS_TVOS
// apple recommends this during audio-interruptions..
@@ -321,24 +321,34 @@ void AudioServer::PushSetListenerOrientationCall(const Vector3f& forward,
});
}
-AudioServer::AudioServer(Thread* thread)
- : thread_(thread), impl_{new AudioServer::Impl()} {
- // we're a singleton...
+AudioServer::AudioServer() : impl_{new AudioServer::Impl()} {
+ // We're a singleton; make sure we don't already exist.
assert(g_audio_server == nullptr);
- g_audio_server = this;
- thread->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
- thread->AddResumeCallback(NewLambdaRunnableRaw([this] { OnThreadResume(); }));
+ // Spin up our thread.
+ thread_ = new Thread(ThreadTag::kAudio);
+ g_app->pausable_threads.push_back(thread_);
+}
+
+auto AudioServer::OnAppStart() -> void {
+ thread_->PushCallSynchronous([this] { OnAppStartInThread(); });
+}
+
+auto AudioServer::OnAppStartInThread() -> void {
+ assert(InAudioThread());
+ thread()->AddPauseCallback(NewLambdaRunnableRaw([this] { OnThreadPause(); }));
+ thread()->AddResumeCallback(
+ NewLambdaRunnableRaw([this] { OnThreadResume(); }));
// Get our thread to give us periodic processing time.
- process_timer_ = thread->NewTimer(kAudioProcessIntervalNormal, true,
- NewLambdaRunnable([this] { Process(); }));
+ process_timer_ = thread()->NewTimer(kAudioProcessIntervalNormal, true,
+ NewLambdaRunnable([this] { Process(); }));
#if BA_ENABLE_AUDIO
// Bring up OpenAL stuff.
{
- const char* alDeviceName = nullptr;
+ const char* al_device_name = nullptr;
// On the rift build in vr mode we need to make sure we open the rift audio
// device.
@@ -347,7 +357,7 @@ AudioServer::AudioServer(Thread* thread)
ALboolean enumeration =
alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT");
if (enumeration == AL_FALSE) {
- Log("OpenAL enumeration extensions missing.");
+ Log(LogLevel::kError, "OpenAL enumeration extensions missing.");
} else {
const ALCchar* devices =
alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
@@ -357,26 +367,26 @@ AudioServer::AudioServer(Thread* thread)
// If the string is blank, we weren't able to find the oculus
// audio device. In that case we'll just go with default.
if (g_rift_audio_device_name != "") {
- // Log("AL Devices list:");
- // Log("----------");
+ // Log(LogLevel::kInfo, "AL Devices list:");
+ // Log(LogLevel::kInfo, "----------");
while (device && *device != '\0' && next && *next != '\0') {
// These names seem to be things like "OpenAL Soft on FOO"
// ..we should be able to search for FOO.
if (strstr(device, g_rift_audio_device_name.c_str())) {
- alDeviceName = device;
+ al_device_name = device;
}
len = strlen(device);
device += (len + 1);
next += (len + 2);
}
- // Log("----------");
+ // Log(LogLevel::kInfo, "----------");
}
}
}
#endif // BA_RIFT_BUILD
ALCdevice* device;
- device = alcOpenDevice(alDeviceName);
+ device = alcOpenDevice(al_device_name);
BA_PRECONDITION(device);
impl_->alc_context_ = alcCreateContext(device, nullptr);
BA_PRECONDITION(impl_->alc_context_);
@@ -404,8 +414,8 @@ AudioServer::AudioServer(Thread* thread)
sound_source_refs_.push_back(s);
sources_.push_back(&(*s));
} else {
- Log("Error: Made " + std::to_string(i) + " sources; (wanted "
- + std::to_string(target_source_count) + ").");
+ Log(LogLevel::kError, "Made " + std::to_string(i) + " sources; (wanted "
+ + std::to_string(target_source_count) + ").");
break;
}
}
@@ -463,9 +473,10 @@ void AudioServer::UpdateAvailableSources() {
// that probably means somebody's grabbing a source but never
// resubmitting it.
if (t - i->client_source()->last_lock_time() > 10000) {
- Log("Error: Client audio source has been locked for too long; "
+ Log(LogLevel::kError,
+ "Client audio source has been locked for too long; "
"probably leaked. (debug id "
- + std::to_string(i->client_source()->lock_debug_id()) + ")");
+ + std::to_string(i->client_source()->lock_debug_id()) + ")");
}
continue;
}
@@ -601,7 +612,7 @@ void AudioServer::Process() {
// If we're paused we don't do nothin'.
if (!paused_) {
// Do some loading...
- have_pending_loads_ = g_media->RunPendingAudioLoads();
+ have_pending_loads_ = g_assets->RunPendingAudioLoads();
// Keep that available-sources list filled.
UpdateAvailableSources();
@@ -666,7 +677,7 @@ void AudioServer::FadeSoundOut(uint32_t play_id, uint32_t time) {
std::make_pair(play_id, SoundFadeNode(play_id, time, true)));
}
-void AudioServer::DeleteMediaComponent(MediaComponentData* c) {
+void AudioServer::DeleteAssetComponent(AssetComponentData* c) {
assert(InAudioThread());
c->Unload();
delete c;
@@ -684,8 +695,8 @@ AudioServer::ThreadSource::ThreadSource(AudioServer* audio_thread_in, int id_in,
ALenum err = alGetError();
valid_ = (err == AL_NO_ERROR);
if (!valid_) {
- Log(std::string("Error: AL Error ") + GetALErrorString(err)
- + " on source creation.");
+ Log(LogLevel::kError, std::string("AL Error ") + GetALErrorString(err)
+ + " on source creation.");
} else {
// In vr mode we keep the microphone a bit closer to the camera
// for realism purposes, so we need stuff louder in general.
@@ -702,7 +713,9 @@ AudioServer::ThreadSource::ThreadSource(AudioServer* audio_thread_in, int id_in,
CHECK_AL_ERROR;
}
*valid_out = valid_;
- if (valid_) al_source_count_++;
+ if (valid_) {
+ al_source_count_++;
+ }
#endif // BA_ENABLE_AUDIO
}
@@ -734,9 +747,8 @@ AudioServer::ThreadSource::~ThreadSource() {
#endif // BA_ENABLE_AUDIO
}
-auto AudioServer::ThreadSource::GetDefaultOwnerThread() const
- -> ThreadIdentifier {
- return ThreadIdentifier::kAudio;
+auto AudioServer::ThreadSource::GetDefaultOwnerThread() const -> ThreadTag {
+ return ThreadTag::kAudio;
}
void AudioServer::ThreadSource::UpdateAvailability() {
@@ -867,9 +879,9 @@ void AudioServer::ThreadSource::SetPosition(float x, float y, float z) {
z = 500;
}
if (oob) {
- BA_LOG_ONCE(
- "Error: AudioServer::ThreadSource::SetPosition"
- " got out-of-bounds value.");
+ BA_LOG_ONCE(LogLevel::kError,
+ "AudioServer::ThreadSource::SetPosition"
+ " got out-of-bounds value.");
}
ALfloat source_pos[] = {x, y, z};
alSourcefv(source_, AL_POSITION, source_pos);
@@ -1033,7 +1045,7 @@ void AudioServer::ThreadSource::Stop() {
// to free up...
// (we can't kill media-refs outside the main thread)
if (source_sound_) {
- assert(g_media);
+ assert(g_assets);
g_audio_server->AddSoundRefDelete(source_sound_);
source_sound_ = nullptr;
}
@@ -1087,22 +1099,22 @@ void AudioServer::PushSetSoundPitchCall(float val) {
void AudioServer::PushSetPausedCall(bool pause) {
thread()->PushCall([this, pause] {
if (g_buildconfig.ostype_android()) {
- Log("Error: Shouldn't be getting SetPausedCall on android.");
+ Log(LogLevel::kError, "Shouldn't be getting SetPausedCall on android.");
}
SetPaused(pause);
});
}
void AudioServer::PushComponentUnloadCall(
- const std::vector*>& components) {
+ const std::vector*>& components) {
thread()->PushCall([this, components] {
// Unload all components we were passed...
for (auto&& i : components) {
(**i).Unload();
}
- // ...and then ship these pointers back to the game thread, so it can free
+ // ...and then ship these pointers back to the logic thread, so it can free
// the references.
- g_game->PushFreeMediaComponentRefsCall(components);
+ g_logic->PushFreeAssetComponentRefsCall(components);
});
}
@@ -1118,8 +1130,9 @@ void AudioServer::AddSoundRefDelete(const Object::Ref* c) {
std::scoped_lock lock(sound_ref_delete_list_mutex_);
sound_ref_delete_list_.push_back(c);
}
- // Now push a call to the game thread to do the deletes.
- g_game->thread()->PushCall([] { g_audio_server->ClearSoundRefDeleteList(); });
+ // Now push a call to the logic thread to do the deletes.
+ g_logic->thread()->PushCall(
+ [] { g_audio_server->ClearSoundRefDeleteList(); });
}
void AudioServer::ClearSoundRefDeleteList() {
@@ -1142,7 +1155,7 @@ void AudioServer::BeginInterruption() {
break;
}
if (GetRealTime() - t > 1000) {
- Log("Error: Timed out waiting for audio pause.");
+ Log(LogLevel::kError, "Timed out waiting for audio pause.");
break;
}
Platform::SleepMS(2);
@@ -1164,7 +1177,7 @@ void AudioServer::EndInterruption() {
break;
}
if (GetRealTime() - t > 1000) {
- Log("Error: Timed out waiting for audio unpause.");
+ Log(LogLevel::kError, "Timed out waiting for audio unpause.");
break;
}
Platform::SleepMS(2);
diff --git a/src/ballistica/audio/audio_server.h b/src/ballistica/audio/audio_server.h
index d747b98e..e8d6720e 100644
--- a/src/ballistica/audio/audio_server.h
+++ b/src/ballistica/audio/audio_server.h
@@ -22,45 +22,47 @@ class AudioServer {
return play_id >> 16u;
}
- explicit AudioServer(Thread* o);
+ AudioServer();
+ auto OnAppStart() -> void;
- void PushSetVolumesCall(float music_volume, float sound_volume);
- void PushSetSoundPitchCall(float val);
- void PushSetPausedCall(bool pause);
+ auto PushSetVolumesCall(float music_volume, float sound_volume) -> void;
+ auto PushSetSoundPitchCall(float val) -> void;
+ auto PushSetPausedCall(bool pause) -> void;
- static void BeginInterruption();
- static void EndInterruption();
+ static auto BeginInterruption() -> void;
+ static auto EndInterruption() -> void;
- void PushSetListenerPositionCall(const Vector3f& p);
- void PushSetListenerOrientationCall(const Vector3f& forward,
- const Vector3f& up);
- void PushResetCall();
- void PushHavePendingLoadsCall();
- void PushComponentUnloadCall(
- const std::vector*>& components);
+ auto PushSetListenerPositionCall(const Vector3f& p) -> void;
+ auto PushSetListenerOrientationCall(const Vector3f& forward,
+ const Vector3f& up) -> void;
+ auto PushResetCall() -> void;
+ auto PushHavePendingLoadsCall() -> void;
+ auto PushComponentUnloadCall(
+ const std::vector*>& components) -> void;
- /// For use by g_game_module().
- void ClearSoundRefDeleteList();
+ /// For use by g_logic_module().
+ auto ClearSoundRefDeleteList() -> void;
auto paused() const -> bool { return paused_; }
// Client sources use these to pass settings to the server.
- void PushSourceSetIsMusicCall(uint32_t play_id, bool val);
- void PushSourceSetPositionalCall(uint32_t play_id, bool val);
- void PushSourceSetPositionCall(uint32_t play_id, const Vector3f& p);
- void PushSourceSetGainCall(uint32_t play_id, float val);
- void PushSourceSetFadeCall(uint32_t play_id, float val);
- void PushSourceSetLoopingCall(uint32_t play_id, bool val);
- void PushSourcePlayCall(uint32_t play_id, Object::Ref* sound);
- void PushSourceStopCall(uint32_t play_id);
- void PushSourceEndCall(uint32_t play_id);
+ auto PushSourceSetIsMusicCall(uint32_t play_id, bool val) -> void;
+ auto PushSourceSetPositionalCall(uint32_t play_id, bool val) -> void;
+ auto PushSourceSetPositionCall(uint32_t play_id, const Vector3f& p) -> void;
+ auto PushSourceSetGainCall(uint32_t play_id, float val) -> void;
+ auto PushSourceSetFadeCall(uint32_t play_id, float val) -> void;
+ auto PushSourceSetLoopingCall(uint32_t play_id, bool val) -> void;
+ auto PushSourcePlayCall(uint32_t play_id, Object::Ref* sound)
+ -> void;
+ auto PushSourceStopCall(uint32_t play_id) -> void;
+ auto PushSourceEndCall(uint32_t play_id) -> void;
// Fade a playing sound out over the given time. If it is already
// fading or does not exist, does nothing.
- void FadeSoundOut(uint32_t play_id, uint32_t time);
+ auto FadeSoundOut(uint32_t play_id, uint32_t time) -> void;
// Stop a sound from playing if it exists.
- void StopSound(uint32_t play_id);
+ auto StopSound(uint32_t play_id) -> void;
auto thread() const -> Thread* { return thread_; }
@@ -68,16 +70,17 @@ class AudioServer {
class ThreadSource;
struct Impl;
+ auto OnAppStartInThread() -> void;
~AudioServer();
auto OnThreadPause() -> void;
auto OnThreadResume() -> void;
- void SetPaused(bool paused);
+ auto SetPaused(bool paused) -> void;
- void SetMusicVolume(float volume);
- void SetSoundVolume(float volume);
- void SetSoundPitch(float pitch);
+ auto SetMusicVolume(float volume) -> void;
+ auto SetSoundVolume(float volume) -> void;
+ auto SetSoundPitch(float pitch) -> void;
auto music_volume() -> float { return music_volume_; }
auto sound_volume() -> float { return sound_volume_; }
auto sound_pitch() -> float { return sound_pitch_; }
@@ -85,22 +88,22 @@ class AudioServer {
/// If a sound play id is currently playing, return the sound.
auto GetPlayingSound(uint32_t play_id) -> ThreadSource*;
- void Reset();
- void Process();
+ auto Reset() -> void;
+ auto Process() -> void;
/// Send a component to the audio thread to delete.
- void DeleteMediaComponent(MediaComponentData* c);
+ auto DeleteAssetComponent(AssetComponentData* c) -> void;
- void UpdateTimerInterval();
- void UpdateAvailableSources();
- void UpdateMusicPlayState();
- void ProcessSoundFades();
+ auto UpdateTimerInterval() -> void;
+ auto UpdateAvailableSources() -> void;
+ auto UpdateMusicPlayState() -> void;
+ auto ProcessSoundFades() -> void;
// Some threads such as audio hold onto allocated Media-Component-Refs to keep
// media components alive that they need. Media-Component-Refs, however, must
- // be disposed of in the game thread, so they are passed back to it through
+ // be disposed of in the logic thread, so they are passed back to it through
// this function.
- void AddSoundRefDelete(const Object::Ref* c);
+ auto AddSoundRefDelete(const Object::Ref* c) -> void;
// 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.
diff --git a/src/ballistica/audio/audio_source.cc b/src/ballistica/audio/audio_source.cc
index 88c16257..4e391f34 100644
--- a/src/ballistica/audio/audio_source.cc
+++ b/src/ballistica/audio/audio_source.cc
@@ -2,10 +2,10 @@
#include "ballistica/audio/audio_source.h"
+#include "ballistica/assets/data/sound_data.h"
#include "ballistica/audio/audio.h"
#include "ballistica/audio/audio_server.h"
#include "ballistica/math/vector3f.h"
-#include "ballistica/media/data/sound_data.h"
namespace ballistica {
@@ -41,7 +41,7 @@ void AudioSource::SetPosition(float x, float y, float z) {
assert(client_queue_size_ > 0);
#if BA_DEBUG_BUILD
if (std::isnan(x) || std::isnan(y) || std::isnan(z)) {
- Log("Error: Got nan value in AudioSource::SetPosition.");
+ Log(LogLevel::kError, "Got nan value in AudioSource::SetPosition.");
}
#endif
g_audio_server->PushSourceSetPositionCall(play_id_, Vector3f(x, y, z));
diff --git a/src/ballistica/audio/audio_streamer.cc b/src/ballistica/audio/audio_streamer.cc
index d44a9982..9cdee4a1 100644
--- a/src/ballistica/audio/audio_streamer.cc
+++ b/src/ballistica/audio/audio_streamer.cc
@@ -86,8 +86,9 @@ void AudioStreamer::Update() {
// A fun anomaly in the linux version; we sometimes get more
// "processed" buffers than we have queued.
if (queued < processed) {
- Log("Error: streamer oddness: queued(" + std::to_string(queued)
- + "); processed(" + std::to_string(processed) + ")");
+ Log(LogLevel::kError, "Streamer oddness: queued(" + std::to_string(queued)
+ + "); processed(" + std::to_string(processed)
+ + ")");
processed = queued;
}
diff --git a/src/ballistica/audio/audio_streamer.h b/src/ballistica/audio/audio_streamer.h
index 82ce85f0..15eb8012 100644
--- a/src/ballistica/audio/audio_streamer.h
+++ b/src/ballistica/audio/audio_streamer.h
@@ -15,8 +15,8 @@ namespace ballistica {
// Provider for streamed audio data.
class AudioStreamer : public Object {
public:
- auto GetDefaultOwnerThread() const -> ThreadIdentifier override {
- return ThreadIdentifier::kAudio;
+ auto GetDefaultOwnerThread() const -> ThreadTag override {
+ return ThreadTag::kAudio;
}
AudioStreamer(const char* file_name, ALuint source, bool loop);
~AudioStreamer() override;
diff --git a/src/ballistica/audio/ogg_stream.cc b/src/ballistica/audio/ogg_stream.cc
index 93286491..68b40ef6 100644
--- a/src/ballistica/audio/ogg_stream.cc
+++ b/src/ballistica/audio/ogg_stream.cc
@@ -88,7 +88,8 @@ void OggStream::DoStream(char* pcm, int* size, unsigned int* rate) {
static bool reported_error = false;
if (!reported_error) {
reported_error = true;
- Log("Error streaming ogg file: '" + file_name() + "'.");
+ Log(LogLevel::kError,
+ "Error streaming ogg file: '" + file_name() + "'.");
}
if (loops()) {
ov_pcm_seek(&ogg_file_, 0);
diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc
index 9e8a4227..578bebac 100644
--- a/src/ballistica/ballistica.cc
+++ b/src/ballistica/ballistica.cc
@@ -4,73 +4,69 @@
#include