added soft_default functionality to dataclassio

This commit is contained in:
Eric Froemling 2022-04-21 17:54:36 -07:00
parent 7677658104
commit 9529c7cf32
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
21 changed files with 293 additions and 97 deletions

View File

@ -3971,50 +3971,50 @@
"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/fd/f8/10dab633b840e11d48028ece0e94",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/95/5c/25082f7cccc42c15e5b83c75c475",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5e/97/9e0e1c1dc834ad181859b0ee0b78",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/b2/1c0acb568e9c59ac9fd5874cae5f",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0b/18/2bc39720f1316779415cc94cb113",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/a7/6a840428e14ef51bcd0df363a434",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c2/41/0c32e18e1e70a972a1115e92e186",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/47/64/7ccc6f00b6956c1a7432432549bd",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/c9/4f/5440667c1b6fea19ae0de266bfd8",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/32/f0/239dbf6e7dd3cd3db7486fde7407",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/98/72/6c901ee766aebf76fb80eae90589",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/db/1e/6774a41b43542afc038908d8e89b",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/df/d2/1fd51009e9fb22045c2a583cd64a",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fd/81/3fc11ac92e6ebcec071c7f93ffe7",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/33/7b/20b1def5897ee9f60817b75cb51f",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/51/13/b66b6692b578e3c1b7a253ac764e",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/06/e4/45df563117d8cc07f606d3df504f",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/cf/d4/885ba111bb2b13084cf31f64cede",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/20/2d/3c0bc587aea1bd0e04702bfe2291",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/19/25/9ae33702dec28a19114b023f9dd5",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c2/86/37c7b19623c5f72eb4223f1fa6a2",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f2/ee/e42d3fe7a0d2ad6a4395c6b5fd1f",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/4a/439e5c93cf7fdf31893dcc1cfaa3",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/cf/4e/a1085b9060bb4c7ee260bcd3291c",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/84/42/59f61b5645662d30c1ad2c6410b9",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3d/f8/9298792aa9378a520596bba6a388",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/bb/cae4aa7229c869262db19e9dcdd8",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5a/de/1e35235ed2b1279fd95b845ed04d",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/53/05/e570e9edd509552a3d2028ab099d",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/e9/9a956250851d65a3602c20ae990a",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/09/1c/d3536f33192842c6b30b06771611",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0c/4a/77171c3984442e73727bbf47ddec",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a1/a7/25adabdaa21491cd25ef28a4f846",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ba/0f/eaee0823fe7a1f299e3a19578451",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/66/fe/17320024436fd49b4d8886075fc9",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/77/17075093fd218bd46e6dad294f3f",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/f3/f3/a31d843c10f30086f84368376b35",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c9/e9/221a9f0d18117353851624446b32",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/c3/54/0de51809c3a7edf28c38dd144a10",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/03/4d/76acfd2bcd4c0c94a85e450bc3d3",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/a4/94/76a46fa659db22ca2155e1b423a9",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/60/a3/5e7fe045108577d6c17076838c99",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/9d/5d/7d24ce4b8cccfca69c593ff59bfe",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/c9/4c/751c6d0ea202603d20385aaa1d94",
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/3a/d3/38075453348d9d2abd102554a937",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/1c/1cd7a078b292c0d01d634f97f222",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fa/20/4f69c5c8a3e9bf9afabff8a7118f",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3a/3a/d23f5fabe309b6e8694aff471b9b",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/6f/12942dd120a3ec0963249b596989",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/90/3b11a947cd2befe576c12dc58a9c",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/77/77/2c01655f3144cd40c9ee252c7226",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f2/62/a0ba340093f8c143ab39149244e9",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/67/a9/4b48db661bc7b1f6338ee0389e87",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/8e/44/c087c45ca09e5a8e4284076d4663",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/ee/452c5c9164807e82d97214f7fc5b",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7a/f0/2a4003966c6e7ec531bcfb19f013",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ec/be/637f05ea13de731126047d88a6c2",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/c6/2503d6a33f1a86d3504732091540",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/26/14/ba5b7d47bec90c93af50fe344a1e",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/79/e08d502d6b980db9c9506b6614ca",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/62/a7/c88cf55d6242a7b28467b193cb7f",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/36/7e/6f55132fea94bbca6b41cc764a28",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/f4/4a/a7aa2270ca1bd8cc15cb5204d089",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/86/df/dd3bef3462b735d85243e24540f9",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f9/81/e339e45d6c650df8217acbfb5f29",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/de/d8/ce0ae67d8fa1bc4afb931c2e8a0f",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/0a/4907ea64f8492164a84ab9503aaf",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/48/b4/8ed406ae6ff13da64c7ec97b6f56",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/63/60/190e42f26c0f1224c2ffa69e3992",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/61/a4936fb9455dcd014a1eb5e570f1",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/29/75/b61dae6070661f68ddb54cf14ee4",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2f/31/1373c730b4e06c515a439b2e15d9",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7e/f2/567e3019d15c23424bd9c8562679",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b2/43/4c8e335e4771c9bbc01737ca8ca8",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0b/4c/6d68b4f4b2e10597ca74dff0b0cb",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1d/c1/f566397ffc7d5c943b32c6508479",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4d/07/d0ed02b5363672e0e1039567ce60",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8f/fc/e9c87d067c8511b8183f09dcd05d",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f7/e0/94da6e5b577853226c1ca81978de",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1b/06/983ab3446f2bf0b31a0d8c93322b",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/1c/dd/cf46a040f49e72b0693f10f72ca6",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/1b/f9/c5b6eeb4493d4a8acba006bc4293",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/cc/d1/e7965899f642259e45adc059b629",
"build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/09/67/573507643fe3790b9f19ec707be0",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/1a/d0/a33a7402cdf38076ac726f155fcf",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/81/fb/68aaa7cb8fad0a49c6a9b47590b5",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/7f/83/62496b38a9828d6ed21d41a636ea",
"build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/89/1a/9d4b19c0c6fa33db78e75376c7e8",
"src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/b3/15/7c6d580b3482870b5b058858624c",
"src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/d3/db/e73d4dcf1280d5f677c3cf8b47c3"
}

