mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-29 02:23:22 +08:00
Merge branch 'master' into fairydust
This commit is contained in:
commit
7663b9aafe
119
.efrocachemap
119
.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"
|
||||
}
|
||||
10
.idea/dictionaries/ericf.xml
generated
10
.idea/dictionaries/ericf.xml
generated
@ -64,9 +64,11 @@
|
||||
<w>aiomain</w>
|
||||
<w>alarmsound</w>
|
||||
<w>alibaba</w>
|
||||
<w>allerrors</w>
|
||||
<w>allpaths</w>
|
||||
<w>allsettings</w>
|
||||
<w>allteams</w>
|
||||
<w>allwarnings</w>
|
||||
<w>aman</w>
|
||||
<w>amazonaws</w>
|
||||
<w>aname</w>
|
||||
@ -111,6 +113,7 @@
|
||||
<w>appspot</w>
|
||||
<w>appstate</w>
|
||||
<w>appstore</w>
|
||||
<w>apptime</w>
|
||||
<w>apputils</w>
|
||||
<w>archivepath</w>
|
||||
<w>archivepathbase</w>
|
||||
@ -234,6 +237,7 @@
|
||||
<w>benning</w>
|
||||
<w>bfiledir</w>
|
||||
<w>bfiles</w>
|
||||
<w>bgdynamics</w>
|
||||
<w>bgmodel</w>
|
||||
<w>bgrn</w>
|
||||
<w>bgterrain</w>
|
||||
@ -415,6 +419,7 @@
|
||||
<w>cleanlist</w>
|
||||
<w>cleanupcheck</w>
|
||||
<w>cleanupchecks</w>
|
||||
<w>clearsign</w>
|
||||
<w>clientid</w>
|
||||
<w>clientlist</w>
|
||||
<w>clienttobasn</w>
|
||||
@ -433,6 +438,7 @@
|
||||
<w>clrhdr</w>
|
||||
<w>clrnames</w>
|
||||
<w>clrred</w>
|
||||
<w>cmakelist</w>
|
||||
<w>cmakelists</w>
|
||||
<w>cmakeserver</w>
|
||||
<w>cmath</w>
|
||||
@ -1341,6 +1347,7 @@
|
||||
<w>levelgametype</w>
|
||||
<w>levelmodule</w>
|
||||
<w>levelname</w>
|
||||
<w>levelno</w>
|
||||
<w>lfull</w>
|
||||
<w>lfval</w>
|
||||
<w>libballisticacore</w>
|
||||
@ -1647,6 +1654,7 @@
|
||||
<w>nettest</w>
|
||||
<w>nettesting</w>
|
||||
<w>netutils</w>
|
||||
<w>networkwrite</w>
|
||||
<w>nevermind</w>
|
||||
<w>newactivity</w>
|
||||
<w>newdamage</w>
|
||||
@ -2380,6 +2388,7 @@
|
||||
<w>startscan</w>
|
||||
<w>startsplits</w>
|
||||
<w>starttime</w>
|
||||
<w>startupmsg</w>
|
||||
<w>statestr</w>
|
||||
<w>statictest</w>
|
||||
<w>statictestfiles</w>
|
||||
@ -2408,6 +2417,7 @@
|
||||
<w>stot</w>
|
||||
<w>strftime</w>
|
||||
<w>stringified</w>
|
||||
<w>stringifying</w>
|
||||
<w>stringprep</w>
|
||||
<w>stringptr</w>
|
||||
<w>strippable</w>
|
||||
|
||||
44
CHANGELOG.md
44
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)
|
||||
|
||||
4
Makefile
4
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
|
||||
|
||||
@ -1 +1 @@
|
||||
126683827977798484003262787310231621875
|
||||
137071025041513581787580065580079045765
|
||||
@ -1 +1 @@
|
||||
27855823406376609779797608591198912121
|
||||
139020022013133168311319486434408589898
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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', '<NULL_BYTE>'),
|
||||
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.
|
||||
|
||||
@ -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.')
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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'
|
||||
|
||||
10
ballisticacore-cmake/.idea/dictionaries/ericf.xml
generated
10
ballisticacore-cmake/.idea/dictionaries/ericf.xml
generated
@ -41,7 +41,9 @@
|
||||
<w>airborn</w>
|
||||
<w>alext</w>
|
||||
<w>alibaba</w>
|
||||
<w>allerrors</w>
|
||||
<w>allocs</w>
|
||||
<w>allwarnings</w>
|
||||
<w>alot</w>
|
||||
<w>alphaimg</w>
|
||||
<w>alphapixels</w>
|
||||
@ -67,6 +69,7 @@
|
||||
<w>appnameupper</w>
|
||||
<w>appspot</w>
|
||||
<w>appstate</w>
|
||||
<w>apptime</w>
|
||||
<w>argsjoined</w>
|
||||
<w>argstr</w>
|
||||
<w>armcap</w>
|
||||
@ -119,6 +122,7 @@
|
||||
<w>bdea</w>
|
||||
<w>benning</w>
|
||||
<w>bezanson</w>
|
||||
<w>bgdynamics</w>
|
||||
<w>bgra</w>
|
||||
<w>bigendian</w>
|
||||
<w>bilinear</w>
|
||||
@ -226,10 +230,12 @@
|
||||
<w>classdict</w>
|
||||
<w>classline</w>
|
||||
<w>cleanupcheck</w>
|
||||
<w>clearsign</w>
|
||||
<w>clientid</w>
|
||||
<w>clientinfo</w>
|
||||
<w>clienttobasn</w>
|
||||
<w>clipcount</w>
|
||||
<w>cmakelist</w>
|
||||
<w>cmath</w>
|
||||
<w>cmds</w>
|
||||
<w>cmdvals</w>
|
||||
@ -697,6 +703,7 @@
|
||||
<w>leaderboard</w>
|
||||
<w>leaderboards</w>
|
||||
<w>lenval</w>
|
||||
<w>levelno</w>
|
||||
<w>lgui</w>
|
||||
<w>lhalf</w>
|
||||
<w>libbz</w>
|
||||
@ -848,6 +855,7 @@
|
||||
<w>netcode</w>
|
||||
<w>netplay</w>
|
||||
<w>nettest</w>
|
||||
<w>networkwrite</w>
|
||||
<w>newactivity</w>
|
||||
<w>newchild</w>
|
||||
<w>newimg</w>
|
||||
@ -1239,6 +1247,7 @@
|
||||
<w>startpos</w>
|
||||
<w>startsplits</w>
|
||||
<w>starttime</w>
|
||||
<w>startupmsg</w>
|
||||
<w>startx</w>
|
||||
<w>starty</w>
|
||||
<w>statestr</w>
|
||||
@ -1258,6 +1267,7 @@
|
||||
<w>strdup</w>
|
||||
<w>stringi</w>
|
||||
<w>stringified</w>
|
||||
<w>stringifying</w>
|
||||
<w>strlen</w>
|
||||
<w>strs</w>
|
||||
<w>strtof</w>
|
||||
|
||||
@ -58,6 +58,7 @@
|
||||
<inspection_tool class="NotAssignable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="NotImplementedFunctions" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="NotSuperclass" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="NullDereference" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCDFA" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCLoopDoesntUseConditionVariable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCUnusedGlobalDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
|
||||
@ -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
|
||||
|
||||
@ -201,6 +201,40 @@
|
||||
<ClInclude Include="..\..\src\ballistica\app\app_flavor_vr.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\app\stress_test.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\app\stress_test.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets_server.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets_server.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\asset_component.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\asset_component.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\collide_model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\collide_model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\cube_map_texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\cube_map_texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\sound.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\sound.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\asset_component_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\asset_component_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\collide_model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\collide_model_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\data_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\data_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\sound_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\sound_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_preload_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_preload_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\audio\al_sys.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\audio\al_sys.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\audio\audio.cc" />
|
||||
@ -289,43 +323,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\part.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\dynamics\rigid_body.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\rigid_body.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\account.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\account.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\client_controller_interface.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_set.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client_udp.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host_udp.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\friend_score_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\game.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\game.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\game_stream.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\game_stream.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\host_activity.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\host_activity.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\player.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\player.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\player_spec.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\player_spec.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\score_to_beat.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\host_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\host_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\net_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\net_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\replay_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\replay_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\generic\base64.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\generic\base64.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\generic\buffer.h" />
|
||||
@ -444,9 +441,41 @@
|
||||
<ClInclude Include="..\..\src\ballistica\input\input.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\input\remote_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\input\remote_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\input\std_input_module.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\input\std_input_module.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\internal\app_internal.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\client_controller_interface.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_set.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\friend_score_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\host_activity.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\host_activity.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\logic.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\logic.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player_spec.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player_spec.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\host_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\host_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\net_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\net_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\replay_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\replay_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\v1_account.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\v1_account.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\math\matrix44f.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\matrix44f.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\point2d.h" />
|
||||
@ -457,44 +486,10 @@
|
||||
<ClCompile Include="..\..\src\ballistica\math\vector3f.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector3f.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector4f.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\collide_model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\collide_model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\cube_map_texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\cube_map_texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\media_component.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\media_component.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\sound.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\sound.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\collide_model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\collide_model_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\data_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\data_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\media_component_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\media_component_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\sound_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\sound_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_preload_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_preload_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\media.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\media.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\media_server.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\media_server.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_reader.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_reader.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_write_module.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_write_module.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_writer.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_writer.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\networking.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\networking.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\networking_sys.h" />
|
||||
@ -510,6 +505,8 @@
|
||||
<ClInclude Include="..\..\src\ballistica\platform\platform.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\sdl\sdl_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\sdl\sdl_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\stdio_console.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\stdio_console.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\windows\platform_windows.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\windows\platform_windows.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\class\python_class.cc" />
|
||||
@ -548,14 +545,14 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\class\python_class_widget.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_assets.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_assets.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_gameplay.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_gameplay.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_graphics.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_graphics.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_input.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_input.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_media.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_media.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_networking.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_networking.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_system.cc" />
|
||||
@ -629,6 +626,10 @@
|
||||
<ClInclude Include="..\..\src\ballistica\scene\node\time_display_node.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene_stream.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene_stream.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\v1\scene_v1.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\v1\scene_v1.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\ui\console.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\ui\console.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\ui\root_ui.cc" />
|
||||
|
||||
@ -37,6 +37,108 @@
|
||||
<ClInclude Include="..\..\src\ballistica\app\stress_test.h">
|
||||
<Filter>ballistica\app</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets.cc">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets.h">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets_server.cc">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets_server.h">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\asset_component.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\asset_component.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\collide_model.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\collide_model.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\cube_map_texture.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\cube_map_texture.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\data.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\data.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\model.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\model.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\sound.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\sound.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\texture.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\texture.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\asset_component_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\asset_component_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\collide_model_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\collide_model_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\data_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\data_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\model_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_renderer_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\sound_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\sound_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_preload_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_preload_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_renderer_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\audio\al_sys.cc">
|
||||
<Filter>ballistica\audio</Filter>
|
||||
</ClCompile>
|
||||
@ -301,117 +403,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\rigid_body.h">
|
||||
<Filter>ballistica\dynamics</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\account.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\account.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\client_controller_interface.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_set.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_set.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client_udp.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client_udp.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host_udp.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host_udp.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\friend_score_set.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\game.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\game.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\game_stream.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\game_stream.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\host_activity.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\host_activity.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\player.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\player.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\player_spec.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\player_spec.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\score_to_beat.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\host_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\host_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\net_client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\net_client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\replay_client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\replay_client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\generic\base64.cc">
|
||||
<Filter>ballistica\generic</Filter>
|
||||
</ClCompile>
|
||||
@ -766,15 +757,111 @@
|
||||
<ClInclude Include="..\..\src\ballistica\input\remote_app.h">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\input\std_input_module.cc">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\input\std_input_module.h">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\internal\app_internal.h">
|
||||
<Filter>ballistica\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\client_controller_interface.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_set.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_set.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\friend_score_set.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\host_activity.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\host_activity.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\logic.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\logic.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player_spec.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player_spec.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\host_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\host_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\net_client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\net_client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\replay_client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\replay_client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\v1_account.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\v1_account.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\math\matrix44f.cc">
|
||||
<Filter>ballistica\math</Filter>
|
||||
</ClCompile>
|
||||
@ -805,118 +892,16 @@
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector4f.h">
|
||||
<Filter>ballistica\math</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\collide_model.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\collide_model.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\cube_map_texture.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\cube_map_texture.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\data.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\data.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\media_component.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\media_component.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\model.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\model.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\sound.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\sound.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\texture.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\texture.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\collide_model_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\collide_model_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\data_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\data_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\media_component_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\media_component_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\model_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_renderer_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\sound_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\sound_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_preload_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_preload_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_renderer_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\media.cc">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\media.h">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\media_server.cc">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\media_server.h">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_reader.cc">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_reader.h">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_write_module.cc">
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_writer.cc">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_write_module.h">
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_writer.h">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\networking.cc">
|
||||
@ -964,6 +949,12 @@
|
||||
<ClInclude Include="..\..\src\ballistica\platform\sdl\sdl_app.h">
|
||||
<Filter>ballistica\platform\sdl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\platform\stdio_console.cc">
|
||||
<Filter>ballistica\platform</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\platform\stdio_console.h">
|
||||
<Filter>ballistica\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\platform\windows\platform_windows.cc">
|
||||
<Filter>ballistica\platform\windows</Filter>
|
||||
</ClCompile>
|
||||
@ -1078,6 +1069,12 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_app.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_assets.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_assets.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_gameplay.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
@ -1096,12 +1093,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_input.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_media.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_media.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_networking.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
@ -1321,6 +1312,18 @@
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene.h">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene_stream.cc">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene_stream.h">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\scene\v1\scene_v1.cc">
|
||||
<Filter>ballistica\scene\v1</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\scene\v1\scene_v1.h">
|
||||
<Filter>ballistica\scene\v1</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\ui\console.cc">
|
||||
<Filter>ballistica\ui</Filter>
|
||||
</ClCompile>
|
||||
@ -1646,15 +1649,15 @@
|
||||
<ItemGroup>
|
||||
<Filter Include="ballistica" />
|
||||
<Filter Include="ballistica\app" />
|
||||
<Filter Include="ballistica\assets" />
|
||||
<Filter Include="ballistica\assets\component" />
|
||||
<Filter Include="ballistica\assets\data" />
|
||||
<Filter Include="ballistica\audio" />
|
||||
<Filter Include="ballistica\config" />
|
||||
<Filter Include="ballistica\core" />
|
||||
<Filter Include="ballistica\dynamics" />
|
||||
<Filter Include="ballistica\dynamics\bg" />
|
||||
<Filter Include="ballistica\dynamics\material" />
|
||||
<Filter Include="ballistica\game" />
|
||||
<Filter Include="ballistica\game\connection" />
|
||||
<Filter Include="ballistica\game\session" />
|
||||
<Filter Include="ballistica\generic" />
|
||||
<Filter Include="ballistica\graphics" />
|
||||
<Filter Include="ballistica\graphics\component" />
|
||||
@ -1665,10 +1668,10 @@
|
||||
<Filter Include="ballistica\input" />
|
||||
<Filter Include="ballistica\input\device" />
|
||||
<Filter Include="ballistica\internal" />
|
||||
<Filter Include="ballistica\logic" />
|
||||
<Filter Include="ballistica\logic\connection" />
|
||||
<Filter Include="ballistica\logic\session" />
|
||||
<Filter Include="ballistica\math" />
|
||||
<Filter Include="ballistica\media" />
|
||||
<Filter Include="ballistica\media\component" />
|
||||
<Filter Include="ballistica\media\data" />
|
||||
<Filter Include="ballistica\networking" />
|
||||
<Filter Include="ballistica\platform" />
|
||||
<Filter Include="ballistica\platform\apple" />
|
||||
@ -1680,6 +1683,7 @@
|
||||
<Filter Include="ballistica\python\methods" />
|
||||
<Filter Include="ballistica\scene" />
|
||||
<Filter Include="ballistica\scene\node" />
|
||||
<Filter Include="ballistica\scene\v1" />
|
||||
<Filter Include="ballistica\ui" />
|
||||
<Filter Include="ballistica\ui\widget" />
|
||||
<Filter Include="external" />
|
||||
|
||||
@ -196,6 +196,40 @@
|
||||
<ClInclude Include="..\..\src\ballistica\app\app_flavor_vr.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\app\stress_test.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\app\stress_test.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets_server.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets_server.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\asset_component.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\asset_component.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\collide_model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\collide_model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\cube_map_texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\cube_map_texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\sound.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\sound.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\asset_component_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\asset_component_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\collide_model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\collide_model_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\data_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\data_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\sound_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\sound_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_preload_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_preload_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\audio\al_sys.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\audio\al_sys.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\audio\audio.cc" />
|
||||
@ -284,43 +318,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\part.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\dynamics\rigid_body.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\rigid_body.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\account.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\account.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\client_controller_interface.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_set.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client_udp.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host_udp.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\friend_score_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\game.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\game.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\game_stream.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\game_stream.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\host_activity.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\host_activity.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\player.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\player.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\player_spec.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\player_spec.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\score_to_beat.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\host_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\host_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\net_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\net_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\replay_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\replay_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\generic\base64.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\generic\base64.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\generic\buffer.h" />
|
||||
@ -439,9 +436,41 @@
|
||||
<ClInclude Include="..\..\src\ballistica\input\input.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\input\remote_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\input\remote_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\input\std_input_module.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\input\std_input_module.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\internal\app_internal.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\client_controller_interface.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_set.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\friend_score_set.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\host_activity.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\host_activity.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\logic.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\logic.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player_spec.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player_spec.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\host_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\host_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\net_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\net_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\replay_client_session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\replay_client_session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\session.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\session.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\logic\v1_account.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\logic\v1_account.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\math\matrix44f.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\matrix44f.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\point2d.h" />
|
||||
@ -452,44 +481,10 @@
|
||||
<ClCompile Include="..\..\src\ballistica\math\vector3f.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector3f.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector4f.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\collide_model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\collide_model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\cube_map_texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\cube_map_texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\media_component.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\media_component.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\model.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\model.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\sound.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\sound.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\texture.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\texture.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\collide_model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\collide_model_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\data_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\data_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\media_component_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\media_component_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\model_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\sound_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\sound_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_preload_data.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_preload_data.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_renderer_data.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\media.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\media.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\media\media_server.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\media\media_server.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_reader.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_reader.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_write_module.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_write_module.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_writer.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_writer.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\networking\networking.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\networking.h" />
|
||||
<ClInclude Include="..\..\src\ballistica\networking\networking_sys.h" />
|
||||
@ -505,6 +500,8 @@
|
||||
<ClInclude Include="..\..\src\ballistica\platform\platform.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\sdl\sdl_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\sdl\sdl_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\stdio_console.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\stdio_console.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\platform\windows\platform_windows.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\platform\windows\platform_windows.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\class\python_class.cc" />
|
||||
@ -543,14 +540,14 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\class\python_class_widget.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_app.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_app.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_assets.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_assets.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_gameplay.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_gameplay.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_graphics.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_graphics.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_input.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_input.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_media.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_media.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_networking.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_networking.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_system.cc" />
|
||||
@ -624,6 +621,10 @@
|
||||
<ClInclude Include="..\..\src\ballistica\scene\node\time_display_node.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene_stream.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene_stream.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\scene\v1\scene_v1.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\scene\v1\scene_v1.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\ui\console.cc" />
|
||||
<ClInclude Include="..\..\src\ballistica\ui\console.h" />
|
||||
<ClCompile Include="..\..\src\ballistica\ui\root_ui.cc" />
|
||||
|
||||
@ -37,6 +37,108 @@
|
||||
<ClInclude Include="..\..\src\ballistica\app\stress_test.h">
|
||||
<Filter>ballistica\app</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets.cc">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets.h">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\assets_server.cc">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\assets_server.h">
|
||||
<Filter>ballistica\assets</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\asset_component.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\asset_component.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\collide_model.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\collide_model.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\cube_map_texture.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\cube_map_texture.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\data.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\data.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\model.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\model.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\sound.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\sound.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\component\texture.cc">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\component\texture.h">
|
||||
<Filter>ballistica\assets\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\asset_component_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\asset_component_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\collide_model_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\collide_model_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\data_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\data_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\model_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\model_renderer_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\sound_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\sound_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\assets\data\texture_preload_data.cc">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_preload_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\assets\data\texture_renderer_data.h">
|
||||
<Filter>ballistica\assets\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\audio\al_sys.cc">
|
||||
<Filter>ballistica\audio</Filter>
|
||||
</ClCompile>
|
||||
@ -301,117 +403,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\dynamics\rigid_body.h">
|
||||
<Filter>ballistica\dynamics</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\account.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\account.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\client_controller_interface.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_set.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_set.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_client_udp.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_client_udp.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\connection\connection_to_host_udp.cc">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\connection\connection_to_host_udp.h">
|
||||
<Filter>ballistica\game\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\friend_score_set.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\game.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\game.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\game_stream.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\game_stream.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\host_activity.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\host_activity.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\player.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\player.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\player_spec.cc">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\player_spec.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\game\score_to_beat.h">
|
||||
<Filter>ballistica\game</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\host_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\host_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\net_client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\net_client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\replay_client_session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\replay_client_session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\game\session\session.cc">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\game\session\session.h">
|
||||
<Filter>ballistica\game\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\generic\base64.cc">
|
||||
<Filter>ballistica\generic</Filter>
|
||||
</ClCompile>
|
||||
@ -766,15 +757,111 @@
|
||||
<ClInclude Include="..\..\src\ballistica\input\remote_app.h">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\input\std_input_module.cc">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\input\std_input_module.h">
|
||||
<Filter>ballistica\input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\internal\app_internal.h">
|
||||
<Filter>ballistica\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\client_controller_interface.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_set.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_set.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_client_udp.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.cc">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\connection\connection_to_host_udp.h">
|
||||
<Filter>ballistica\logic\connection</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\friend_score_set.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\host_activity.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\host_activity.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\logic.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\logic.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\player_spec.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\player_spec.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\host_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\host_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\net_client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\net_client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\replay_client_session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\replay_client_session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\session\session.cc">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\session\session.h">
|
||||
<Filter>ballistica\logic\session</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\logic\v1_account.cc">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\logic\v1_account.h">
|
||||
<Filter>ballistica\logic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\math\matrix44f.cc">
|
||||
<Filter>ballistica\math</Filter>
|
||||
</ClCompile>
|
||||
@ -805,118 +892,16 @@
|
||||
<ClInclude Include="..\..\src\ballistica\math\vector4f.h">
|
||||
<Filter>ballistica\math</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\collide_model.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\collide_model.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\cube_map_texture.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\cube_map_texture.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\data.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\data.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\media_component.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\media_component.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\model.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\model.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\sound.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\sound.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\component\texture.cc">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\component\texture.h">
|
||||
<Filter>ballistica\media\component</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\collide_model_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\collide_model_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\data_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\data_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\media_component_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\media_component_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\model_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\model_renderer_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\sound_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\sound_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\data\texture_preload_data.cc">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_preload_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ballistica\media\data\texture_renderer_data.h">
|
||||
<Filter>ballistica\media\data</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\media.cc">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\media.h">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\media\media_server.cc">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\media\media_server.h">
|
||||
<Filter>ballistica\media</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_reader.cc">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_reader.h">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_write_module.cc">
|
||||
<ClCompile Include="..\..\src\ballistica\networking\network_writer.cc">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_write_module.h">
|
||||
<ClInclude Include="..\..\src\ballistica\networking\network_writer.h">
|
||||
<Filter>ballistica\networking</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\networking\networking.cc">
|
||||
@ -964,6 +949,12 @@
|
||||
<ClInclude Include="..\..\src\ballistica\platform\sdl\sdl_app.h">
|
||||
<Filter>ballistica\platform\sdl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\platform\stdio_console.cc">
|
||||
<Filter>ballistica\platform</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\platform\stdio_console.h">
|
||||
<Filter>ballistica\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\platform\windows\platform_windows.cc">
|
||||
<Filter>ballistica\platform\windows</Filter>
|
||||
</ClCompile>
|
||||
@ -1078,6 +1069,12 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_app.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_assets.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_assets.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_gameplay.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
@ -1096,12 +1093,6 @@
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_input.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_media.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\python\methods\python_methods_media.h">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\python\methods\python_methods_networking.cc">
|
||||
<Filter>ballistica\python\methods</Filter>
|
||||
</ClCompile>
|
||||
@ -1321,6 +1312,18 @@
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene.h">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\scene\scene_stream.cc">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\scene\scene_stream.h">
|
||||
<Filter>ballistica\scene</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\scene\v1\scene_v1.cc">
|
||||
<Filter>ballistica\scene\v1</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ballistica\scene\v1\scene_v1.h">
|
||||
<Filter>ballistica\scene\v1</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ballistica\ui\console.cc">
|
||||
<Filter>ballistica\ui</Filter>
|
||||
</ClCompile>
|
||||
@ -1646,15 +1649,15 @@
|
||||
<ItemGroup>
|
||||
<Filter Include="ballistica" />
|
||||
<Filter Include="ballistica\app" />
|
||||
<Filter Include="ballistica\assets" />
|
||||
<Filter Include="ballistica\assets\component" />
|
||||
<Filter Include="ballistica\assets\data" />
|
||||
<Filter Include="ballistica\audio" />
|
||||
<Filter Include="ballistica\config" />
|
||||
<Filter Include="ballistica\core" />
|
||||
<Filter Include="ballistica\dynamics" />
|
||||
<Filter Include="ballistica\dynamics\bg" />
|
||||
<Filter Include="ballistica\dynamics\material" />
|
||||
<Filter Include="ballistica\game" />
|
||||
<Filter Include="ballistica\game\connection" />
|
||||
<Filter Include="ballistica\game\session" />
|
||||
<Filter Include="ballistica\generic" />
|
||||
<Filter Include="ballistica\graphics" />
|
||||
<Filter Include="ballistica\graphics\component" />
|
||||
@ -1665,10 +1668,10 @@
|
||||
<Filter Include="ballistica\input" />
|
||||
<Filter Include="ballistica\input\device" />
|
||||
<Filter Include="ballistica\internal" />
|
||||
<Filter Include="ballistica\logic" />
|
||||
<Filter Include="ballistica\logic\connection" />
|
||||
<Filter Include="ballistica\logic\session" />
|
||||
<Filter Include="ballistica\math" />
|
||||
<Filter Include="ballistica\media" />
|
||||
<Filter Include="ballistica\media\component" />
|
||||
<Filter Include="ballistica\media\data" />
|
||||
<Filter Include="ballistica\networking" />
|
||||
<Filter Include="ballistica\platform" />
|
||||
<Filter Include="ballistica\platform\apple" />
|
||||
@ -1680,6 +1683,7 @@
|
||||
<Filter Include="ballistica\python\methods" />
|
||||
<Filter Include="ballistica\scene" />
|
||||
<Filter Include="ballistica\scene\node" />
|
||||
<Filter Include="ballistica\scene\v1" />
|
||||
<Filter Include="ballistica\ui" />
|
||||
<Filter Include="ballistica\ui\widget" />
|
||||
<Filter Include="external" />
|
||||
|
||||
@ -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<std::string, NodeType*> node_types;
|
||||
std::unordered_map<int, NodeType*> node_types_by_id;
|
||||
@ -41,10 +32,10 @@ class App {
|
||||
std::vector<Thread*> 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{};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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<StressTest>()) {
|
||||
// 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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<int>(GetRealTime()), avg, node_count,
|
||||
|
||||
@ -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 <sys/stat.h>
|
||||
#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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(preload_time),
|
||||
static_cast_check_fit<int>(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<int>(preload_time),
|
||||
static_cast_check_fit<int>(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<int>(preload_time),
|
||||
static_cast_check_fit<int>(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<int>(preload_time),
|
||||
static_cast_check_fit<int>(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<int>(preload_time),
|
||||
static_cast_check_fit<int>(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<int>(total_preload_time),
|
||||
static_cast<int>(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<int>(MediaType::kTexture)] = true;
|
||||
AssetComponentData::LockGuard lock(i.second.get());
|
||||
have_pending_loads_[static_cast<int>(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<int>(MediaType::kTexture)] = true;
|
||||
AssetComponentData::LockGuard lock(i.second.get());
|
||||
have_pending_loads_[static_cast<int>(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<int>(MediaType::kTexture)] = true;
|
||||
AssetComponentData::LockGuard lock(i.second.get());
|
||||
have_pending_loads_[static_cast<int>(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<int>(MediaType::kModel)] = true;
|
||||
AssetComponentData::LockGuard lock(i.second.get());
|
||||
have_pending_loads_[static_cast<int>(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<ModelData> {
|
||||
return GetComponentData(file_name, &models_);
|
||||
}
|
||||
|
||||
auto Media::GetSoundData(const std::string& file_name)
|
||||
auto Assets::GetSoundData(const std::string& file_name)
|
||||
-> Object::Ref<SoundData> {
|
||||
return GetComponentData(file_name, &sounds_);
|
||||
}
|
||||
|
||||
auto Media::GetDataData(const std::string& file_name) -> Object::Ref<DataData> {
|
||||
auto Assets::GetDataData(const std::string& file_name)
|
||||
-> Object::Ref<DataData> {
|
||||
return GetComponentData(file_name, &datas_);
|
||||
}
|
||||
|
||||
auto Media::GetCollideModelData(const std::string& file_name)
|
||||
auto Assets::GetCollideModelData(const std::string& file_name)
|
||||
-> Object::Ref<CollideModelData> {
|
||||
return GetComponentData(file_name, &collide_models_);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto Media::GetComponentData(
|
||||
auto Assets::GetComponentData(
|
||||
const std::string& file_name,
|
||||
std::unordered_map<std::string, Object::Ref<T> >* c_list)
|
||||
-> Object::Ref<T> {
|
||||
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<T>(i->second.get());
|
||||
@ -475,8 +468,8 @@ auto Media::GetComponentData(
|
||||
auto d(Object::New<T>(file_name));
|
||||
(*c_list)[file_name] = d;
|
||||
{
|
||||
MediaComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(d->GetMediaType())] = true;
|
||||
AssetComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(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<TextureData> {
|
||||
auto Assets::GetTextureData(TextPacker* packer) -> Object::Ref<TextureData> {
|
||||
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<TextureData> {
|
||||
auto d(Object::New<TextureData>(packer));
|
||||
text_textures_[hash] = d;
|
||||
{
|
||||
MediaComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(d->GetMediaType())] = true;
|
||||
AssetComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(d->GetAssetType())] = true;
|
||||
MarkComponentForLoad(d.get());
|
||||
}
|
||||
d->set_last_used_time(GetRealTime());
|
||||
@ -504,10 +497,10 @@ auto Media::GetTextureData(TextPacker* packer) -> Object::Ref<TextureData> {
|
||||
}
|
||||
}
|
||||
|
||||
auto Media::GetTextureDataQRCode(const std::string& url)
|
||||
auto Assets::GetTextureDataQRCode(const std::string& url)
|
||||
-> Object::Ref<TextureData> {
|
||||
assert(InLogicThread());
|
||||
assert(media_lists_locked_);
|
||||
assert(asset_lists_locked_);
|
||||
auto i = qr_textures_.find(url);
|
||||
if (i != qr_textures_.end()) {
|
||||
return Object::Ref<TextureData>(i->second.get());
|
||||
@ -515,8 +508,8 @@ auto Media::GetTextureDataQRCode(const std::string& url)
|
||||
auto d(Object::New<TextureData>(url));
|
||||
qr_textures_[url] = d;
|
||||
{
|
||||
MediaComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(d->GetMediaType())] = true;
|
||||
AssetComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(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<TextureData> {
|
||||
assert(InLogicThread());
|
||||
assert(media_lists_locked_);
|
||||
assert(asset_lists_locked_);
|
||||
auto i = textures_.find(file_name);
|
||||
if (i != textures_.end()) {
|
||||
return Object::Ref<TextureData>(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<int>(d->GetMediaType())] = true;
|
||||
AssetComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(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<TextureData> {
|
||||
assert(InLogicThread());
|
||||
assert(media_lists_locked_);
|
||||
assert(asset_lists_locked_);
|
||||
auto i = textures_.find(file_name);
|
||||
if (i != textures_.end()) {
|
||||
return Object::Ref<TextureData>(i->second.get());
|
||||
@ -594,8 +587,8 @@ auto Media::GetTextureData(const std::string& file_name)
|
||||
auto d(Object::New<TextureData>(file_name, TextureType::k2D, min_quality));
|
||||
textures_[file_name] = d;
|
||||
{
|
||||
MediaComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(d->GetMediaType())] = true;
|
||||
AssetComponentData::LockGuard lock(d.get());
|
||||
have_pending_loads_[static_cast<int>(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<MediaComponentData>(c);
|
||||
g_media_server->thread()->PushRunnable(
|
||||
Object::NewDeferred<PreloadRunnable>(media_ptr));
|
||||
auto asset_ref_ptr = new Object::Ref<AssetComponentData>(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<int>(MediaType::kModel)]) {
|
||||
auto Assets::GetModelPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(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<int>(MediaType::kModel)] = false;
|
||||
have_pending_loads_[static_cast<int>(AssetType::kModel)] = false;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
auto Media::GetTexturePendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(MediaType::kTexture)]) {
|
||||
auto Assets::GetTexturePendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(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<int>(MediaType::kTexture)] = false;
|
||||
have_pending_loads_[static_cast<int>(AssetType::kTexture)] = false;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
auto Media::GetSoundPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(MediaType::kSound)]) {
|
||||
auto Assets::GetSoundPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(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<int>(MediaType::kSound)] = false;
|
||||
have_pending_loads_[static_cast<int>(AssetType::kSound)] = false;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
auto Media::GetDataPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(MediaType::kData)]) {
|
||||
auto Assets::GetDataPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(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<int>(MediaType::kData)] = false;
|
||||
have_pending_loads_[static_cast<int>(AssetType::kData)] = false;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
auto Media::GetCollideModelPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(MediaType::kCollideModel)]) {
|
||||
auto Assets::GetCollideModelPendingLoadCount() -> int {
|
||||
if (!have_pending_loads_[static_cast<int>(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<int>(MediaType::kCollideModel)] = false;
|
||||
have_pending_loads_[static_cast<int>(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 <class T>
|
||||
auto Media::GetComponentPendingLoadCount(
|
||||
std::unordered_map<std::string, Object::Ref<T> >* t_list, MediaType type)
|
||||
auto Assets::GetComponentPendingLoadCount(
|
||||
std::unordered_map<std::string, Object::Ref<T> >* 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 <class T>
|
||||
auto Media::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
||||
auto Assets::RunPendingLoadList(std::vector<Object::Ref<T>*>* c_list) -> bool {
|
||||
bool flush = false;
|
||||
millisecs_t starttime = GetRealTime();
|
||||
|
||||
@ -818,40 +810,40 @@ auto Media::RunPendingLoadList(std::vector<Object::Ref<T>*>* 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<Object::Ref<MediaComponentData>*> graphics_thread_unloads;
|
||||
std::vector<Object::Ref<MediaComponentData>*> audio_thread_unloads;
|
||||
std::vector<Object::Ref<AssetComponentData>*> graphics_thread_unloads;
|
||||
std::vector<Object::Ref<AssetComponentData>*> 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<MediaComponentData>(texture_data));
|
||||
new Object::Ref<AssetComponentData>(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<MediaComponentData>(texture_data));
|
||||
new Object::Ref<AssetComponentData>(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<MediaComponentData>(texture_data));
|
||||
new Object::Ref<AssetComponentData>(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<MediaComponentData>(model_data));
|
||||
new Object::Ref<AssetComponentData>(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<MediaComponentData>(sound_data));
|
||||
new Object::Ref<AssetComponentData>(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<std::string>& media_paths_used = media_paths_;
|
||||
const std::vector<std::string>& 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<MediaComponentData>* c) {
|
||||
switch ((**c).GetMediaType()) {
|
||||
case MediaType::kTexture:
|
||||
case MediaType::kModel: {
|
||||
void Assets::AddPendingLoad(Object::Ref<AssetComponentData>* 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<MediaComponentData>* 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<MediaComponentData>* i : pending_loads_done_) {
|
||||
for (Object::Ref<AssetComponentData>* 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
|
||||
@ -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 <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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 <typename T>
|
||||
static auto GetMedia(
|
||||
static auto GetAsset(
|
||||
std::unordered_map<std::string, Object::WeakRef<T> >* list,
|
||||
const std::string& name, Scene* scene) -> Object::Ref<T> {
|
||||
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 <class T>
|
||||
auto RunPendingLoadList(std::vector<Object::Ref<T>*>* cList) -> bool;
|
||||
|
||||
/// This function takes a newly allocated pointer which
|
||||
/// is deleted once the load is completed.
|
||||
void AddPendingLoad(Object::Ref<MediaComponentData>* c);
|
||||
struct PreloadRunnable;
|
||||
auto AddPendingLoad(Object::Ref<AssetComponentData>* 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<TextureData>;
|
||||
auto GetTextureData(TextPacker* packer) -> Object::Ref<TextureData>;
|
||||
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<size_t>(id) < system_textures_.size());
|
||||
return system_textures_[static_cast<int>(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<size_t>(id) < system_cube_map_textures_.size());
|
||||
return system_cube_map_textures_[static_cast<int>(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<size_t>(id) < system_sounds_.size());
|
||||
return system_sounds_[static_cast<int>(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<size_t>(id) < system_models_.size());
|
||||
return system_models_[static_cast<int>(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<uint32_t>(models_.size());
|
||||
@ -150,24 +146,19 @@ class Media {
|
||||
auto total_collide_model_count() const -> uint32_t {
|
||||
return static_cast<uint32_t>(collide_models_.size());
|
||||
}
|
||||
struct PreloadRunnable : public Runnable {
|
||||
explicit PreloadRunnable(Object::Ref<MediaComponentData>* c_in) : c(c_in) {}
|
||||
void Run() override;
|
||||
Object::Ref<MediaComponentData>* 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 <class T>
|
||||
auto GetComponentPendingLoadCount(
|
||||
std::unordered_map<std::string, Object::Ref<T> >* t_list, MediaType type)
|
||||
std::unordered_map<std::string, Object::Ref<T> >* t_list, AssetType type)
|
||||
-> int;
|
||||
|
||||
template <class T>
|
||||
@ -176,26 +167,26 @@ class Media {
|
||||
std::unordered_map<std::string, Object::Ref<T> >* c_list)
|
||||
-> Object::Ref<T>;
|
||||
|
||||
std::vector<std::string> media_paths_;
|
||||
bool have_pending_loads_[static_cast<int>(MediaType::kLast)]{};
|
||||
std::vector<std::string> asset_paths_;
|
||||
bool have_pending_loads_[static_cast<int>(AssetType::kLast)]{};
|
||||
std::unordered_map<std::string, std::string> 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<Object::Ref<TextureData> > system_textures_;
|
||||
std::vector<Object::Ref<TextureData> > system_cube_map_textures_;
|
||||
std::vector<Object::Ref<SoundData> > system_sounds_;
|
||||
std::vector<Object::Ref<DataData> > system_datas_;
|
||||
std::vector<Object::Ref<ModelData> > system_models_;
|
||||
|
||||
// All existing media by filename (including internal).
|
||||
// All existing assets by filename (including internal).
|
||||
std::unordered_map<std::string, Object::Ref<TextureData> > textures_;
|
||||
std::unordered_map<std::string, Object::Ref<TextureData> > text_textures_;
|
||||
std::unordered_map<std::string, Object::Ref<TextureData> > 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<Object::Ref<MediaComponentData>*> pending_loads_graphics_;
|
||||
std::vector<Object::Ref<MediaComponentData>*> pending_loads_sounds_;
|
||||
std::vector<Object::Ref<MediaComponentData>*> pending_loads_datas_;
|
||||
std::vector<Object::Ref<MediaComponentData>*> pending_loads_other_;
|
||||
std::vector<Object::Ref<MediaComponentData>*> pending_loads_done_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_loads_graphics_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_loads_sounds_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_loads_datas_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_loads_other_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_loads_done_;
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
#endif // BALLISTICA_MEDIA_MEDIA_H_
|
||||
#endif // BALLISTICA_ASSETS_ASSETS_H_
|
||||
@ -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<AssetComponentData>* 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<uint8_t>& data) {
|
||||
void AssetsServer::PushAddMessageToReplayCall(
|
||||
const std::vector<uint8_t>& data) {
|
||||
thread()->PushCall([this, data] {
|
||||
if (replays_broken_) {
|
||||
return;
|
||||
@ -87,7 +110,8 @@ void MediaServer::PushAddMessageToReplayCall(const std::vector<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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<uint8_t> 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();
|
||||
}
|
||||
|
||||
42
src/ballistica/assets/assets_server.h
Normal file
42
src/ballistica/assets/assets_server.h
Normal file
@ -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 <list>
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t>& data) -> void;
|
||||
auto PushPendingPreload(Object::Ref<AssetComponentData>* 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<std::vector<uint8_t> > replay_messages_;
|
||||
size_t replay_message_bytes_{};
|
||||
Timer* process_timer_{};
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_preloads_;
|
||||
std::vector<Object::Ref<AssetComponentData>*> pending_preloads_audio_;
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
#endif // BALLISTICA_ASSETS_ASSETS_SERVER_H_
|
||||
@ -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 "<ballistica::" + GetMediaComponentTypeName() + " \"" + name() + "\">";
|
||||
auto AssetComponent::GetObjectDescription() const -> std::string {
|
||||
return "<ballistica::" + GetAssetComponentTypeName() + " \"" + name() + "\">";
|
||||
}
|
||||
|
||||
void MediaComponent::ClearPyObject() {
|
||||
void AssetComponent::ClearPyObject() {
|
||||
assert(py_object_ != nullptr);
|
||||
py_object_ = nullptr;
|
||||
}
|
||||
@ -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 <string>
|
||||
|
||||
@ -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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 <string>
|
||||
|
||||
#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_
|
||||
@ -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());
|
||||
}
|
||||
@ -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 <string>
|
||||
|
||||
#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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 <string>
|
||||
|
||||
#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_
|
||||
@ -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();
|
||||
}
|
||||
@ -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 <mutex>
|
||||
#include <string>
|
||||
@ -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_
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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()
|
||||
@ -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 <string>
|
||||
|
||||
#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_
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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_
|
||||
@ -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<char>* 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<char>* 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<char>* 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;
|
||||
}
|
||||
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 <string>
|
||||
#include <vector>
|
||||
|
||||
#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_
|
||||
@ -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 <cstring>
|
||||
#endif
|
||||
|
||||
#include "ballistica/assets/component/texture.h"
|
||||
#include "ballistica/graphics/texture/ktx.h"
|
||||
#include "ballistica/media/component/texture.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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)
|
||||
+ ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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<AudioSource*> client_sources_;
|
||||
|
||||
|
||||
@ -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<SoundData>* 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<uint32_t>(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<AudioSource> client_source_;
|
||||
float fade_ = 1.0f;
|
||||
float gain_ = 1.0f;
|
||||
AudioServer* audio_thread_;
|
||||
bool valid_ = false;
|
||||
const Object::Ref<SoundData>* 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<SoundData>* 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<AudioStreamer> 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<Object::Ref<MediaComponentData>*>& components) {
|
||||
const std::vector<Object::Ref<AssetComponentData>*>& 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<SoundData>* 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);
|
||||
|
||||
@ -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<Object::Ref<MediaComponentData>*>& 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<Object::Ref<AssetComponentData>*>& 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<SoundData>* 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<SoundData>* 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<SoundData>* c);
|
||||
auto AddSoundRefDelete(const Object::Ref<SoundData>* 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.
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -4,73 +4,69 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "ballistica/app/app_config.h"
|
||||
#include "ballistica/app/app_flavor.h"
|
||||
#include "ballistica/assets/assets.h"
|
||||
#include "ballistica/assets/assets_server.h"
|
||||
#include "ballistica/audio/audio.h"
|
||||
#include "ballistica/audio/audio_server.h"
|
||||
#include "ballistica/core/fatal_error.h"
|
||||
#include "ballistica/core/logging.h"
|
||||
#include "ballistica/core/thread.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_server.h"
|
||||
#include "ballistica/game/account.h"
|
||||
#include "ballistica/graphics/graphics_server.h"
|
||||
#include "ballistica/graphics/text/text_graphics.h"
|
||||
#include "ballistica/input/input.h"
|
||||
#include "ballistica/internal/app_internal.h"
|
||||
#include "ballistica/media/media_server.h"
|
||||
#include "ballistica/networking/network_write_module.h"
|
||||
#include "ballistica/logic/v1_account.h"
|
||||
#include "ballistica/networking/network_reader.h"
|
||||
#include "ballistica/networking/network_writer.h"
|
||||
#include "ballistica/networking/networking.h"
|
||||
#include "ballistica/platform/platform.h"
|
||||
#include "ballistica/platform/stdio_console.h"
|
||||
#include "ballistica/python/python.h"
|
||||
#include "ballistica/scene/scene.h"
|
||||
#include "ballistica/scene/v1/scene_v1.h"
|
||||
#include "ballistica/ui/ui.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kAppBuildNumber = 20798;
|
||||
const char* kAppVersion = "1.7.7";
|
||||
const int kAppBuildNumber = 20877;
|
||||
const char* kAppVersion = "1.7.9";
|
||||
|
||||
// Our standalone globals.
|
||||
// These are separated out for easy access.
|
||||
// Everything else should go into App (or more ideally into a class).
|
||||
int g_early_log_writes{10};
|
||||
int g_early_v1_cloud_log_writes{10};
|
||||
|
||||
Account* g_account{};
|
||||
AppConfig* g_app_config{};
|
||||
App* g_app{};
|
||||
AppConfig* g_app_config{};
|
||||
AppInternal* g_app_internal{};
|
||||
AppFlavor* g_app_flavor{};
|
||||
Assets* g_assets{};
|
||||
AssetsServer* g_assets_server{};
|
||||
Audio* g_audio{};
|
||||
AudioServer* g_audio_server{};
|
||||
BGDynamics* g_bg_dynamics{};
|
||||
BGDynamicsServer* g_bg_dynamics_server{};
|
||||
Game* g_game{};
|
||||
Context* g_context{};
|
||||
Graphics* g_graphics{};
|
||||
GraphicsServer* g_graphics_server{};
|
||||
Input* g_input{};
|
||||
Logic* g_logic{};
|
||||
Thread* g_main_thread{};
|
||||
Media* g_media{};
|
||||
MediaServer* g_media_server{};
|
||||
NetworkReader* g_network_reader{};
|
||||
Networking* g_networking{};
|
||||
NetworkWriteModule* g_network_write_module{};
|
||||
NetworkReader* g_network_reader{};
|
||||
NetworkWriter* g_network_writer{};
|
||||
Platform* g_platform{};
|
||||
Python* g_python{};
|
||||
StdInputModule* g_std_input_module{};
|
||||
SceneV1* g_scene_v1{};
|
||||
StdioConsole* g_stdio_console{};
|
||||
TextGraphics* g_text_graphics{};
|
||||
UI* g_ui{};
|
||||
Utils* g_utils{};
|
||||
|
||||
// Basic overview of our bootstrapping process:
|
||||
// 1: All threads and globals are created and provisioned. Everything above
|
||||
// should exist at the end of this step (if it is going to exist).
|
||||
// Threads should not be talking to each other yet at this point.
|
||||
// 2: The system is set in motion. Game thread is told to load/apply the config.
|
||||
// This event kicks off an initial-screen-creation message sent to the
|
||||
// graphics-server thread. Other systems are informed that bootstrapping
|
||||
// is complete and that they are free to talk to each other. Initial
|
||||
// input-devices are added, media loads can begin (at least ones not
|
||||
// dependent on the screen/renderer), etc.
|
||||
// 3: The initial screen is created on the graphics-server thread in response
|
||||
// to the message sent from the game thread. A completion notice is sent
|
||||
// back to the game thread when done.
|
||||
// 4: Back on the game thread, any renderer-dependent media-loads/etc. can begin
|
||||
// and lastly the initial game session is kicked off.
|
||||
V1Account* g_v1_account{};
|
||||
|
||||
auto BallisticaMain(int argc, char** argv) -> int {
|
||||
try {
|
||||
@ -83,77 +79,107 @@ auto BallisticaMain(int argc, char** argv) -> int {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 1: Create and provision all globals.
|
||||
// Phase 1: "The board is set."
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// Absolute bare-bones basics.
|
||||
g_app = new App(argc, argv);
|
||||
// Here we instantiate all of our globals. Code here should
|
||||
// avoid any logic that accesses other globals since they may
|
||||
// not yet exist.
|
||||
|
||||
// Minimal globals we must assign immediately as they ARE needed
|
||||
// for construction of the others (would be great to eliminate this need).
|
||||
g_platform = Platform::Create();
|
||||
g_app = new App(argc, argv);
|
||||
g_app_internal = CreateAppInternal();
|
||||
g_main_thread = new Thread(ThreadTag::kMain, ThreadSource::kWrapMain);
|
||||
|
||||
// If we're not running under a Python executable, we need to set up
|
||||
// our own Python environment.
|
||||
assert(g_python == nullptr);
|
||||
g_python = new Python();
|
||||
// For everything else, we hold off until the end to actually assign
|
||||
// them to their globals. This keeps us honest and catches any stray
|
||||
// inter-global access that we might accidentally include in a
|
||||
// constructor.
|
||||
auto* app_flavor = g_platform->CreateAppFlavor();
|
||||
auto* python = Python::Create();
|
||||
auto* graphics = g_platform->CreateGraphics();
|
||||
auto* graphics_server = new GraphicsServer();
|
||||
auto* audio = new Audio();
|
||||
auto* audio_server = new AudioServer();
|
||||
auto* context = new Context(nullptr);
|
||||
auto* text_graphics = new TextGraphics();
|
||||
auto* app_config = new AppConfig();
|
||||
auto* v1_account = new V1Account();
|
||||
auto* utils = new Utils();
|
||||
auto* assets = new Assets();
|
||||
auto* assets_server = new AssetsServer();
|
||||
auto* ui = Object::NewUnmanaged<UI>();
|
||||
auto* networking = new Networking();
|
||||
auto* network_reader = new NetworkReader();
|
||||
auto* network_writer = new NetworkWriter();
|
||||
auto* input = new Input();
|
||||
auto* logic = new Logic();
|
||||
auto* scene_v1 = new SceneV1();
|
||||
auto* bg_dynamics = HeadlessMode() ? nullptr : new BGDynamics;
|
||||
auto* bg_dynamics_server = HeadlessMode() ? nullptr : new BGDynamicsServer;
|
||||
auto* stdio_console =
|
||||
g_buildconfig.enable_stdio_console() ? new StdioConsole() : nullptr;
|
||||
|
||||
// Create a Thread wrapper around the current (main) thread.
|
||||
g_main_thread = new Thread(ThreadIdentifier::kMain, ThreadType::kMain);
|
||||
Thread::UpdateMainThreadID();
|
||||
g_app_flavor = app_flavor;
|
||||
g_python = python;
|
||||
g_graphics = graphics;
|
||||
g_graphics_server = graphics_server;
|
||||
g_audio = audio;
|
||||
g_audio_server = audio_server;
|
||||
g_context = context;
|
||||
g_text_graphics = text_graphics;
|
||||
g_app_config = app_config;
|
||||
g_v1_account = v1_account;
|
||||
g_utils = utils;
|
||||
g_assets = assets;
|
||||
g_assets_server = assets_server;
|
||||
g_ui = ui;
|
||||
g_networking = networking;
|
||||
g_network_reader = network_reader;
|
||||
g_network_writer = network_writer;
|
||||
g_input = input;
|
||||
g_logic = logic;
|
||||
g_scene_v1 = scene_v1;
|
||||
g_bg_dynamics = bg_dynamics;
|
||||
g_bg_dynamics_server = bg_dynamics_server;
|
||||
g_stdio_console = stdio_console;
|
||||
|
||||
// Spin up our specific app variation (VR, headless, regular, etc.)
|
||||
g_app_flavor = g_platform->CreateAppFlavor();
|
||||
g_app_flavor->PostInit();
|
||||
|
||||
g_account = new Account();
|
||||
g_utils = new Utils();
|
||||
Scene::Init();
|
||||
|
||||
// Spin up our other standard threads.
|
||||
auto* media_thread{new Thread(ThreadIdentifier::kMedia)};
|
||||
g_app->pausable_threads.push_back(media_thread);
|
||||
auto* audio_thread{new Thread(ThreadIdentifier::kAudio)};
|
||||
g_app->pausable_threads.push_back(audio_thread);
|
||||
auto* logic_thread{new Thread(ThreadIdentifier::kLogic)};
|
||||
g_app->pausable_threads.push_back(logic_thread);
|
||||
auto* network_write_thread{new Thread(ThreadIdentifier::kNetworkWrite)};
|
||||
g_app->pausable_threads.push_back(network_write_thread);
|
||||
|
||||
// Spin up our subsystems in those threads.
|
||||
logic_thread->PushCallSynchronous(
|
||||
[logic_thread] { new Game(logic_thread); });
|
||||
network_write_thread->PushCallSynchronous([network_write_thread] {
|
||||
new NetworkWriteModule(network_write_thread);
|
||||
});
|
||||
media_thread->PushCallSynchronous(
|
||||
[media_thread] { new MediaServer(media_thread); });
|
||||
new GraphicsServer(g_main_thread);
|
||||
audio_thread->PushCallSynchronous(
|
||||
[audio_thread] { new AudioServer(audio_thread); });
|
||||
|
||||
// Now let the platform spin up any other threads/modules it uses.
|
||||
// (bg-dynamics in non-headless builds, stdin/stdout where applicable,
|
||||
// etc.)
|
||||
g_platform->CreateAuxiliaryModules();
|
||||
|
||||
// Ok at this point we can be considered up-and-running.
|
||||
g_app->is_bootstrapped = true;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 2: Set things in motion.
|
||||
// Phase 2: "The pieces are moving."
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// Let the app and platform do whatever else it wants here such as adding
|
||||
// initial input devices/etc.
|
||||
g_app_flavor->OnBootstrapComplete();
|
||||
g_platform->OnBootstrapComplete();
|
||||
// Allow our subsystems to start doing work in their own threads
|
||||
// and communicating with other subsystems. Note that we may still
|
||||
// want to run some things serially here and ordering may be important
|
||||
// (for instance we want to give our main thread a chance to register
|
||||
// all initial input devices with the logic thread before the logic
|
||||
// thread applies the current config to them).
|
||||
|
||||
// Ok; now that we're bootstrapped, tell the game thread to read and apply
|
||||
// the config which should kick off the real action.
|
||||
g_game->PushApplyConfigCall();
|
||||
g_logic->OnAppStart();
|
||||
g_audio_server->OnAppStart();
|
||||
g_assets_server->OnAppStart();
|
||||
g_platform->OnAppStart();
|
||||
g_app_flavor->OnAppStart();
|
||||
if (g_stdio_console) {
|
||||
g_stdio_console->OnAppStart();
|
||||
}
|
||||
|
||||
// As the last step of this phase, tell the logic thread to apply
|
||||
// the app config which will kick off screen creation and otherwise
|
||||
// get the ball rolling.
|
||||
g_logic->PushApplyConfigCall();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 3/4: Create a screen and/or kick off game (in other threads).
|
||||
// Phase 3: "We come to it at last; the great battle of our time."
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// At this point all threads are off and running and we simply
|
||||
// feed events until things end (or return and let the OS do that).
|
||||
|
||||
if (g_app_flavor->ManagesEventLoop()) {
|
||||
// On our event-loop-managing platforms we now simply sit in our event
|
||||
// loop until the app is quit.
|
||||
@ -223,77 +249,87 @@ auto FatalError(const std::string& message) -> void {
|
||||
FatalError::ReportFatalError(message, false);
|
||||
bool exit_cleanly = !IsUnmodifiedBlessedBuild();
|
||||
bool handled = FatalError::HandleFatalError(exit_cleanly, false);
|
||||
assert(handled);
|
||||
BA_PRECONDITION(handled);
|
||||
}
|
||||
|
||||
// FIXME: move this to g_app or whatnot.
|
||||
auto GetAppInstanceUUID() -> const std::string& {
|
||||
static std::string session_id;
|
||||
static bool have_session_id = false;
|
||||
static std::string app_instance_uuid;
|
||||
static bool have_app_instance_uuid = false;
|
||||
|
||||
if (!have_session_id) {
|
||||
if (!have_app_instance_uuid) {
|
||||
if (g_python) {
|
||||
Python::ScopedInterpreterLock gil;
|
||||
auto uuid = g_python->obj(Python::ObjID::kUUIDStrCall).Call();
|
||||
if (uuid.exists()) {
|
||||
session_id = uuid.ValueAsString().c_str();
|
||||
have_session_id = true;
|
||||
app_instance_uuid = uuid.ValueAsString().c_str();
|
||||
have_app_instance_uuid = true;
|
||||
}
|
||||
}
|
||||
if (!have_session_id) {
|
||||
if (!have_app_instance_uuid) {
|
||||
// As an emergency fallback simply use a single random number.
|
||||
Log("WARNING: GetSessionUUID() using rand fallback.");
|
||||
// We should probably simply disallow this before Python is up.
|
||||
Log(LogLevel::kWarning, "GetSessionUUID() using rand fallback.");
|
||||
srand(static_cast<unsigned int>(
|
||||
Platform::GetCurrentMilliseconds())); // NOLINT
|
||||
session_id = std::to_string(static_cast<uint32_t>(rand())); // NOLINT
|
||||
have_session_id = true;
|
||||
Platform::GetCurrentMilliseconds())); // NOLINT
|
||||
app_instance_uuid =
|
||||
std::to_string(static_cast<uint32_t>(rand())); // NOLINT
|
||||
have_app_instance_uuid = true;
|
||||
}
|
||||
if (session_id.size() >= 100) {
|
||||
Log("WARNING: session id longer than it should be.");
|
||||
if (app_instance_uuid.size() >= 100) {
|
||||
Log(LogLevel::kWarning, "session id longer than it should be.");
|
||||
}
|
||||
}
|
||||
return session_id;
|
||||
}
|
||||
|
||||
auto InLogicThread() -> bool {
|
||||
return (g_game && g_game->thread()->IsCurrent());
|
||||
return app_instance_uuid;
|
||||
}
|
||||
|
||||
auto InMainThread() -> bool {
|
||||
return (g_app && std::this_thread::get_id() == g_app->main_thread_id);
|
||||
assert(g_main_thread); // Root out early use of this.
|
||||
return (g_main_thread->IsCurrent());
|
||||
}
|
||||
|
||||
auto InLogicThread() -> bool {
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_logic && g_logic->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto InGraphicsThread() -> bool {
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_graphics_server && g_graphics_server->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto InAudioThread() -> bool {
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_audio_server && g_audio_server->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto InBGDynamicsThread() -> bool {
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_bg_dynamics_server && g_bg_dynamics_server->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto InMediaThread() -> bool {
|
||||
return (g_media_server && g_media_server->thread()->IsCurrent());
|
||||
auto InAssetsThread() -> bool {
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_assets_server && g_assets_server->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto InNetworkWriteThread() -> bool {
|
||||
return (g_network_write_module
|
||||
&& g_network_write_module->thread()->IsCurrent());
|
||||
assert(g_app && g_app->is_bootstrapped); // Root out early use of this.
|
||||
return (g_network_writer && g_network_writer->thread()->IsCurrent());
|
||||
}
|
||||
|
||||
auto Log(const std::string& msg, bool to_stdout, bool to_server) -> void {
|
||||
Logging::Log(msg, to_stdout, to_server);
|
||||
auto Log(LogLevel level, const std::string& msg) -> void {
|
||||
Logging::Log(level, msg);
|
||||
}
|
||||
|
||||
auto IsVRMode() -> bool { return g_app->vr_mode; }
|
||||
|
||||
void ScreenMessage(const std::string& s, const Vector3f& color) {
|
||||
if (g_game) {
|
||||
g_game->PushScreenMessage(s, color);
|
||||
if (g_logic) {
|
||||
g_logic->PushScreenMessage(s, color);
|
||||
} else {
|
||||
Log("ScreenMessage before g_game init (will be lost): '" + s + "'");
|
||||
Log(LogLevel::kError,
|
||||
"ScreenMessage before g_logic init (will be lost): '" + s + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,28 +5,14 @@
|
||||
|
||||
// Try to ensure they're providing proper config stuff.
|
||||
#ifndef BA_HAVE_CONFIG
|
||||
#error platform config has not been defined!
|
||||
#error ballistica platform config has not been defined!
|
||||
#endif
|
||||
|
||||
// FIXME: We need to update to C++17 to get unified std::abs().
|
||||
// Until we do that, int types are defined in <cstdlib>
|
||||
// and float/double in <cmath>, meaning its possible to call the wrong
|
||||
// version if we aren't careful and only include one header.
|
||||
// For now just including both here at the top level to hopefully
|
||||
// minimize problems.
|
||||
// UPDATE: We should now be building with C++17 everywhere; should add a
|
||||
// check to ensure that is the case and can simplify this.
|
||||
#ifdef __cplusplus
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
// Minimum functionality we want available everywhere we are included.
|
||||
#include "ballistica/core/exception.h"
|
||||
#include "ballistica/core/inline.h"
|
||||
#include "ballistica/core/macros.h"
|
||||
@ -116,8 +102,8 @@ const float kGameStepSeconds =
|
||||
(static_cast<float>(kGameStepMilliseconds) / 1000.0f);
|
||||
|
||||
// Globals.
|
||||
extern int g_early_log_writes;
|
||||
extern Account* g_account;
|
||||
extern int g_early_v1_cloud_log_writes;
|
||||
extern V1Account* g_v1_account;
|
||||
extern AppFlavor* g_app_flavor;
|
||||
extern AppConfig* g_app_config;
|
||||
extern App* g_app;
|
||||
@ -127,19 +113,20 @@ extern AudioServer* g_audio_server;
|
||||
extern BGDynamics* g_bg_dynamics;
|
||||
extern BGDynamicsServer* g_bg_dynamics_server;
|
||||
extern Context* g_context;
|
||||
extern Game* g_game;
|
||||
extern Graphics* g_graphics;
|
||||
extern GraphicsServer* g_graphics_server;
|
||||
extern Input* g_input;
|
||||
extern Logic* g_logic;
|
||||
extern Thread* g_main_thread;
|
||||
extern Media* g_media;
|
||||
extern MediaServer* g_media_server;
|
||||
extern Assets* g_assets;
|
||||
extern AssetsServer* g_assets_server;
|
||||
extern Networking* g_networking;
|
||||
extern NetworkReader* g_network_reader;
|
||||
extern NetworkWriteModule* g_network_write_module;
|
||||
extern NetworkWriter* g_network_writer;
|
||||
extern Platform* g_platform;
|
||||
extern Python* g_python;
|
||||
extern StdInputModule* g_std_input_module;
|
||||
extern SceneV1* g_scene_v1;
|
||||
extern StdioConsole* g_stdio_console;
|
||||
extern TextGraphics* g_text_graphics;
|
||||
extern UI* g_ui;
|
||||
extern Utils* g_utils;
|
||||
@ -172,17 +159,20 @@ auto InGraphicsThread() -> bool; // (main and graphics are same currently)
|
||||
auto InLogicThread() -> bool;
|
||||
auto InAudioThread() -> bool;
|
||||
auto InBGDynamicsThread() -> bool;
|
||||
auto InMediaThread() -> bool;
|
||||
auto InAssetsThread() -> bool;
|
||||
auto InNetworkWriteThread() -> bool;
|
||||
|
||||
/// Return a human-readable name for the current thread.
|
||||
auto GetCurrentThreadName() -> std::string;
|
||||
|
||||
/// Write a string to the log.
|
||||
/// This will go to stdout, windows debug log, android log, etc.
|
||||
/// A trailing newline will be added.
|
||||
auto Log(const std::string& msg, bool to_stdout = true, bool to_server = true)
|
||||
-> void;
|
||||
/// Submit a log entry.
|
||||
/// Can be called from any thread at any time.
|
||||
/// Use either this or Python printing functionality for anything
|
||||
/// that should be seen by the user, as both of those will end up
|
||||
/// in the in-app console, cloud based consoles, android log, etc.
|
||||
/// Regular C level prints to stdout/stderr will not and will only
|
||||
/// be visible on some platforms.
|
||||
auto Log(LogLevel level, const std::string& msg) -> void;
|
||||
|
||||
/// Log a fatal error and kill the app.
|
||||
/// Can be called from any thread at any time.
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
#define BA_ENABLE_EXECINFO_BACKTRACES 1
|
||||
|
||||
// Allow stdin commands too.
|
||||
#define BA_USE_STDIN_THREAD 1
|
||||
#define BA_ENABLE_STDIO_CONSOLE 1
|
||||
|
||||
#define BA_DEFINE_MAIN 1
|
||||
|
||||
|
||||
@ -122,8 +122,8 @@ namespace ballistica {
|
||||
#error platform string undefined
|
||||
#endif
|
||||
|
||||
#ifndef BA_USE_STDIN_THREAD
|
||||
#define BA_USE_STDIN_THREAD 0
|
||||
#ifndef BA_ENABLE_STDIO_CONSOLE
|
||||
#define BA_ENABLE_STDIO_CONSOLE 0
|
||||
#endif
|
||||
|
||||
#ifndef BA_HARDWARE_CURSOR
|
||||
@ -240,7 +240,9 @@ class BuildConfig {
|
||||
|
||||
bool use_store_kit() const { return EXPBOOL_(BA_USE_STORE_KIT); }
|
||||
bool use_game_center() const { return EXPBOOL_(BA_USE_GAME_CENTER); }
|
||||
bool use_stdin_thread() const { return EXPBOOL_(BA_USE_STDIN_THREAD); }
|
||||
bool enable_stdio_console() const {
|
||||
return EXPBOOL_(BA_ENABLE_STDIO_CONSOLE);
|
||||
}
|
||||
bool enable_os_font_rendering() const {
|
||||
return EXPBOOL_(BA_ENABLE_OS_FONT_RENDERING);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
// note: define overrides BEFORE common makefile
|
||||
|
||||
#define BA_USE_STDIN_THREAD 1
|
||||
#define BA_ENABLE_STDIO_CONSOLE 1
|
||||
|
||||
#define BA_SDL_BUILD 1
|
||||
#define BA_SDL2_BUILD 1
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// note: define overrides BEFORE common header
|
||||
#define BA_HEADLESS_BUILD 1
|
||||
|
||||
#define BA_USE_STDIN_THREAD 1
|
||||
#define BA_ENABLE_STDIO_CONSOLE 1
|
||||
|
||||
#define BA_MINSDL_BUILD 1
|
||||
|
||||
|
||||
@ -2,20 +2,12 @@
|
||||
|
||||
#include "ballistica/core/context.h"
|
||||
|
||||
#include "ballistica/game/host_activity.h"
|
||||
#include "ballistica/generic/runnable.h"
|
||||
#include "ballistica/logic/host_activity.h"
|
||||
#include "ballistica/ui/ui.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
// Dynamically allocate this; don't want it torn down on quit.
|
||||
Context* g_context = nullptr;
|
||||
|
||||
void Context::Init() {
|
||||
assert(!g_context);
|
||||
g_context = new Context(nullptr);
|
||||
}
|
||||
|
||||
ContextTarget::ContextTarget() = default;
|
||||
ContextTarget::~ContextTarget() = default;
|
||||
|
||||
@ -108,7 +100,7 @@ auto ContextTarget::NewTimer(TimeType timetype, TimerMedium length, bool repeat,
|
||||
void ContextTarget::DeleteTimer(TimeType timetype, int timer_id) {
|
||||
// We throw on NewTimer; lets just ignore anything that comes
|
||||
// through here to avoid messing up destructors.
|
||||
Log("ContextTarget::DeleteTimer() called; unexpected.");
|
||||
Log(LogLevel::kError, "ContextTarget::DeleteTimer() called; unexpected.");
|
||||
}
|
||||
|
||||
auto ContextTarget::GetTime(TimeType timetype) -> millisecs_t {
|
||||
|
||||
@ -14,18 +14,16 @@ namespace ballistica {
|
||||
// effects properly apply to the place they came from.
|
||||
class Context {
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
static auto current() -> const Context& {
|
||||
assert(g_context);
|
||||
|
||||
// Context can only be accessed from the game thread.
|
||||
// Context can only be accessed from the logic thread.
|
||||
BA_PRECONDITION(InLogicThread());
|
||||
|
||||
return *g_context;
|
||||
}
|
||||
static void set_current(const Context& context) {
|
||||
// Context can only be accessed from the game thread.
|
||||
// Context can only be accessed from the logic thread.
|
||||
BA_PRECONDITION(InLogicThread());
|
||||
|
||||
*g_context = context;
|
||||
|
||||
@ -27,7 +27,7 @@ auto FatalError::ReportFatalError(const std::string& message,
|
||||
// error to the user and exiting the app cleanly (so we don't pollute our
|
||||
// crash records with results of user tinkering).
|
||||
|
||||
// Give the platform the opportunity to completely override our handling.
|
||||
// Give the platform the opportunity to augment or override our handling.
|
||||
if (g_platform) {
|
||||
auto handled =
|
||||
g_platform->ReportFatalError(message, in_top_level_exception_handler);
|
||||
@ -38,7 +38,8 @@ auto FatalError::ReportFatalError(const std::string& message,
|
||||
|
||||
std::string dialog_msg = message;
|
||||
if (!dialog_msg.empty()) {
|
||||
dialog_msg += "\n";
|
||||
// Why was this here?
|
||||
// dialog_msg += "\n";
|
||||
}
|
||||
|
||||
auto starttime = time(nullptr);
|
||||
@ -69,11 +70,16 @@ auto FatalError::ReportFatalError(const std::string& message,
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent the early-log insta-send mechanism from firing since we do
|
||||
// basically the same thing ourself here (avoid sending the same logs twice).
|
||||
g_early_log_writes = 0;
|
||||
// Prevent the early-v1-cloud-log insta-send mechanism from firing since
|
||||
// we do basically the same thing ourself here (avoid sending the same
|
||||
// logs twice).
|
||||
g_early_v1_cloud_log_writes = 0;
|
||||
|
||||
Logging::Log(logmsg);
|
||||
// Add this to our V1CloudLog which we'll be attempting to send momentarily,
|
||||
// and also go to platform-specific logging and good ol' stderr.
|
||||
Logging::V1CloudLog(logmsg);
|
||||
Logging::DisplayLog("root", LogLevel::kCritical, logmsg);
|
||||
fprintf(stderr, "%s\n", logmsg.c_str());
|
||||
|
||||
std::string prefix = "FATAL-ERROR-LOG:";
|
||||
std::string suffix;
|
||||
@ -83,7 +89,7 @@ auto FatalError::ReportFatalError(const std::string& message,
|
||||
if (g_app == nullptr) {
|
||||
suffix = logmsg;
|
||||
}
|
||||
g_app_internal->DirectSendLogs(prefix, suffix, true, &result);
|
||||
g_app_internal->DirectSendV1CloudLogs(prefix, suffix, true, &result);
|
||||
|
||||
// If we're able to show a fatal-error dialog synchronously, do so.
|
||||
if (g_platform && g_platform->CanShowBlockingFatalErrorDialog()) {
|
||||
@ -148,10 +154,10 @@ auto FatalError::HandleFatalError(bool exit_cleanly,
|
||||
// bring the app down ourself.
|
||||
if (!in_top_level_exception_handler) {
|
||||
if (exit_cleanly) {
|
||||
Log("Calling exit(1)...");
|
||||
Logging::DisplayLog("root", LogLevel::kCritical, "Calling exit(1)...");
|
||||
exit(1);
|
||||
} else {
|
||||
Log("Calling abort()...");
|
||||
Logging::DisplayLog("root", LogLevel::kCritical, "Calling abort()...");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,106 +5,103 @@
|
||||
#include <map>
|
||||
|
||||
#include "ballistica/app/app.h"
|
||||
#include "ballistica/game/game.h"
|
||||
#include "ballistica/internal/app_internal.h"
|
||||
#include "ballistica/logic/logic.h"
|
||||
#include "ballistica/networking/telnet_server.h"
|
||||
#include "ballistica/platform/platform.h"
|
||||
#include "ballistica/python/python.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
static void PrintCommon(const std::string& s) {
|
||||
auto Logging::Log(LogLevel level, const std::string& msg) -> void {
|
||||
// This is basically up to Python to handle, but its up to us
|
||||
// if Python's not up yet.
|
||||
if (!g_python) {
|
||||
// Make an attempt to get it at least seen (and note the fact
|
||||
// that its super-early).
|
||||
const char* errmsg{"Logging::Log() called before g_python exists."};
|
||||
if (g_platform) {
|
||||
g_platform->DisplayLog("root", LogLevel::kError, errmsg);
|
||||
g_platform->DisplayLog("root", level, msg);
|
||||
}
|
||||
fprintf(stderr, "%s\n%s\n", errmsg, msg.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// All we want to do is call Python logging.XXX. That's on Python.
|
||||
g_python->LoggingCall(level, msg);
|
||||
}
|
||||
|
||||
auto Logging::DisplayLog(const std::string& name, LogLevel level,
|
||||
const std::string& msg) -> void {
|
||||
auto msgnewline{msg + "\n"};
|
||||
|
||||
// Print to in-game console.
|
||||
{
|
||||
if (g_game != nullptr) {
|
||||
g_game->PushConsolePrintCall(s);
|
||||
if (g_logic != nullptr) {
|
||||
g_logic->PushConsolePrintCall(msgnewline);
|
||||
} else {
|
||||
if (g_platform != nullptr) {
|
||||
g_platform->HandleLog(
|
||||
"Warning: Log() called before game-thread setup; "
|
||||
"will not appear on in-game console.\n");
|
||||
g_platform->DisplayLog("root", LogLevel::kWarning,
|
||||
"DisplayLog() called before logic-thread setup; "
|
||||
"will not appear on in-game console.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print to any telnet clients.
|
||||
if (g_app && g_app->telnet_server) {
|
||||
g_app->telnet_server->PushPrint(s);
|
||||
g_app->telnet_server->PushPrint(msgnewline);
|
||||
}
|
||||
|
||||
// Ship to platform-specific display mechanisms (android log, etc).
|
||||
g_platform->DisplayLog(name, level, msg);
|
||||
}
|
||||
|
||||
void Logging::PrintStdout(const std::string& s, bool flush) {
|
||||
fprintf(stdout, "%s", s.c_str());
|
||||
if (flush) {
|
||||
fflush(stdout);
|
||||
}
|
||||
PrintCommon(s);
|
||||
}
|
||||
|
||||
void Logging::PrintStderr(const std::string& s, bool flush) {
|
||||
fprintf(stderr, "%s", s.c_str());
|
||||
if (flush) {
|
||||
fflush(stderr);
|
||||
}
|
||||
PrintCommon(s);
|
||||
}
|
||||
|
||||
void Logging::Log(const std::string& msg, bool to_stdout, bool to_server) {
|
||||
if (to_stdout) {
|
||||
PrintStdout(msg + "\n", true);
|
||||
auto Logging::V1CloudLog(const std::string& msg) -> void {
|
||||
// Route through platform-specific loggers if present.
|
||||
// (things like Crashlytics crash-logging)
|
||||
if (g_platform) {
|
||||
Platform::DebugLog(msg);
|
||||
}
|
||||
|
||||
// Ship to the platform logging mechanism (android-log, stderr, etc.)
|
||||
// if that's available yet.
|
||||
if (g_platform != nullptr) {
|
||||
g_platform->HandleLog(msg);
|
||||
}
|
||||
|
||||
// Ship to master-server/etc.
|
||||
if (to_server) {
|
||||
// Route through platform-specific loggers if present.
|
||||
// (things like Crashlytics crash-logging)
|
||||
if (g_platform) {
|
||||
Platform::DebugLog(msg);
|
||||
}
|
||||
|
||||
// Add to our complete log.
|
||||
if (g_app != nullptr) {
|
||||
std::scoped_lock lock(g_app->log_mutex);
|
||||
if (!g_app->log_full) {
|
||||
(g_app->log) += (msg + "\n");
|
||||
if ((g_app->log).size() > 10000) {
|
||||
// Allow some reasonable overflow for last statement.
|
||||
if ((g_app->log).size() > 100000) {
|
||||
// FIXME: This could potentially chop up utf-8 chars.
|
||||
(g_app->log).resize(100000);
|
||||
}
|
||||
g_app->log += "\n<max log size reached>\n";
|
||||
g_app->log_full = true;
|
||||
// Add to our complete v1-cloud-log.
|
||||
if (g_app != nullptr) {
|
||||
std::scoped_lock lock(g_app->v1_cloud_log_mutex);
|
||||
if (!g_app->v1_cloud_log_full) {
|
||||
(g_app->v1_cloud_log) += (msg + "\n");
|
||||
if ((g_app->v1_cloud_log).size() > 10000) {
|
||||
// Allow some reasonable overflow for last statement.
|
||||
if ((g_app->v1_cloud_log).size() > 100000) {
|
||||
// FIXME: This could potentially chop up utf-8 chars.
|
||||
(g_app->v1_cloud_log).resize(100000);
|
||||
}
|
||||
g_app->v1_cloud_log += "\n<max log size reached>\n";
|
||||
g_app->v1_cloud_log_full = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the game is fully bootstrapped, let the Python layer handle logs.
|
||||
// It will group log messages intelligently and ship them to the
|
||||
// master server with various other context info included.
|
||||
if (g_app && g_app->is_bootstrapped) {
|
||||
assert(g_python != nullptr);
|
||||
g_python->PushObjCall(Python::ObjID::kHandleLogCall);
|
||||
} else {
|
||||
// For log messages during bootstrapping we ship them immediately since
|
||||
// we don't know if the Python layer is (or will be) able to.
|
||||
if (g_early_log_writes > 0) {
|
||||
g_early_log_writes -= 1;
|
||||
std::string logprefix = "EARLY-LOG:";
|
||||
std::string logsuffix;
|
||||
// If the game is fully bootstrapped, let the Python layer handle logs.
|
||||
// It will group log messages intelligently and ship them to the
|
||||
// master server with various other context info included.
|
||||
if (g_app && g_app->is_bootstrapped) {
|
||||
assert(g_python != nullptr);
|
||||
g_python->PushObjCall(Python::ObjID::kHandleV1CloudLogCall);
|
||||
} else {
|
||||
// For log messages during bootstrapping we ship them immediately since
|
||||
// we don't know if the Python layer is (or will be) able to.
|
||||
if (g_early_v1_cloud_log_writes > 0) {
|
||||
g_early_v1_cloud_log_writes -= 1;
|
||||
std::string logprefix = "EARLY-LOG:";
|
||||
std::string logsuffix;
|
||||
|
||||
// If we're an early enough error, our global log isn't even available,
|
||||
// so include this specific message as a suffix instead.
|
||||
if (g_app == nullptr) {
|
||||
logsuffix = msg;
|
||||
}
|
||||
g_app_internal->DirectSendLogs(logprefix, logsuffix, false);
|
||||
// If we're an early enough error, our global log isn't even available,
|
||||
// so include this specific message as a suffix instead.
|
||||
if (g_app == nullptr) {
|
||||
logsuffix = msg;
|
||||
}
|
||||
g_app_internal->DirectSendV1CloudLogs(logprefix, logsuffix, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,23 +5,33 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ballistica/ballistica.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
class Logging {
|
||||
public:
|
||||
/// Print a string directly to stdout as well as the in-game console
|
||||
/// and any connected telnet consoles.
|
||||
static auto PrintStdout(const std::string& s, bool flush = false) -> void;
|
||||
/// Write a message to the log. Intended for logging use in C++ code.
|
||||
/// This is safe to call by any thread at any time. In general it simply
|
||||
/// passes through to the equivalent Python log calls: logging.info,
|
||||
/// logging.warning, etc.
|
||||
/// Note that log messages often must go through some background
|
||||
/// processing before being seen by the user, meaning they may not
|
||||
/// always work well for tight debugging purposes. In cases such as these,
|
||||
/// printf() type calls or calling DisplayLog() directly may work better.
|
||||
/// (though both of these should be avoided in permanent code).
|
||||
static auto Log(LogLevel level, const std::string& msg) -> void;
|
||||
|
||||
/// Print a string directly to stderr as well as the in-game console
|
||||
/// and any connected telnet consoles.
|
||||
static auto PrintStderr(const std::string& s, bool flush = false) -> void;
|
||||
/// Immediately display a log message in the in-game console,
|
||||
/// platform-specific logs, etc. This generally should not be called
|
||||
/// directly but instead wired up to display messages coming from the
|
||||
/// Python logging system.
|
||||
static auto DisplayLog(const std::string& name, LogLevel level,
|
||||
const std::string& msg) -> void;
|
||||
|
||||
/// Write a string to the debug log.
|
||||
/// This will go to stdout, windows debug log, android log, etc. depending
|
||||
/// on the platform.
|
||||
static auto Log(const std::string& msg, bool to_stdout = true,
|
||||
bool to_server = true) -> void;
|
||||
/// Write a message to the v1 cloud log. This is considered legacy
|
||||
/// and will be phased out eventually.
|
||||
static auto V1CloudLog(const std::string& msg) -> void;
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -18,8 +18,8 @@ void MacroFunctionTimerEnd(millisecs_t starttime, millisecs_t time,
|
||||
}
|
||||
millisecs_t endtime = g_platform->GetTicks();
|
||||
if (endtime - starttime > time) {
|
||||
Log("Warning: " + std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent in " + funcname);
|
||||
Log(LogLevel::kWarning, std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent in " + funcname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,9 +32,9 @@ void MacroFunctionTimerEndThread(millisecs_t starttime, millisecs_t time,
|
||||
}
|
||||
millisecs_t endtime = g_platform->GetTicks();
|
||||
if (endtime - starttime > time) {
|
||||
Log("Warning: " + std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent by " + ballistica::GetCurrentThreadName()
|
||||
+ " thread in " + funcname);
|
||||
Log(LogLevel::kWarning,
|
||||
std::to_string(endtime - starttime) + " milliseconds spent by "
|
||||
+ ballistica::GetCurrentThreadName() + " thread in " + funcname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,8 +47,9 @@ void MacroFunctionTimerEndEx(millisecs_t starttime, millisecs_t time,
|
||||
}
|
||||
millisecs_t endtime = g_platform->GetTicks();
|
||||
if (endtime - starttime > time) {
|
||||
Log("Warning: " + std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent in " + funcname + " for " + what);
|
||||
Log(LogLevel::kWarning, std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent in " + funcname + " for "
|
||||
+ what);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,9 +63,10 @@ void MacroFunctionTimerEndThreadEx(millisecs_t starttime, millisecs_t time,
|
||||
}
|
||||
millisecs_t endtime = g_platform->GetTicks();
|
||||
if (endtime - starttime > time) {
|
||||
Log("Warning: " + std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent by " + ballistica::GetCurrentThreadName()
|
||||
+ " thread in " + funcname + " for " + what);
|
||||
Log(LogLevel::kWarning, std::to_string(endtime - starttime)
|
||||
+ " milliseconds spent by "
|
||||
+ ballistica::GetCurrentThreadName()
|
||||
+ " thread in " + funcname + " for " + what);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,9 +79,9 @@ void MacroTimeCheckEnd(millisecs_t starttime, millisecs_t time,
|
||||
}
|
||||
millisecs_t e = g_platform->GetTicks();
|
||||
if (e - starttime > time) {
|
||||
Log(std::string("Warning: ") + name + " took "
|
||||
+ std::to_string(e - starttime) + " milliseconds; " + file + " line "
|
||||
+ std::to_string(line));
|
||||
Log(LogLevel::kWarning,
|
||||
std::string(name) + " took " + std::to_string(e - starttime)
|
||||
+ " milliseconds; " + file + " line " + std::to_string(line));
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,19 +90,19 @@ void MacroLogErrorTrace(const std::string& msg, const char* fname, int line) {
|
||||
snprintf(buffer, sizeof(buffer), "%s:%d:", fname, line);
|
||||
buffer[sizeof(buffer) - 1] = 0;
|
||||
Python::PrintStackTrace();
|
||||
Log(std::string(buffer) + " error: " + msg);
|
||||
Log(LogLevel::kError, std::string(buffer) + " error: " + msg);
|
||||
}
|
||||
|
||||
void MacroLogError(const std::string& msg, const char* fname, int line) {
|
||||
char e_buffer[2048];
|
||||
snprintf(e_buffer, sizeof(e_buffer), "%s:%d:", fname, line);
|
||||
e_buffer[sizeof(e_buffer) - 1] = 0;
|
||||
ballistica::Log(std::string(e_buffer) + " error: " + msg);
|
||||
Log(LogLevel::kError, std::string(e_buffer) + " error: " + msg);
|
||||
}
|
||||
|
||||
void MacroLogPythonTrace(const std::string& msg) {
|
||||
Python::PrintStackTrace();
|
||||
Log(msg);
|
||||
Log(LogLevel::kError, msg);
|
||||
}
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -86,11 +86,11 @@
|
||||
} \
|
||||
((void)0) // (see 'Trailing-semicolon note' at top)
|
||||
|
||||
#define BA_LOG_ONCE(msg) \
|
||||
#define BA_LOG_ONCE(lvl, msg) \
|
||||
{ \
|
||||
static bool did_log_here = false; \
|
||||
if (!did_log_here) { \
|
||||
ballistica::Log(msg); \
|
||||
ballistica::Log(lvl, msg); \
|
||||
did_log_here = true; \
|
||||
} \
|
||||
} \
|
||||
@ -120,12 +120,12 @@
|
||||
|
||||
/// Test a condition and simply print a log message if it fails (on both debug
|
||||
/// and release builds)
|
||||
#define BA_PRECONDITION_LOG(b) \
|
||||
{ \
|
||||
if (!(b)) { \
|
||||
Log("Precondition failed: " #b); \
|
||||
} \
|
||||
} \
|
||||
#define BA_PRECONDITION_LOG(b) \
|
||||
{ \
|
||||
if (!(b)) { \
|
||||
Log(LogLevel::kError, "Precondition failed: " #b); \
|
||||
} \
|
||||
} \
|
||||
((void)0) // (see 'Trailing-semicolon note' at top)
|
||||
|
||||
/// Test a condition and abort the program if it fails (on both debug
|
||||
|
||||
@ -54,9 +54,9 @@ void Object::PrintObjects() {
|
||||
assert(count == g_app->object_count);
|
||||
}
|
||||
}
|
||||
Log(s);
|
||||
Log(LogLevel::kInfo, s);
|
||||
#else
|
||||
Log("PrintObjects() only functions in debug builds.");
|
||||
Log(LogLevel::kInfo, "PrintObjects() only functions in debug builds.");
|
||||
#endif // BA_DEBUG_BUILD
|
||||
}
|
||||
|
||||
@ -126,8 +126,8 @@ auto Object::GetObjectDescription() const -> std::string {
|
||||
+ ">";
|
||||
}
|
||||
|
||||
auto Object::GetDefaultOwnerThread() const -> ThreadIdentifier {
|
||||
return ThreadIdentifier::kLogic;
|
||||
auto Object::GetDefaultOwnerThread() const -> ThreadTag {
|
||||
return ThreadTag::kLogic;
|
||||
}
|
||||
|
||||
auto Object::GetThreadOwnership() const -> Object::ThreadOwnership {
|
||||
@ -141,19 +141,19 @@ auto Object::GetThreadOwnership() const -> Object::ThreadOwnership {
|
||||
|
||||
#if BA_DEBUG_BUILD
|
||||
|
||||
static auto GetCurrentThreadIdentifier() -> ThreadIdentifier {
|
||||
static auto GetCurrentThreadTag() -> ThreadTag {
|
||||
if (InMainThread()) {
|
||||
return ThreadIdentifier::kMain;
|
||||
return ThreadTag::kMain;
|
||||
} else if (InLogicThread()) {
|
||||
return ThreadIdentifier::kLogic;
|
||||
return ThreadTag::kLogic;
|
||||
} else if (InAudioThread()) {
|
||||
return ThreadIdentifier::kAudio;
|
||||
return ThreadTag::kAudio;
|
||||
} else if (InNetworkWriteThread()) {
|
||||
return ThreadIdentifier::kNetworkWrite;
|
||||
} else if (InMediaThread()) {
|
||||
return ThreadIdentifier::kMedia;
|
||||
return ThreadTag::kNetworkWrite;
|
||||
} else if (InAssetsThread()) {
|
||||
return ThreadTag::kAssets;
|
||||
} else if (InBGDynamicsThread()) {
|
||||
return ThreadIdentifier::kBGDynamics;
|
||||
return ThreadTag::kBGDynamics;
|
||||
} else {
|
||||
throw Exception(std::string("unrecognized thread: ")
|
||||
+ GetCurrentThreadName());
|
||||
@ -166,8 +166,8 @@ auto Object::ObjectUpdateForAcquire() -> void {
|
||||
// If we're set to use the next-referencing thread and haven't set one
|
||||
// yet, do so.
|
||||
if (thread_ownership == ThreadOwnership::kNextReferencing
|
||||
&& owner_thread_ == ThreadIdentifier::kInvalid) {
|
||||
owner_thread_ = GetCurrentThreadIdentifier();
|
||||
&& owner_thread_ == ThreadTag::kInvalid) {
|
||||
owner_thread_ = GetCurrentThreadTag();
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ auto Object::ObjectThreadCheck() -> void {
|
||||
|
||||
ThreadOwnership thread_ownership = GetThreadOwnership();
|
||||
|
||||
ThreadIdentifier t;
|
||||
ThreadTag t;
|
||||
if (thread_ownership == ThreadOwnership::kClassDefault) {
|
||||
t = GetDefaultOwnerThread();
|
||||
} else {
|
||||
@ -189,32 +189,32 @@ auto Object::ObjectThreadCheck() -> void {
|
||||
+ "; expected " THREADNAME " thread; got " \
|
||||
+ GetCurrentThreadName())
|
||||
switch (t) {
|
||||
case ThreadIdentifier::kMain:
|
||||
case ThreadTag::kMain:
|
||||
if (!InMainThread()) {
|
||||
DO_FAIL("Main");
|
||||
}
|
||||
break;
|
||||
case ThreadIdentifier::kLogic:
|
||||
case ThreadTag::kLogic:
|
||||
if (!InLogicThread()) {
|
||||
DO_FAIL("Logic");
|
||||
}
|
||||
break;
|
||||
case ThreadIdentifier::kAudio:
|
||||
case ThreadTag::kAudio:
|
||||
if (!InAudioThread()) {
|
||||
DO_FAIL("Audio");
|
||||
}
|
||||
break;
|
||||
case ThreadIdentifier::kNetworkWrite:
|
||||
case ThreadTag::kNetworkWrite:
|
||||
if (!InNetworkWriteThread()) {
|
||||
DO_FAIL("NetworkWrite");
|
||||
}
|
||||
break;
|
||||
case ThreadIdentifier::kMedia:
|
||||
if (!InMediaThread()) {
|
||||
DO_FAIL("Media");
|
||||
case ThreadTag::kAssets:
|
||||
if (!InAssetsThread()) {
|
||||
DO_FAIL("Assets");
|
||||
}
|
||||
break;
|
||||
case ThreadIdentifier::kBGDynamics:
|
||||
case ThreadTag::kBGDynamics:
|
||||
if (!InBGDynamicsThread()) {
|
||||
DO_FAIL("BGDynamics");
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ class Object {
|
||||
/// it can perform sanity-tests to make sure references are not being
|
||||
/// added at incorrect times or from incorrect threads.
|
||||
/// The default implementation uses the per-object
|
||||
/// ThreadOwnership/ThreadIdentifier values accessible below. NOTE: this
|
||||
/// ThreadOwnership/ThreadTag values accessible below. NOTE: this
|
||||
/// check runs only in the debug build so don't add any logical side-effects!
|
||||
virtual void ObjectThreadCheck();
|
||||
|
||||
@ -59,15 +59,15 @@ class Object {
|
||||
|
||||
/// Return the exact thread to check for with ThreadOwnership::kClassDefault
|
||||
/// (in the default ObjectThreadCheck implementation at least).
|
||||
/// Default returns ThreadIdentifier::kLogic
|
||||
virtual auto GetDefaultOwnerThread() const -> ThreadIdentifier;
|
||||
/// Default returns ThreadTag::kLogic
|
||||
virtual auto GetDefaultOwnerThread() const -> ThreadTag;
|
||||
|
||||
/// Set thread ownership for an individual object.
|
||||
void SetThreadOwnership(ThreadOwnership ownership) {
|
||||
#if BA_DEBUG_BUILD
|
||||
thread_ownership_ = ownership;
|
||||
if (thread_ownership_ == ThreadOwnership::kNextReferencing) {
|
||||
owner_thread_ = ThreadIdentifier::kInvalid;
|
||||
owner_thread_ = ThreadTag::kInvalid;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -560,7 +560,7 @@ class Object {
|
||||
Object* object_next_{};
|
||||
Object* object_prev_{};
|
||||
ThreadOwnership thread_ownership_{ThreadOwnership::kClassDefault};
|
||||
ThreadIdentifier owner_thread_{ThreadIdentifier::kInvalid};
|
||||
ThreadTag owner_thread_{ThreadTag::kInvalid};
|
||||
bool thread_checks_enabled_{true};
|
||||
millisecs_t object_birth_time_{};
|
||||
bool object_printed_warning_{};
|
||||
|
||||
@ -11,7 +11,6 @@ namespace ballistica {
|
||||
|
||||
void Thread::SetInternalThreadName(const std::string& name) {
|
||||
std::scoped_lock lock(g_app->thread_name_map_mutex);
|
||||
std::thread::id thread_id = std::this_thread::get_id();
|
||||
g_app->thread_name_map[std::this_thread::get_id()] = name;
|
||||
}
|
||||
|
||||
@ -44,26 +43,54 @@ auto Thread::RunLogicThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
|
||||
auto Thread::RunLogicThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Thread::RunAudioThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
auto Thread::RunAudioThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Thread::RunBGDynamicThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
|
||||
auto Thread::RunBGDynamicThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Thread::RunNetworkWriteThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
|
||||
auto Thread::RunNetworkWriteThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Thread::RunStdInputThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
auto Thread::RunStdInputThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Thread::RunMediaThread(void* data) -> int {
|
||||
auto Thread::RunAssetsThread(void* data) -> int {
|
||||
return static_cast<Thread*>(data)->ThreadMain();
|
||||
}
|
||||
|
||||
auto Thread::RunAssetsThreadP(void* data) -> void* {
|
||||
static_cast<Thread*>(data)->ThreadMain();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Thread::SetPaused(bool paused) {
|
||||
// Can be toggled from the main thread only.
|
||||
assert(std::this_thread::get_id() == g_app->main_thread_id);
|
||||
@ -85,7 +112,7 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
}
|
||||
|
||||
// While we're waiting, allow other python threads to run.
|
||||
if (owns_python_) {
|
||||
if (acquires_python_gil_) {
|
||||
g_python->ReleaseGIL();
|
||||
}
|
||||
|
||||
@ -96,29 +123,29 @@ void Thread::WaitForNextEvent(bool single_cycle) {
|
||||
millisecs_t wait_time = timers_.GetTimeToNextExpire(real_time);
|
||||
if (wait_time > 0) {
|
||||
std::unique_lock<std::mutex> lock(thread_message_mutex_);
|
||||
if (thread_message_count_ == 0) {
|
||||
if (thread_messages_.empty()) {
|
||||
thread_message_cv_.wait_for(lock, std::chrono::milliseconds(wait_time),
|
||||
[this] {
|
||||
// Go back to sleep on spurious wakeups
|
||||
// if we didn't wind up with any new
|
||||
// messages.
|
||||
return (thread_message_count_ > 0);
|
||||
return !thread_messages_.empty();
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not running timers; just wait indefinitely for the next message.
|
||||
std::unique_lock<std::mutex> lock(thread_message_mutex_);
|
||||
if (thread_message_count_ == 0) {
|
||||
if (thread_messages_.empty()) {
|
||||
thread_message_cv_.wait(lock, [this] {
|
||||
// Go back to sleep on spurious wakeups
|
||||
// (if we didn't wind up with any new messages).
|
||||
return (thread_message_count_ > 0);
|
||||
return !(thread_messages_.empty());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (owns_python_) {
|
||||
if (acquires_python_gil_) {
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
}
|
||||
@ -203,49 +230,69 @@ void Thread::GetThreadMessages(std::list<ThreadMessage>* messages) {
|
||||
|
||||
// Make sure they passed an empty one in.
|
||||
assert(messages->empty());
|
||||
if (thread_message_count_ > 0) {
|
||||
std::unique_lock<std::mutex> lock(thread_message_mutex_);
|
||||
assert(thread_messages_.size() == thread_message_count_);
|
||||
std::scoped_lock lock(thread_message_mutex_);
|
||||
if (!thread_messages_.empty()) {
|
||||
messages->swap(thread_messages_);
|
||||
thread_message_count_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in)
|
||||
: type_(type_in), identifier_(identifier_in) {
|
||||
switch (type_) {
|
||||
case ThreadType::kStandard: {
|
||||
// Lock down until the thread is up and running. It'll unlock us when
|
||||
// it's ready to go.
|
||||
Thread::Thread(ThreadTag identifier_in, ThreadSource source)
|
||||
: source_(source), identifier_(identifier_in) {
|
||||
switch (source_) {
|
||||
case ThreadSource::kCreate: {
|
||||
int (*func)(void*);
|
||||
void* (*funcp)(void*);
|
||||
switch (identifier_) {
|
||||
case ThreadIdentifier::kLogic:
|
||||
case ThreadTag::kLogic:
|
||||
func = RunLogicThread;
|
||||
funcp = RunLogicThreadP;
|
||||
break;
|
||||
case ThreadIdentifier::kMedia:
|
||||
func = RunMediaThread;
|
||||
case ThreadTag::kAssets:
|
||||
func = RunAssetsThread;
|
||||
funcp = RunAssetsThreadP;
|
||||
break;
|
||||
case ThreadIdentifier::kMain:
|
||||
case ThreadTag::kMain:
|
||||
// Shouldn't happen; this thread gets wrapped; not launched.
|
||||
throw Exception();
|
||||
case ThreadIdentifier::kAudio:
|
||||
case ThreadTag::kAudio:
|
||||
func = RunAudioThread;
|
||||
funcp = RunAudioThreadP;
|
||||
break;
|
||||
case ThreadIdentifier::kBGDynamics:
|
||||
case ThreadTag::kBGDynamics:
|
||||
func = RunBGDynamicThread;
|
||||
funcp = RunBGDynamicThreadP;
|
||||
break;
|
||||
case ThreadIdentifier::kNetworkWrite:
|
||||
case ThreadTag::kNetworkWrite:
|
||||
func = RunNetworkWriteThread;
|
||||
funcp = RunNetworkWriteThreadP;
|
||||
break;
|
||||
case ThreadIdentifier::kStdin:
|
||||
case ThreadTag::kStdin:
|
||||
func = RunStdInputThread;
|
||||
funcp = RunStdInputThreadP;
|
||||
break;
|
||||
default:
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
// Let 'er rip.
|
||||
thread_ = new std::thread(func, this);
|
||||
// Let 'er rip.
|
||||
|
||||
// NOTE: Apple platforms have a default secondary thread stack size
|
||||
// of 512k which I've found to be insufficient in cases of heavy
|
||||
// Python recursion or large simulations. It sounds like Windows
|
||||
// and Android might have 1mb as default; let's try to standardize
|
||||
// on that across the board. Unfortunately we have to use pthreads
|
||||
// to get custom stack sizes; std::thread stupidly doesn't support it.
|
||||
|
||||
// FIXME - move this to platform.
|
||||
#if BA_OSTYPE_MACOS || BA_OSTYPE_IOS_TVOS || BA_OSTYPE_LINUX
|
||||
pthread_attr_t attr;
|
||||
BA_PRECONDITION(pthread_attr_init(&attr) == 0);
|
||||
BA_PRECONDITION(pthread_attr_setstacksize(&attr, 1024 * 1024) == 0);
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, &attr, funcp, this);
|
||||
#else
|
||||
new std::thread(func, this);
|
||||
#endif
|
||||
|
||||
// Block until the thread is bootstrapped.
|
||||
// (maybe not necessary, but let's be cautious in case we'd
|
||||
@ -255,7 +302,7 @@ Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in)
|
||||
|
||||
break;
|
||||
}
|
||||
case ThreadType::kMain: {
|
||||
case ThreadSource::kWrapMain: {
|
||||
// We've got no thread of our own to launch
|
||||
// so we run our setup stuff right here instead of off in some.
|
||||
assert(std::this_thread::get_id() == g_app->main_thread_id);
|
||||
@ -275,41 +322,41 @@ Thread::Thread(ThreadIdentifier identifier_in, ThreadType type_in)
|
||||
|
||||
auto Thread::ThreadMain() -> int {
|
||||
try {
|
||||
assert(type_ == ThreadType::kStandard);
|
||||
assert(source_ == ThreadSource::kCreate);
|
||||
thread_id_ = std::this_thread::get_id();
|
||||
const char* name;
|
||||
const char* id_string;
|
||||
|
||||
switch (identifier_) {
|
||||
case ThreadIdentifier::kLogic:
|
||||
case ThreadTag::kLogic:
|
||||
name = "logic";
|
||||
id_string = "ballistica logic";
|
||||
break;
|
||||
case ThreadIdentifier::kStdin:
|
||||
case ThreadTag::kStdin:
|
||||
name = "stdin";
|
||||
id_string = "ballistica stdin";
|
||||
break;
|
||||
case ThreadIdentifier::kMedia:
|
||||
name = "media";
|
||||
id_string = "ballistica media";
|
||||
case ThreadTag::kAssets:
|
||||
name = "assets";
|
||||
id_string = "ballistica assets";
|
||||
break;
|
||||
case ThreadIdentifier::kFileOut:
|
||||
case ThreadTag::kFileOut:
|
||||
name = "fileout";
|
||||
id_string = "ballistica file-out";
|
||||
break;
|
||||
case ThreadIdentifier::kMain:
|
||||
case ThreadTag::kMain:
|
||||
name = "main";
|
||||
id_string = "ballistica main";
|
||||
break;
|
||||
case ThreadIdentifier::kAudio:
|
||||
case ThreadTag::kAudio:
|
||||
name = "audio";
|
||||
id_string = "ballistica audio";
|
||||
break;
|
||||
case ThreadIdentifier::kBGDynamics:
|
||||
case ThreadTag::kBGDynamics:
|
||||
name = "bgdynamics";
|
||||
id_string = "ballistica bg-dynamics";
|
||||
break;
|
||||
case ThreadIdentifier::kNetworkWrite:
|
||||
case ThreadTag::kNetworkWrite:
|
||||
name = "networkwrite";
|
||||
id_string = "ballistica network writing";
|
||||
break;
|
||||
@ -322,10 +369,7 @@ auto Thread::ThreadMain() -> int {
|
||||
|
||||
// Mark ourself as bootstrapped and signal listeners so
|
||||
// anyone waiting for us to spin up can move along.
|
||||
{
|
||||
std::scoped_lock lock(client_listener_mutex_);
|
||||
bootstrapped_ = true;
|
||||
}
|
||||
bootstrapped_ = true;
|
||||
client_listener_cv_.notify_all();
|
||||
|
||||
// Now just run our loop until we die.
|
||||
@ -358,15 +402,17 @@ auto Thread::ThreadMain() -> int {
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::SetOwnsPython() {
|
||||
owns_python_ = true;
|
||||
void Thread::SetAcquiresPythonGIL() {
|
||||
assert(!acquires_python_gil_); // This should be called exactly once.
|
||||
assert(IsCurrent());
|
||||
acquires_python_gil_ = true;
|
||||
g_python->AcquireGIL();
|
||||
}
|
||||
|
||||
// Explicitly kill the main thread.
|
||||
void Thread::Quit() {
|
||||
assert(type_ == ThreadType::kMain);
|
||||
if (type_ == ThreadType::kMain) {
|
||||
assert(source_ == ThreadSource::kWrapMain);
|
||||
if (source_ == ThreadSource::kWrapMain) {
|
||||
done_ = true;
|
||||
}
|
||||
}
|
||||
@ -382,8 +428,9 @@ void Thread::LogThreadMessageTally() {
|
||||
writing_tally_ = true;
|
||||
|
||||
std::unordered_map<std::string, int> tally;
|
||||
Log("Thread message tally (" + std::to_string(thread_messages_.size())
|
||||
+ " in list):");
|
||||
Log(LogLevel::kError, "Thread message tally ("
|
||||
+ std::to_string(thread_messages_.size())
|
||||
+ " in list):");
|
||||
for (auto&& m : thread_messages_) {
|
||||
std::string s;
|
||||
switch (m.type) {
|
||||
@ -417,8 +464,8 @@ void Thread::LogThreadMessageTally() {
|
||||
}
|
||||
int entry = 1;
|
||||
for (auto&& i : tally) {
|
||||
Log(" #" + std::to_string(entry++) + " (" + std::to_string(i.second)
|
||||
+ "x): " + i.first);
|
||||
Log(LogLevel::kError, " #" + std::to_string(entry++) + " ("
|
||||
+ std::to_string(i.second) + "x): " + i.first);
|
||||
}
|
||||
writing_tally_ = false;
|
||||
}
|
||||
@ -432,13 +479,10 @@ void Thread::PushThreadMessage(const ThreadMessage& t) {
|
||||
// Plop the data on to the list; we're assuming the mutex is locked.
|
||||
thread_messages_.push_back(t);
|
||||
|
||||
// Keep our own count; apparently size() on an stl list involves
|
||||
// iterating.
|
||||
// Keep our own count; apparently size() on an stl list involves iterating.
|
||||
// FIXME: Actually I don't think this is the case anymore; should check.
|
||||
thread_message_count_++;
|
||||
assert(thread_message_count_ == thread_messages_.size());
|
||||
|
||||
// Show message count states.
|
||||
// Debugging: show message count states.
|
||||
if (explicit_bool(false)) {
|
||||
static int one_off = 0;
|
||||
static int foo = 0;
|
||||
@ -446,7 +490,7 @@ void Thread::PushThreadMessage(const ThreadMessage& t) {
|
||||
one_off++;
|
||||
|
||||
// Show momemtary spikes.
|
||||
if (thread_message_count_ > 100 && one_off > 100) {
|
||||
if (thread_messages_.size() > 100 && one_off > 100) {
|
||||
one_off = 0;
|
||||
foo = 999;
|
||||
}
|
||||
@ -454,24 +498,25 @@ void Thread::PushThreadMessage(const ThreadMessage& t) {
|
||||
// Show count periodically.
|
||||
if ((std::this_thread::get_id() == g_app->main_thread_id) && foo > 100) {
|
||||
foo = 0;
|
||||
Log("MSG COUNT " + std::to_string(thread_message_count_));
|
||||
Log(LogLevel::kInfo,
|
||||
"MSG COUNT " + std::to_string(thread_messages_.size()));
|
||||
}
|
||||
}
|
||||
|
||||
if (thread_message_count_ > 1000) {
|
||||
if (thread_messages_.size() > 1000) {
|
||||
static bool sent_error = false;
|
||||
if (!sent_error) {
|
||||
sent_error = true;
|
||||
Log("Error: ThreadMessage list > 1000 in thread: "
|
||||
+ GetCurrentThreadName());
|
||||
Log(LogLevel::kError,
|
||||
"ThreadMessage list > 1000 in thread: " + GetCurrentThreadName());
|
||||
LogThreadMessageTally();
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent runaway mem usage if the list gets out of control.
|
||||
if (thread_message_count_ > 10000) {
|
||||
throw Exception("KILLING APP: ThreadMessage list > 10000 in thread: "
|
||||
+ GetCurrentThreadName());
|
||||
if (thread_messages_.size() > 10000) {
|
||||
FatalError("ThreadMessage list > 10000 in thread: "
|
||||
+ GetCurrentThreadName());
|
||||
}
|
||||
|
||||
// Unlock thread-message list and inform thread that there's something
|
||||
@ -618,5 +663,12 @@ auto Thread::CheckPushSafety() -> bool {
|
||||
return CheckPushRunnableSafety();
|
||||
}
|
||||
}
|
||||
auto Thread::CheckPushRunnableSafety() -> bool {
|
||||
std::scoped_lock lock(client_listener_mutex_);
|
||||
|
||||
// We first complain when we get to 1000 queued messages so
|
||||
// let's consider things unsafe when we're halfway there.
|
||||
return (thread_messages_.size() < kThreadMessageSafetyThreshold);
|
||||
}
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -23,8 +23,7 @@ const int kThreadMessageSafetyThreshold{500};
|
||||
// A thread with a built-in event loop.
|
||||
class Thread {
|
||||
public:
|
||||
explicit Thread(ThreadIdentifier id,
|
||||
ThreadType type_in = ThreadType::kStandard);
|
||||
explicit Thread(ThreadTag id, ThreadSource source = ThreadSource::kCreate);
|
||||
virtual ~Thread();
|
||||
|
||||
auto ClearCurrentThreadName() -> void;
|
||||
@ -44,7 +43,7 @@ class Thread {
|
||||
// Used to quit the main thread.
|
||||
void Quit();
|
||||
|
||||
void SetOwnsPython();
|
||||
void SetAcquiresPythonGIL();
|
||||
|
||||
void SetPaused(bool paused);
|
||||
auto thread_id() const -> std::thread::id { return thread_id_; }
|
||||
@ -55,13 +54,7 @@ class Thread {
|
||||
void set_thread_id(std::thread::id id) { thread_id_ = id; }
|
||||
|
||||
auto RunEventLoop(bool single_cycle = false) -> int;
|
||||
auto identifier() const -> ThreadIdentifier { return identifier_; }
|
||||
|
||||
auto CheckPushRunnableSafety() -> bool {
|
||||
// We first complain when we get to 1000 queued messages so
|
||||
// let's consider things unsafe when we're halfway there.
|
||||
return (thread_message_count_ < kThreadMessageSafetyThreshold);
|
||||
}
|
||||
auto identifier() const -> ThreadTag { return identifier_; }
|
||||
|
||||
// Register a timer to run on the thread.
|
||||
auto NewTimer(millisecs_t length, bool repeat,
|
||||
@ -116,7 +109,7 @@ class Thread {
|
||||
explicit ThreadMessage(Type type, Runnable* runnable, bool* completion_flag)
|
||||
: type(type), runnable(runnable), completion_flag{completion_flag} {}
|
||||
};
|
||||
|
||||
auto CheckPushRunnableSafety() -> bool;
|
||||
auto SetInternalThreadName(const std::string& name) -> void;
|
||||
auto WaitForNextEvent(bool single_cycle) -> void;
|
||||
auto LoopUpkeep(bool once) -> void;
|
||||
@ -132,12 +125,12 @@ class Thread {
|
||||
int messages_since_paused_{};
|
||||
millisecs_t last_paused_message_report_time_{};
|
||||
bool done_{};
|
||||
ThreadType type_;
|
||||
ThreadSource source_;
|
||||
int listen_sd_{};
|
||||
std::thread::id thread_id_{};
|
||||
ThreadIdentifier identifier_{ThreadIdentifier::kInvalid};
|
||||
ThreadTag identifier_{ThreadTag::kInvalid};
|
||||
millisecs_t last_complaint_time_{};
|
||||
bool owns_python_{};
|
||||
bool acquires_python_gil_{};
|
||||
|
||||
// FIXME: Should generalize this to some sort of PlatformThreadData class.
|
||||
#if BA_XCODE_BUILD
|
||||
@ -148,11 +141,17 @@ class Thread {
|
||||
// different thread groups makes its easy to see which thread is which
|
||||
// in profilers, backtraces, etc.
|
||||
static auto RunLogicThread(void* data) -> int;
|
||||
static auto RunLogicThreadP(void* data) -> void*;
|
||||
static auto RunAudioThread(void* data) -> int;
|
||||
static auto RunAudioThreadP(void* data) -> void*;
|
||||
static auto RunBGDynamicThread(void* data) -> int;
|
||||
static auto RunBGDynamicThreadP(void* data) -> void*;
|
||||
static auto RunNetworkWriteThread(void* data) -> int;
|
||||
static auto RunNetworkWriteThreadP(void* data) -> void*;
|
||||
static auto RunStdInputThread(void* data) -> int;
|
||||
static auto RunMediaThread(void* data) -> int;
|
||||
static auto RunStdInputThreadP(void* data) -> void*;
|
||||
static auto RunAssetsThread(void* data) -> int;
|
||||
static auto RunAssetsThreadP(void* data) -> void*;
|
||||
|
||||
auto ThreadMain() -> int;
|
||||
auto GetThreadMessages(std::list<ThreadMessage>* messages) -> void;
|
||||
@ -162,12 +161,11 @@ class Thread {
|
||||
auto RunPauseCallbacks() -> void;
|
||||
auto RunResumeCallbacks() -> void;
|
||||
|
||||
int thread_message_count_{};
|
||||
bool bootstrapped_{};
|
||||
std::list<std::pair<Runnable*, bool*>> runnables_;
|
||||
std::list<Runnable*> pause_callbacks_;
|
||||
std::list<Runnable*> resume_callbacks_;
|
||||
std::thread* thread_{};
|
||||
// std::thread* thread_{};
|
||||
std::condition_variable thread_message_cv_;
|
||||
std::mutex thread_message_mutex_;
|
||||
std::list<ThreadMessage> thread_messages_;
|
||||
|
||||
@ -34,12 +34,12 @@ typedef int64_t millisecs_t;
|
||||
// avoid pulling in their full headers as much as possible
|
||||
// to keep compile times down.
|
||||
|
||||
class Account;
|
||||
class AppFlavor;
|
||||
class AppConfig;
|
||||
class App;
|
||||
class AppInternal;
|
||||
class AreaOfInterest;
|
||||
class Assets;
|
||||
class Audio;
|
||||
class AudioServer;
|
||||
class AudioStreamer;
|
||||
@ -81,7 +81,6 @@ class DataData;
|
||||
class Dynamics;
|
||||
class FrameDef;
|
||||
struct FriendScoreSet;
|
||||
class Game;
|
||||
class GLContext;
|
||||
class GlobalsNode;
|
||||
class Graphics;
|
||||
@ -97,15 +96,15 @@ struct JointFixedEF;
|
||||
class Joystick;
|
||||
class JsonDict;
|
||||
class KeyboardInput;
|
||||
class Logic;
|
||||
class Material;
|
||||
class MaterialAction;
|
||||
class MaterialComponent;
|
||||
class MaterialConditionNode;
|
||||
class MaterialContext;
|
||||
class Matrix44f;
|
||||
class Media;
|
||||
class MediaComponentData;
|
||||
class MediaServer;
|
||||
class AssetComponentData;
|
||||
class AssetsServer;
|
||||
class MeshBufferBase;
|
||||
class MeshBufferVertexSprite;
|
||||
class MeshBufferVertexSimpleFull;
|
||||
@ -124,7 +123,7 @@ class NetClientThread;
|
||||
class NetGraph;
|
||||
class Networking;
|
||||
class NetworkReader;
|
||||
class NetworkWriteModule;
|
||||
class NetworkWriter;
|
||||
class Node;
|
||||
class NodeType;
|
||||
class NodeAttribute;
|
||||
@ -132,7 +131,6 @@ class NodeAttributeConnection;
|
||||
class NodeAttributeUnbound;
|
||||
class Object;
|
||||
class ObjectComponent;
|
||||
class GameStream;
|
||||
class Part;
|
||||
class Python;
|
||||
class Platform;
|
||||
@ -164,6 +162,8 @@ class RootUI;
|
||||
class RootWidget;
|
||||
class Runnable;
|
||||
class Scene;
|
||||
class SceneV1;
|
||||
class SceneStream;
|
||||
class ScoreToBeat;
|
||||
class SDLApp;
|
||||
class SDLContext;
|
||||
@ -174,7 +174,7 @@ class SoundData;
|
||||
class SpriteMesh;
|
||||
class StackWidget;
|
||||
class StressTest;
|
||||
class StdInputModule;
|
||||
class StdioConsole;
|
||||
class Module;
|
||||
class TelnetServer;
|
||||
class TestInput;
|
||||
@ -197,6 +197,7 @@ class Vector2f;
|
||||
class Vector3f;
|
||||
class Vector4f;
|
||||
class AppFlavorVR;
|
||||
class V1Account;
|
||||
class VRGraphics;
|
||||
class Widget;
|
||||
|
||||
@ -403,7 +404,7 @@ enum class SpecialChar {
|
||||
kLast // Sentinel
|
||||
};
|
||||
|
||||
enum class MediaType { kTexture, kCollideModel, kModel, kSound, kData, kLast };
|
||||
enum class AssetType { kTexture, kCollideModel, kModel, kSound, kData, kLast };
|
||||
|
||||
/// Python exception types we can raise from our own exceptions.
|
||||
enum class PyExcType {
|
||||
@ -423,6 +424,8 @@ enum class PyExcType {
|
||||
kWidgetNotFound
|
||||
};
|
||||
|
||||
enum class LogLevel { kDebug, kInfo, kWarning, kError, kCritical };
|
||||
|
||||
enum class SystemTextureID {
|
||||
kUIAtlas,
|
||||
kButtonSquare,
|
||||
@ -986,20 +989,20 @@ enum class NodeAttributeType {
|
||||
kCollideModelArray
|
||||
};
|
||||
|
||||
enum class ThreadType {
|
||||
enum class ThreadSource {
|
||||
/// A normal thread spun up by us.
|
||||
kStandard,
|
||||
kCreate,
|
||||
/// For wrapping a ballistica thread around the existing main thread.
|
||||
kMain
|
||||
kWrapMain
|
||||
};
|
||||
|
||||
/// Used for module-thread identification.
|
||||
/// Mostly just for debugging, through a few things are affected by this
|
||||
/// (the Logic thread manages the python GIL, etc).
|
||||
enum class ThreadIdentifier {
|
||||
enum class ThreadTag {
|
||||
kInvalid,
|
||||
kLogic,
|
||||
kMedia,
|
||||
kAssets,
|
||||
kFileOut,
|
||||
kMain,
|
||||
kAudio,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "ballistica/dynamics/bg/bg_dynamics.h"
|
||||
|
||||
#include "ballistica/assets/component/collide_model.h"
|
||||
#include "ballistica/core/thread.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_draw_snapshot.h"
|
||||
#include "ballistica/dynamics/bg/bg_dynamics_fuse_data.h"
|
||||
@ -10,19 +11,12 @@
|
||||
#include "ballistica/graphics/component/object_component.h"
|
||||
#include "ballistica/graphics/component/smoke_component.h"
|
||||
#include "ballistica/graphics/component/sprite_component.h"
|
||||
#include "ballistica/media/component/collide_model.h"
|
||||
|
||||
namespace ballistica {
|
||||
|
||||
void BGDynamics::Init() {
|
||||
// Just init our singleton.
|
||||
new BGDynamics();
|
||||
}
|
||||
|
||||
BGDynamics::BGDynamics() {
|
||||
assert(InLogicThread());
|
||||
// We're a singleton; make sure we don't already exist.
|
||||
assert(g_bg_dynamics == nullptr);
|
||||
g_bg_dynamics = this;
|
||||
}
|
||||
|
||||
void BGDynamics::AddTerrain(CollideModelData* o) {
|
||||
@ -188,7 +182,7 @@ void BGDynamics::Draw(FrameDef* frame_def) {
|
||||
c.SetCameraAligned(true);
|
||||
c.SetColor(2.0f, 2.0f, 2.0f, 1.0f);
|
||||
c.SetOverlay(draw_in_overlay);
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kSparks));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kSparks));
|
||||
c.DrawMesh(sparks_mesh_.get(), kModelDrawFlagNoReflection);
|
||||
c.Submit();
|
||||
}
|
||||
@ -203,7 +197,7 @@ void BGDynamics::Draw(FrameDef* frame_def) {
|
||||
lights_mesh_->SetData(
|
||||
Object::Ref<MeshBuffer<VertexSprite>>(ds->light_vertices));
|
||||
SpriteComponent c(frame_def->light_shadow_pass());
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kLightSoft));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kLightSoft));
|
||||
c.DrawMesh(lights_mesh_.get());
|
||||
c.Submit();
|
||||
}
|
||||
@ -216,7 +210,7 @@ void BGDynamics::Draw(FrameDef* frame_def) {
|
||||
shadows_mesh_->SetData(
|
||||
Object::Ref<MeshBuffer<VertexSprite>>(ds->shadow_vertices));
|
||||
SpriteComponent c(frame_def->light_shadow_pass());
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kLight));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kLight));
|
||||
c.DrawMesh(shadows_mesh_.get());
|
||||
c.Submit();
|
||||
}
|
||||
@ -268,7 +262,7 @@ void BGDynamics::Draw(FrameDef* frame_def) {
|
||||
Object::Ref<MeshBuffer<VertexSimpleFull>>(ds->fuse_vertices));
|
||||
{ // Draw!
|
||||
ObjectComponent c(frame_def->beauty_pass());
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kFuse));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kFuse));
|
||||
c.DrawMesh(fuses_mesh_.get(), kModelDrawFlagNoReflection);
|
||||
c.Submit();
|
||||
}
|
||||
@ -286,16 +280,16 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
ModelData* model;
|
||||
switch (chunk_type) {
|
||||
case BGDynamicsChunkType::kFlagStand:
|
||||
model = g_media->GetModel(SystemModelID::kFlagStand);
|
||||
model = g_assets->GetModel(SystemModelID::kFlagStand);
|
||||
break;
|
||||
case BGDynamicsChunkType::kSplinter:
|
||||
model = g_media->GetModel(SystemModelID::kShrapnelBoard);
|
||||
model = g_assets->GetModel(SystemModelID::kShrapnelBoard);
|
||||
break;
|
||||
case BGDynamicsChunkType::kSlime:
|
||||
model = g_media->GetModel(SystemModelID::kShrapnelSlime);
|
||||
model = g_assets->GetModel(SystemModelID::kShrapnelSlime);
|
||||
break;
|
||||
default:
|
||||
model = g_media->GetModel(SystemModelID::kShrapnel1);
|
||||
model = g_assets->GetModel(SystemModelID::kShrapnel1);
|
||||
break;
|
||||
}
|
||||
ObjectComponent c(frame_def->beauty_pass());
|
||||
@ -303,20 +297,20 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
// Set up shading.
|
||||
switch (chunk_type) {
|
||||
case BGDynamicsChunkType::kRock: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSoft);
|
||||
c.SetReflectionScale(0.2f, 0.2f, 0.2f);
|
||||
c.SetColor(0.6f, 0.6f, 0.5f);
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kIce: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSharp);
|
||||
c.SetAddColor(0.5f, 0.5f, 0.9f);
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kSlime: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSharper);
|
||||
c.SetReflectionScale(3.0f, 3.0f, 3.0f);
|
||||
c.SetColor(0.0f, 0.0f, 0.0f);
|
||||
@ -324,13 +318,13 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kMetal: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kPowerup);
|
||||
c.SetColor(0.5f, 0.5f, 0.55f);
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kSpark: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSharp);
|
||||
c.SetColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
c.SetReflectionScale(4.0f, 3.0f, 2.0f);
|
||||
@ -338,7 +332,7 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kSplinter: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSoft);
|
||||
c.SetColor(1.0f, 0.8f, 0.5f);
|
||||
break;
|
||||
@ -347,7 +341,7 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
c.SetTransparent(true);
|
||||
c.SetPremultiplied(true);
|
||||
c.SetLightShadow(LightShadowType::kNone);
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kShrapnel1));
|
||||
c.SetReflection(ReflectionType::kSharp);
|
||||
c.SetReflectionScale(0.5f, 0.4f, 0.3f);
|
||||
c.SetColor(0.2f, 0.15f, 0.15f, 0.07f);
|
||||
@ -355,7 +349,7 @@ void BGDynamics::DrawChunks(FrameDef* frame_def,
|
||||
break;
|
||||
}
|
||||
case BGDynamicsChunkType::kFlagStand: {
|
||||
c.SetTexture(g_media->GetTexture(SystemTextureID::kFlagPole));
|
||||
c.SetTexture(g_assets->GetTexture(SystemTextureID::kFlagPole));
|
||||
c.SetReflection(ReflectionType::kSharp);
|
||||
c.SetColor(0.9f, 0.6f, 0.3f, 1.0f);
|
||||
break;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user