View File

@ -81,6 +81,7 @@
<w>anyofallof</w>
<w>anyval</w>
<w>aosp</w>
<w>aparsed</w>
<w>apichanges</w>
<w>apis</w>
<w>apks</w>
@ -217,6 +218,7 @@
<w>bdir</w>
<w>belarussian</w>
<w>benboncan</w>
<w>benning</w>
<w>bfiledir</w>
<w>bfiles</w>
<w>bgmodel</w>
@ -847,6 +849,7 @@
<w>flav</w>
<w>fldtypes</w>
<w>flines</w>
<w>floinkdingle</w>
<w>floof</w>
<w>floofcls</w>
<w>floop</w>
@ -950,6 +953,7 @@
<w>gametypes</w>
<w>gameutils</w>
<w>gbytecount</w>
<w>gcwe</w>
<w>gearvr</w>
<w>genchangelog</w>
<w>gencmd</w>
@ -1383,6 +1387,7 @@
<w>ltypes</w>
<w>lubyte</w>
<w>luuid</w>
<w>lval</w>
<w>lzma</w>
<w>lzmamodule</w>
<w>macappstore</w>
@ -1648,6 +1653,7 @@
<w>ogval</w>
<w>oival</w>
<w>okbtn</w>
<w>oldbook</w>
<w>oldlady</w>
<w>onln</w>
<w>onscreencountdown</w>
@ -1818,6 +1824,7 @@
<w>prch</w>
<w>prec</w>
<w>precommand</w>
<w>precompiling</w>
<w>preconfig</w>
<w>preexec</w>
<w>prefablib</w>
@ -1877,6 +1884,7 @@
<w>ptrans</w>
<w>ptype</w>
<w>ptypename</w>
<w>pubdeviceid</w>
<w>publictab</w>
<w>pubsync</w>
<w>pubtargets</w>

View File

@ -1,4 +1,4 @@
### 1.6.12 (20556, 2022-04-19)
### 1.6.12 (20561, 2022-04-21)
- More internal work on V2 master-server communication
### 1.6.11 (20539, 2022-03-23)

View File

@ -695,6 +695,11 @@ test-message:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \
tests/test_efro/test_message.py
# Individual test with extra output enabled.
test-dataclassio:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \
tests/test_efro/test_dataclassio.py
# Individual test with extra output enabled.
test-rpc:
@tools/pcommand pytest -o log_cli=true -o log_cli_level=debug -s -vv \

View File

@ -53,6 +53,7 @@
<w>anyofallof</w>
<w>anyval</w>
<w>aosp</w>
<w>aparsed</w>
<w>apientry</w>
<w>apost</w>
<w>appconfig</w>
@ -104,6 +105,7 @@
<w>bbbbbbb</w>
<w>bcfn</w>
<w>bdea</w>
<w>benning</w>
<w>bezanson</w>
<w>bgra</w>
<w>bigendian</w>
@ -418,6 +420,7 @@
<w>fjco</w>
<w>fjcoiwef</w>
<w>flipbit</w>
<w>floinkdingle</w>
<w>floop</w>
<w>flopsy</w>
<w>fname</w>
@ -462,6 +465,7 @@
<w>gasmsg</w>
<w>gbus</w>
<w>gcc's</w>
<w>gcwe</w>
<w>gearvr</w>
<w>genchangelog</w>
<w>gencmd</w>
@ -668,6 +672,7 @@
<w>ltypes</w>
<w>lubyte</w>
<w>luuid</w>
<w>lval</w>
<w>lvec</w>
<w>lvoid</w>
<w>macbuild</w>
@ -821,6 +826,7 @@
<w>offsy</w>
<w>oiffsss</w>
<w>okbtn</w>
<w>oldbook</w>
<w>oldname</w>
<w>oooo</w>
<w>ooooooo</w>
@ -896,6 +902,7 @@
<w>ppre</w>
<w>pptabcom</w>
<w>precalc</w>
<w>precompiling</w>
<w>preconfig</w>
<w>predeclare</w>
<w>prefs</w>
@ -926,6 +933,7 @@
<w>ptrs</w>
<w>ptype</w>
<w>ptypename</w>
<w>pubdeviceid</w>
<w>publictab</w>
<w>pubtargets</w>
<w>pulseaudio</w>

View File

@ -10,8 +10,11 @@
<option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err52-cpp,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof,-misc-no-recursion" />
<option name="preferClangTidyFilesOverIDESettings" value="false" />
</inspection_tool>
<inspection_tool class="ConstantConditionsOC" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstantFunctionResult" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstructionIsNotAllowed" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateSwitchCase" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EndlessLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GrazieInspection" enabled="false" level="TYPO" enabled_by_default="false" />
<inspection_tool class="HttpUrlsUsage" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredUrls">
@ -93,6 +96,8 @@
<option name="enableSimplifyTernaryWithConstantBranch" value="false" />
</inspection_tool>
<inspection_tool class="StaticnessMismatch" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="UnreachableCallsOfFunction" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnreachableCode" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedExpressionResult" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedGlobalDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedLocalVariable" enabled="false" level="WARNING" enabled_by_default="false" />

View File

@ -21,7 +21,7 @@
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kAppBuildNumber = 20556;
const int kAppBuildNumber = 20561;
const char* kAppVersion = "1.6.12";
// Our standalone globals.

View File

@ -5,6 +5,7 @@
#include "ballistica/ballistica.h"
#include "ballistica/dynamics/material/material_action.h"
#include "ballistica/media/component/sound.h"
namespace ballistica {

View File

@ -89,7 +89,9 @@ void TestInput::Process(millisecs_t time) {
HandleAlreadyPressedTwice();
} else {
jump_pressed_ = !jump_pressed_;
if (jump_pressed_) join_press_count_++;
if (jump_pressed_) {
join_press_count_++;
}
e.type = jump_pressed_ ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
e.jbutton.button = 0;
g_input->PushJoystickEvent(e, joystick_);
@ -121,7 +123,9 @@ void TestInput::Process(millisecs_t time) {
HandleAlreadyPressedTwice();
} else {
pickup_pressed_ = !pickup_pressed_;
if (pickup_pressed_) join_press_count_++;
if (pickup_pressed_) {
join_press_count_++;
}
e.type = pickup_pressed_ ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
e.jbutton.button = 3;
g_input->PushJoystickEvent(e, joystick_);
@ -133,7 +137,9 @@ void TestInput::Process(millisecs_t time) {
HandleAlreadyPressedTwice();
} else {
punch_pressed_ = !punch_pressed_;
if (punch_pressed_) join_press_count_++;
if (punch_pressed_) {
join_press_count_++;
}
e.type = punch_pressed_ ? SDL_JOYBUTTONDOWN : SDL_JOYBUTTONUP;
e.jbutton.button = 1;
g_input->PushJoystickEvent(e, joystick_);

View File

@ -77,7 +77,7 @@ class PlatformApple : public Platform {
auto DoClipboardHasText() -> bool override;
auto DoClipboardSetText(const std::string& text) -> void override;
auto DoClipboardGetText() -> std::string override;
auto GetPublicDeviceUUIDInputs() -> std::list<std::string> override;
auto GetDeviceUUIDInputs() -> std::list<std::string> override;
private:
};

View File

@ -29,7 +29,7 @@ std::string PlatformLinux::GenerateUUID() {
return val;
}
auto PlatformLinux::GetPublicDeviceUUIDInputs() -> std::list<std::string> {
auto PlatformLinux::GetDeviceUUIDInputs() -> std::list<std::string> {
std::list<std::string> out;
// For now let's just go with machine-id.

View File

@ -21,7 +21,7 @@ class PlatformLinux : public Platform {
auto OpenDirExternally(const std::string& path) -> void override;
auto GetPlatformName() -> std::string override;
auto GetSubplatformName() -> std::string override;
auto GetPublicDeviceUUIDInputs() -> std::list<std::string> override;
auto GetDeviceUUIDInputs() -> std::list<std::string> override;
};
} // namespace ballistica

View File

@ -184,17 +184,13 @@ auto Platform::GenerateUUID() -> std::string {
auto Platform::GetPublicDeviceUUID() -> std::string {
assert(g_python);
if (public_device_uuid_.empty()) {
std::list<std::string> inputs{GetPublicDeviceUUIDInputs()};
std::list<std::string> inputs{GetDeviceUUIDInputs()};
// This UUID is supposed to change periodically, so let's plug in
// some stuff to enforce that.
inputs.emplace_back(GetOSVersionString());
inputs.emplace_back(kAppVersion);
inputs.emplace_back("kerploople");
// int i{};
// for (auto&& input : inputs) {
// printf("INPUT %d IS %s\n", i + 1, input.c_str());
// }
auto gil{Python::ScopedInterpreterLock()};
auto pylist{g_python->StringList(inputs)};
auto args{g_python->SingleMemberTuple(pylist)};
@ -205,8 +201,8 @@ auto Platform::GetPublicDeviceUUID() -> std::string {
return public_device_uuid_;
}
auto Platform::GetPublicDeviceUUIDInputs() -> std::list<std::string> {
throw Exception("GetPublicDeviceUUIDInputs unimplemented");
auto Platform::GetDeviceUUIDInputs() -> std::list<std::string> {
throw Exception("GetDeviceUUIDInputs unimplemented");
}
auto Platform::GetDefaultConfigDir() -> std::string {
@ -860,7 +856,7 @@ auto Platform::GetUserAgentString() -> std::string {
+ "; " + GetLocale() + ")"};
// This gets shipped to various places which might choke on fancy unicode
// characers, so let's limit to simple ascii.
// characters, so let's limit to simple ascii.
out = Utils::StripNonAsciiFromUTF8(out);
return out;

View File

@ -186,13 +186,12 @@ class Platform {
/// server bans or spam prevention.
auto GetPublicDeviceUUID() -> std::string;
/// Return values which will be hashed to create a public device uuid.
/// These values may include things that may change periodically such
/// as minor os version numbers, but they should not include things
/// that change constantly or that can be changed easily by the user.
/// Only hashed versions of these values should ever be shared beyond
/// the local device.
virtual auto GetPublicDeviceUUIDInputs() -> std::list<std::string>;
/// Return values which can be hashed to create a public device uuid.
/// Ideally these values should come from an OS-provided guid. They
/// should not include anything that is easily user-changeable.
/// IMPORTANT: Only hashed/transformed versions of these values should
/// ever be shared beyond the local device.
virtual auto GetDeviceUUIDInputs() -> std::list<std::string>;
/// Return whether there is an actual legacy-device-uuid value for
/// this platform, and also return it if so.

View File

@ -127,7 +127,7 @@ void PlatformWindows::SetupInterruptHandling() {
}
}
auto PlatformWindows::GetPublicDeviceUUIDInputs() -> std::list<std::string> {
auto PlatformWindows::GetDeviceUUIDInputs() -> std::list<std::string> {
std::list<std::string> out;
std::string ret;

View File

@ -16,7 +16,7 @@ class PlatformWindows : public Platform {
PlatformWindows();
void SetupInterruptHandling() override;
auto GetDeviceAccountUUIDPrefix() -> std::string override { return "w"; }
auto GetPublicDeviceUUIDInputs() -> std::list<std::string> override;
auto GetDeviceUUIDInputs() -> std::list<std::string> override;
auto GenerateUUID() -> std::string override;
auto GetDefaultConfigDir() -> std::string override;
auto Remove(const char* path) -> int;

View File

@ -873,3 +873,84 @@ def test_extended_data() -> None:
# Uses our output filter.
assert dataclass_to_dict(_TestClass2(vals=(1, 2))) == {'vals': [0, 0]}
def test_soft_default() -> None:
"""Test soft_default IOAttr value."""
# Try both of these with and without storage_name to make sure
# soft_default interacts correctly with both cases.
@ioprepped
@dataclass
class _TestClassA:
ival: int
@ioprepped
@dataclass
class _TestClassA2:
ival: Annotated[int, IOAttrs('i')]
@ioprepped
@dataclass
class _TestClassB:
ival: Annotated[int, IOAttrs(soft_default=0)]
@ioprepped
@dataclass
class _TestClassB2:
ival: Annotated[int, IOAttrs('i', soft_default=0)]
@ioprepped
@dataclass
class _TestClassB3:
ival: Annotated[int, IOAttrs('i', soft_default_factory=lambda: 0)]
# These should fail because there's no value for ival.
with pytest.raises(ValueError):
dataclass_from_dict(_TestClassA, {})
with pytest.raises(ValueError):
dataclass_from_dict(_TestClassA2, {})
# These should succeed because it has a soft-default value to
# fall back on.
dataclass_from_dict(_TestClassB, {})
dataclass_from_dict(_TestClassB2, {})
dataclass_from_dict(_TestClassB3, {})
# soft_default should also allow using store_default=False without
# requiring the dataclass to contain a default or default_factory
@ioprepped
@dataclass
class _TestClassC:
ival: Annotated[int, IOAttrs(store_default=False)] = 0
assert dataclass_to_dict(_TestClassC()) == {}
# This should fail since store_default would be meaningless without
# any source for the default value.
with pytest.raises(TypeError):
@ioprepped
@dataclass
class _TestClassC2:
ival: Annotated[int, IOAttrs(store_default=False)]
# However with our shiny soft_default it should work.
@ioprepped
@dataclass
class _TestClassC3:
ival: Annotated[int, IOAttrs(store_default=False, soft_default=0)]
assert dataclass_to_dict(_TestClassC3(0)) == {}
# we should disallow passing a few mutable types as soft_defaults
# just as dataclass does with regular defaults.
with pytest.raises(TypeError):
@ioprepped
@dataclass
class _TestClassD:
lval: Annotated[list, IOAttrs(soft_default=[])]

View File

@ -13,7 +13,7 @@ from typing import TYPE_CHECKING, get_args
from typing import _AnnotatedAlias # type: ignore
if TYPE_CHECKING:
from typing import Any, Optional
from typing import Any, Optional, Callable, Union
# Types which we can pass through as-is.
SIMPLE_TYPES = {int, bool, str, float, type(None)}
@ -96,18 +96,50 @@ def _is_valid_for_codec(obj: Any, codec: Codec) -> bool:
class IOAttrs:
"""For specifying io behavior in annotations."""
"""For specifying io behavior in annotations.
'storagename', if passed, is the name used when storing to json/etc.
'store_default' can be set to False to avoid writing values when equal
to the default value. Note that this requires the dataclass field
to define a default or default_factory or for its IOAttrs to
define a soft_default value.
'whole_days', if True, requires datetime values to be exactly on day
boundaries (see efro.util.utc_today()).
'whole_hours', if True, requires datetime values to lie exactly on hour
boundaries (see efro.util.utc_this_hour()).
'soft_default', if passed, is used as a default for loading and storing
purposes, but leaves the dataclass itself expecting a value to
be passed in all constructor calls/etc. This is useful when fields
are added that should not be considered optional in new code but for
which there may exist old data that does not contain those values.
'soft_default_factory' should be given instead of 'soft_default' for
mutable types such as lists (to prevent the default from changing
over time).
"""
# A sentinel object to detect if a parameter is supplied or not. Use
# a class to give it a better repr.
class _MissingType:
pass
MISSING = _MissingType()
storagename: Optional[str] = None
store_default: bool = True
whole_days: bool = False
whole_hours: bool = False
soft_default: Any = MISSING
soft_default_factory: Union[Callable[[], Any], _MissingType] = MISSING
def __init__(self,
storagename: Optional[str] = storagename,
store_default: bool = store_default,
whole_days: bool = whole_days,
whole_hours: bool = whole_hours):
def __init__(
self,
storagename: Optional[str] = storagename,
store_default: bool = store_default,
whole_days: bool = whole_days,
whole_hours: bool = whole_hours,
soft_default: Any = MISSING,
soft_default_factory: Union[Callable[[], Any], _MissingType] = MISSING,
):
# Only store values that differ from class defaults to keep
# our instances nice and lean.
@ -120,18 +152,34 @@ class IOAttrs:
self.whole_days = whole_days
if whole_hours != cls.whole_hours:
self.whole_hours = whole_hours
if soft_default is not cls.soft_default:
# Do what dataclasses does with its default types and
# tell the user to use factory for mutable ones.
if isinstance(soft_default, (list, dict, set)):
raise ValueError(
f'mutable {type(soft_default)} is not allowed'
f' for soft_default; use soft_default_factory.')
self.soft_default = soft_default
if soft_default_factory is not cls.soft_default_factory:
self.soft_default_factory = soft_default_factory
def validate_for_field(self, cls: type, field: dataclasses.Field) -> None:
"""Ensure the IOAttrs instance is ok to use with the provided field."""
# Turning off store_default requires the field to have either
# a default_factory or a default
# a default or a a default_factory or for us to have soft equivalents.
if not self.store_default:
default_factory: Any = field.default_factory
if (default_factory is dataclasses.MISSING
and field.default is dataclasses.MISSING):
field_default_factory: Any = field.default_factory
if (field_default_factory is dataclasses.MISSING
and field.default is dataclasses.MISSING
and self.soft_default is self.MISSING
and self.soft_default_factory is self.MISSING):
raise TypeError(f'Field {field.name} of {cls} has'
f' neither a default nor a default_factory;'
f' neither a default nor a default_factory'
f' and IOAttrs contains neither a soft_default'
f' nor a soft_default_factory;'
f' store_default=False cannot be set for it.')
def validate_datetime(self, value: datetime.datetime,

View File

@ -158,6 +158,7 @@ class _Inputter(Generic[T]):
associated values, and nested dataclasses should be passed as dicts.
"""
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
if not isinstance(values, dict):
raise TypeError(
f'Expected a dict for {fieldpath} on {cls.__name__};'
@ -172,6 +173,16 @@ class _Inputter(Generic[T]):
# noinspection PyDataclass
fields = dataclasses.fields(cls)
fields_by_name = {f.name: f for f in fields}
# Preprocess all fields to convert Annotated[] to contained types
# and IOAttrs.
parsed_field_annotations = {
f.name: _parse_annotated(prep.annotations[f.name])
for f in fields
}
# Go through all data in the input, converting it to either dataclass
# args or extra data.
args: dict[str, Any] = {}
for rawkey, value in values.items():
key = prep.storage_names_to_attr_names.get(rawkey, rawkey)
@ -197,18 +208,32 @@ class _Inputter(Generic[T]):
f"'{cls.__name__}' has no '{key}' field.")
else:
fieldname = field.name
anntype = prep.annotations[fieldname]
anntype, ioattrs = _parse_annotated(anntype)
anntype, ioattrs = parsed_field_annotations[fieldname]
subfieldpath = (f'{fieldpath}.{fieldname}'
if fieldpath else fieldname)
args[key] = self._value_from_input(cls, subfieldpath, anntype,
value, ioattrs)
# Go through all fields looking for any not yet present in our data.
# If we find any such fields with a soft-default value or factory
# defined, inject that value into our args.
for key, aparsed in parsed_field_annotations.items():
if key not in args:
ioattrs = aparsed[1]
if (ioattrs is not None and
(ioattrs.soft_default is not ioattrs.MISSING
or ioattrs.soft_default_factory is not ioattrs.MISSING)):
if ioattrs.soft_default is not ioattrs.MISSING:
args[key] = ioattrs.soft_default
else:
assert callable(ioattrs.soft_default_factory)
args[key] = ioattrs.soft_default_factory()
try:
out = cls(**args)
except Exception as exc:
raise RuntimeError(f'Error instantiating class {cls.__name__}'
f' at {fieldpath}: {exc}') from exc
raise ValueError(f'Error instantiating class {cls.__name__}'
f' at {fieldpath}: {exc}') from exc
if extra_attrs:
setattr(out, EXTRA_ATTRS_ATTR, extra_attrs)
return out

View File

@ -68,18 +68,25 @@ class _Outputter:
# we can skip all output processing if we've got a default value.
if ioattrs is not None and not ioattrs.store_default:
default_factory: Any = field.default_factory
if default_factory is not dataclasses.MISSING:
if field.default is not dataclasses.MISSING:
if field.default == value:
continue
elif default_factory is not dataclasses.MISSING:
if default_factory() == value:
continue
elif field.default is not dataclasses.MISSING:
if field.default == value:
elif ioattrs.soft_default is not ioattrs.MISSING:
if ioattrs.soft_default == value:
continue
elif ioattrs.soft_default_factory is not ioattrs.MISSING:
assert callable(ioattrs.soft_default_factory)
if ioattrs.soft_default_factory() == value:
continue
else:
raise RuntimeError(
f'Field {fieldname} of {cls.__name__} has'
f' neither a default nor a default_factory;'
f' store_default=False cannot be set for it.'
f' (AND THIS SHOULD HAVE BEEN CAUGHT IN PREP!)')
f' no source of default values; store_default=False'
f' cannot be set for it. (AND THIS SHOULD HAVE BEEN'
f' CAUGHT IN PREP!)')
outvalue = self._process_value(cls, subfieldpath, anntype, value,
ioattrs)

View File

@ -316,10 +316,6 @@ class RPCEndpoint:
self._debug_print_call(
f'{self._label}: tasks finished; waiting for writer close...')
# At this point we shouldn't touch our tasks anymore.
# Clearing them out allows us to go down
# del self._tasks
# Now wait for our writer to finish going down.
# When we close our writer it generally triggers errors
# in our current blocked read/writes. However that same
@ -328,7 +324,18 @@ class RPCEndpoint:
# So let's silently ignore it when that happens.
assert self._writer.is_closing()
try:
await self._writer.wait_closed()
# It seems that as of Python 3.9.x it is possible for this to hang
# indefinitely. See https://github.com/python/cpython/issues/83939
# It sounds like this should be fixed in 3.11 but for now just
# forcing the issue with a timeout here.
await asyncio.wait_for(self._writer.wait_closed(), timeout=10.0)
except asyncio.TimeoutError:
logging.info('Timeout on _writer.wait_closed() for %s.',
self._label)
if self._debug_print:
self._debug_print_call(
f'{self._label}: got timeout in _writer.wait_closed();'
' This should be fixed in future Python versions.')
except Exception as exc:
if not self._is_expected_connection_error(exc):
logging.exception('Error closing _writer for %s.', self._label)