From d35f479f825bc0a2bc96a2e8cfe68541f541f569 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 27 Oct 2023 18:54:35 -0700 Subject: [PATCH] language updates, dev-console polishing, internal time format cleanup --- .efrocachemap | 94 +++++++++---------- CHANGELOG.md | 12 ++- ballisticakit-cmake/CMakeLists.txt | 1 + .../Generic/BallisticaKitGeneric.vcxproj | 1 + .../BallisticaKitGeneric.vcxproj.filters | 3 + .../Headless/BallisticaKitHeadless.vcxproj | 1 + .../BallisticaKitHeadless.vcxproj.filters | 3 + src/assets/ba_data/python/baenv.py | 2 +- src/ballistica/base/assets/assets_server.cc | 4 +- src/ballistica/base/audio/audio_server.cc | 6 +- src/ballistica/base/base.h | 1 + .../base/graphics/support/camera.cc | 44 ++++----- src/ballistica/base/graphics/support/camera.h | 70 +++++++------- src/ballistica/base/input/input.cc | 6 +- src/ballistica/base/logic/logic.cc | 29 +++--- src/ballistica/base/logic/logic.h | 10 +- .../python/class/python_class_app_timer.cc | 2 +- .../class/python_class_display_timer.cc | 2 +- .../base/python/methods/python_methods_app.cc | 4 +- src/ballistica/base/support/app_timer.h | 7 +- src/ballistica/base/support/display_timer.h | 42 +++++++++ src/ballistica/base/support/repeater.cc | 12 +-- src/ballistica/base/support/repeater.h | 3 +- src/ballistica/base/ui/dev_console.cc | 64 +++++++++++-- src/ballistica/shared/ballistica.cc | 2 +- .../shared/foundation/event_loop.cc | 24 +++-- src/ballistica/shared/foundation/event_loop.h | 33 +++---- 27 files changed, 293 insertions(+), 189 deletions(-) create mode 100644 src/ballistica/base/support/display_timer.h diff --git a/.efrocachemap b/.efrocachemap index 95a2a68d8..3dcc07aed 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -421,7 +421,7 @@ "build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26", "build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8", "build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55", - "build/assets/ba_data/data/langdata.json": "d53c301a74d3b116b00f6abf5a53b16f", + "build/assets/ba_data/data/langdata.json": "b2fbc1751bd168470392de5370c196f4", "build/assets/ba_data/data/languages/arabic.json": "c21378ee214a9dd0cb2971cd46b74374", "build/assets/ba_data/data/languages/belarussian.json": "4d89ed5f9c615771d4fa2bb1834942d3", "build/assets/ba_data/data/languages/chinese.json": "0a9d9534e7329d1e886adae6fdc007c4", @@ -447,10 +447,10 @@ "build/assets/ba_data/data/languages/polish.json": "6677925c370390f1f53bcb737cb00fa8", "build/assets/ba_data/data/languages/portuguese.json": "51e362956f89da3eec980f587c092253", "build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826", - "build/assets/ba_data/data/languages/russian.json": "561504cca28eb3204ac194950029e565", + "build/assets/ba_data/data/languages/russian.json": "6e524210149d95479d6cbfd3506c630b", "build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69", "build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef", - "build/assets/ba_data/data/languages/spanish.json": "5a4dbd505060dd02d634bd4de4d5faab", + "build/assets/ba_data/data/languages/spanish.json": "b179da96097e2b4df9f0397da672be69", "build/assets/ba_data/data/languages/swedish.json": "77d671f10613291ebf9c71da66f18a18", "build/assets/ba_data/data/languages/tamil.json": "65ab7798d637fa62a703750179eeb723", "build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc", @@ -4056,50 +4056,50 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "637b3e06d6536db39d816e0b5820c0ab", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "e3a0ad82944e80528a227807a9a9ba6d", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "f8252819a3d84a2c3be5e3ed938e5f8b", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "7e8682e4ef71b0d432576ce8f879b3b2", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "eb3a79d46714a2585da45f66ae5352eb", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "1ebb8b160059182d79b586f40f4bb207", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "b51ff49b8e145ebee0d5a3f8c2e517fb", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "9eecb06461e9798439c4d15399b7d28a", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "7ffd1e3961eb68f820ff044f2ba62cf9", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "3ab890f1e4116739bce0e2c141440773", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "d6d47b5b7bf720c0936a53deffe07359", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "0ce0fcd7d19e767db721eb43f58424f7", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "4fac89dcba67096cd2f84f0b687b1880", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "0df3b09ffdf3dc519cea1a3a9fb959d2", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "8eb92b2fa10d56cfee3fd8da179cfda7", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "b0764a6280bfbe926b655df8f946e8e2", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "f69383ecdafab7a37907898fcbf98fa1", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "617e7ca8f4ed3d3f726ba9567a15732e", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9133fee71d08209b5ac82f772edae5c9", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "1cfd194e81bb849e337b34df43157ba8", - "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "476e9cf1fb229a023babd799a6e535f1", - "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "cf2a61fae8e8cd757864202a09e71255", - "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "476e9cf1fb229a023babd799a6e535f1", - "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "cf2a61fae8e8cd757864202a09e71255", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "b46b30262b58e96e994211631b470efb", - "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "6cc41e3401daf2e72b884fbfe0fe92b3", - "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "b46b30262b58e96e994211631b470efb", - "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "6cc41e3401daf2e72b884fbfe0fe92b3", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "b915f8a091643d99fd28e8d636063185", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "cb5de031162e4ff0cb5f030adf331a12", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "b915f8a091643d99fd28e8d636063185", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "cb5de031162e4ff0cb5f030adf331a12", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "be2a7322e1ddbb38ba0d22dd94a565e3", - "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "1920c5412307a78aa658c3366c86b7fc", - "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "b257bbc06d82fc912653806c01a42c15", - "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "1920c5412307a78aa658c3366c86b7fc", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "693493fea9a0068d67d05ac32c53d938", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "0ad9cd9671e260ea90f97a3334a063d0", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "0dc8f56e25b1bb2b67bdb6f1b65c56b6", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "02bfe33e3189d0993aff1884cae95ccf", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "7867875c532b032ace05fef64e278635", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "7dfdd479341808a7301158591caac092", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "3604c049578423bce477d0be543529f4", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "57b11043daad1545cd2abb0c13f43db7", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d81b7738fc395f6f926aabaee1920925", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "70d7de73a945afbe78f6ba94dd0fd78c", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "5ee9cf8e99fb9fbc6b80ef7fa6840be5", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "8eb65d8768f338c7188de404d584068f", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "4422950377f4194463b38533487b81df", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "3e85a676808245e0a279e2fb28fad8fc", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "50ac87225e3b4ac843d83fcec96ef542", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "ce8fedb78aac2ec288697fbace511d68", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "9db6948f77ff98d109e799d4d97266f7", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "517b1d6326879fd7ae1ad17d96e7c9ee", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "b49b73a09460467bba983c301d33feb8", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "7b4741075224986c1776bc9e538b80cc", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "f8a1e3030d6e9129f95ab5b7ea171134", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "615505f555b1ecf567ac00c1a71d4073", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "257f4ec71878b30f0a3619d8a5a278d8", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "0d4a6355de77872b17b4ed2856cfd3e3", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "e76d8896417d7c468b743f865f6d317a", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1f7b66a5c7bf998f9d59fa28ef1a2dc5", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "a537bc369c09da6384a47e878b7dd11d", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "0b34b2bdfc77cb1f8c3968c16b304307", + "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "844bab8bf2324a35e4f71510fb4065f3", + "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "0320ab824c7b9271dfdd6361dcd51d82", + "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "844bab8bf2324a35e4f71510fb4065f3", + "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "0320ab824c7b9271dfdd6361dcd51d82", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "28ec03fb21247269ea16b7dc31cc37c9", + "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "80e61c0f2a2e665eaa6260b60ca92144", + "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "28ec03fb21247269ea16b7dc31cc37c9", + "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "80e61c0f2a2e665eaa6260b60ca92144", + "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "773c691b680d407f050d11a0814048cd", + "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "22158f39a92f54838ca05f38e7f635a9", + "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "773c691b680d407f050d11a0814048cd", + "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "22158f39a92f54838ca05f38e7f635a9", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "8d88b975df7ccff1af919ea738dcbc0f", + "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "f7de016cce83b57002b87f42575c2287", + "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "054de6792232f57d2ad4a5a81e5b7e5f", + "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "f7de016cce83b57002b87f42575c2287", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "7f38979e847d5b3abef78acf83e41334", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "10ebbf27705f024b696c92db94d75506", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "287f846d6d424639348a02030f2bace9", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "0a2987deb121f5eb044c220079c17d50", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "97b59f0376cc0bff65bc8f583127e62b", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c7421859bac7d02acb487784573cffd9", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "8e70dcb1e9c6a046473d2fec13796b76", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "104baba8083e75102f81c6e1c6b552b5", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101", "src/ballistica/base/mgen/pyembed/binding_base.inc": "6df0f34207346d89a72924249ddd4706", diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6d03542..a0bab389c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.28 (build 21528, api 8, 2023-10-27) +### 1.7.28 (build 21531, api 8, 2023-10-27) - Massively cleaned up code related to rendering and window systems (OpenGL, SDL, etc). This code had been growing into a nasty tangle for 15 years @@ -192,6 +192,16 @@ technical users can still fix and restore their old configs. Note that the app still also writes .prev configs for extra security, though it no longer uses them for anything itself. +- Converted more internal engine time values from milliseconds to microseconds, + including things like the internal EventLoop timeline. Please holler if you + notice anything running 1000x too fast or slow. In general my strategy going + forward is to use microseconds for exact internal time values but to mostly + expose float seconds to the user on the Python layer. There were starting to + be a few cases were integer milliseconds was not enough precision for internal + values. For instance, if we run with unclamped framerates and hit several + hundred FPS, milliseconds per frame would drop to 0 which could cause + problems. Note that scenev1 will be remaining on milliseconds internally for + compatibility reasons. Scenev2 should move to microseconds though. ### 1.7.27 (build 21282, api 8, 2023-08-30) diff --git a/ballisticakit-cmake/CMakeLists.txt b/ballisticakit-cmake/CMakeLists.txt index 443a6adc9..c4d1ed645 100644 --- a/ballisticakit-cmake/CMakeLists.txt +++ b/ballisticakit-cmake/CMakeLists.txt @@ -441,6 +441,7 @@ set(BALLISTICA_SOURCES ${BA_SRC_ROOT}/ballistica/base/support/classic_soft.h ${BA_SRC_ROOT}/ballistica/base/support/context.cc ${BA_SRC_ROOT}/ballistica/base/support/context.h + ${BA_SRC_ROOT}/ballistica/base/support/display_timer.h ${BA_SRC_ROOT}/ballistica/base/support/huffman.cc ${BA_SRC_ROOT}/ballistica/base/support/huffman.h ${BA_SRC_ROOT}/ballistica/base/support/plus_soft.h diff --git a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj index 3a4e6a25c..fc1948781 100644 --- a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj +++ b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj @@ -433,6 +433,7 @@ + diff --git a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters index 90ed3d40e..078cbd382 100644 --- a/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters +++ b/ballisticakit-windows/Generic/BallisticaKitGeneric.vcxproj.filters @@ -733,6 +733,9 @@ ballistica\base\support + + ballistica\base\support + ballistica\base\support diff --git a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj index 7b5fa8924..b4f73ad37 100644 --- a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj +++ b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj @@ -428,6 +428,7 @@ + diff --git a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters index 90ed3d40e..078cbd382 100644 --- a/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters +++ b/ballisticakit-windows/Headless/BallisticaKitHeadless.vcxproj.filters @@ -733,6 +733,9 @@ ballistica\base\support + + ballistica\base\support + ballistica\base\support diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 553292578..1d1469c62 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21528 +TARGET_BALLISTICA_BUILD = 21531 TARGET_BALLISTICA_VERSION = '1.7.28' diff --git a/src/ballistica/base/assets/assets_server.cc b/src/ballistica/base/assets/assets_server.cc index 9c89f00e1..aaf27ba56 100644 --- a/src/ballistica/base/assets/assets_server.cc +++ b/src/ballistica/base/assets/assets_server.cc @@ -25,7 +25,7 @@ void AssetsServer::OnAppStartInThread() { // Ask our thread to give us periodic processing time (close to but // not *exactly* one second; try to avoid aliasing with similar updates). process_timer_ = event_loop()->NewTimer( - 987, true, NewLambdaRunnable([this] { Process(); }).Get()); + 987 * 1000, true, NewLambdaRunnable([this] { Process(); }).Get()); } void AssetsServer::PushPendingPreload(Object::Ref* asset_ref_ptr) { @@ -258,7 +258,7 @@ void AssetsServer::Process() { // we're writing a replay.. otherwise just sleep indefinitely. if (pending_preloads_.empty() && pending_preloads_audio_.empty()) { if (writing_replay_) { - process_timer_->SetLength(1000); + process_timer_->SetLength(1000 * 1000); } else { process_timer_->SetLength(-1); } diff --git a/src/ballistica/base/audio/audio_server.cc b/src/ballistica/base/audio/audio_server.cc index adcdee409..a7a9ad1a9 100644 --- a/src/ballistica/base/audio/audio_server.cc +++ b/src/ballistica/base/audio/audio_server.cc @@ -32,9 +32,9 @@ LPALCDEVICEPAUSESOFT alcDevicePauseSOFT; LPALCDEVICERESUMESOFT alcDeviceResumeSOFT; #endif -const int kAudioProcessIntervalNormal{500}; -const int kAudioProcessIntervalFade{50}; -const int kAudioProcessIntervalPendingLoad{1}; +const int kAudioProcessIntervalNormal{500 * 1000}; +const int kAudioProcessIntervalFade{50 * 1000}; +const int kAudioProcessIntervalPendingLoad{1 * 1000}; #if BA_DEBUG_BUILD || BA_TEST_BUILD const bool kShowInUseSounds{}; diff --git a/src/ballistica/base/base.h b/src/ballistica/base/base.h index 07ab3f2e2..f4b041011 100644 --- a/src/ballistica/base/base.h +++ b/src/ballistica/base/base.h @@ -53,6 +53,7 @@ class ClassicSoftInterface; class CollisionMeshAsset; class CollisionCache; class DevConsole; +class DisplayTimer; class Context; class ContextRef; class DataAsset; diff --git a/src/ballistica/base/graphics/support/camera.cc b/src/ballistica/base/graphics/support/camera.cc index d12ad130d..050057b13 100644 --- a/src/ballistica/base/graphics/support/camera.cc +++ b/src/ballistica/base/graphics/support/camera.cc @@ -23,8 +23,7 @@ const float kPanMax = 9.0f; const float kPanMin = -9.0f; Camera::Camera() - : last_mode_set_time_(g_core->GetAppTimeMillisecs()), - lock_panning_(g_core->IsVRMode()), + : lock_panning_(g_core->IsVRMode()), pan_speed_scale_(g_core->IsVRMode() ? 0.3f : 1.0f) {} Camera::~Camera() = default; @@ -607,7 +606,8 @@ void Camera::Update(millisecs_t elapsed) { float damping = 0.006f; float damping2 = 0.006f; float xy_blend_speed = 0.0002f; - millisecs_t real_time = g_core->GetAppTimeMillisecs(); + time_ += elapsed; + // millisecs_t real_time = g_core->GetAppTimeMillisecs(); // Prevent camera "explosions" if we've been unable to update for a while. elapsed = std::min(millisecs_t{100}, elapsed); @@ -653,18 +653,18 @@ void Camera::Update(millisecs_t elapsed) { } if (!g_core->IsVRMode()) { - smooth_speed_.x += elapsedf * rand_component - * (-0.5f - + Utils::precalc_rand_1((real_time / rand_incr_1) - % kPrecalcRandsCount)); - smooth_speed_.y += elapsedf * rand_component - * (-0.5f - + Utils::precalc_rand_2((real_time / rand_incr_2) - % kPrecalcRandsCount)); - smooth_speed_.z += elapsedf * rand_component - * (-0.5f - + Utils::precalc_rand_3((real_time / rand_incr_3) - % kPrecalcRandsCount)); + smooth_speed_.x += + elapsedf * rand_component + * (-0.5f + + Utils::precalc_rand_1((time_ / rand_incr_1) % kPrecalcRandsCount)); + smooth_speed_.y += + elapsedf * rand_component + * (-0.5f + + Utils::precalc_rand_2((time_ / rand_incr_2) % kPrecalcRandsCount)); + smooth_speed_.z += + elapsedf * rand_component + * (-0.5f + + Utils::precalc_rand_3((time_ / rand_incr_3) % kPrecalcRandsCount)); } if (RandomFloat() < 0.1f && !g_core->IsVRMode()) { @@ -714,15 +714,14 @@ void Camera::Update(millisecs_t elapsed) { shake_vel_.x += 0.05f * shake_amount_ * (0.5f - - Utils::precalc_rand_1(real_time % 122 * i % kPrecalcRandsCount)); + - Utils::precalc_rand_1(time_ % 122 * i % kPrecalcRandsCount)); shake_vel_.y += 0.05f * shake_amount_ * (0.5f - - Utils::precalc_rand_2(real_time % 323 * i % kPrecalcRandsCount)); + - Utils::precalc_rand_2(time_ % 323 * i % kPrecalcRandsCount)); shake_vel_.z += 0.05f * shake_amount_ - * (0.5f - - Utils::precalc_rand_3(real_time % 76 * i % kPrecalcRandsCount)); + * (0.5f - Utils::precalc_rand_3(time_ % 76 * i % kPrecalcRandsCount)); } for (int j = 0; j < iterations; j++) { @@ -740,8 +739,8 @@ void Camera::Update(millisecs_t elapsed) { uint32_t interval = g_core->IsVRMode() ? 50 : 100; // Occasionally, update microphone position for audio. - if (real_time - last_listener_update_time_ > interval) { - last_listener_update_time_ = real_time; + if (time_ - last_listener_update_time_ > interval) { + last_listener_update_time_ = time_; bool do_regular_update = true; if (g_core->IsVRMode()) { #if BA_VR_MODE @@ -891,7 +890,8 @@ void Camera::SetMode(CameraMode m) { if (mode_ != m) { mode_ = m; smooth_next_frame_ = false; - last_mode_set_time_ = g_core->GetAppTimeMillisecs(); + // last_mode_set_time_ = g_core->GetAppTimeMillisecs(); + // last_mode_set_time_ = time_; heading_ = kInitialHeading; } } diff --git a/src/ballistica/base/graphics/support/camera.h b/src/ballistica/base/graphics/support/camera.h index 7b13bb4ce..f6fe6504d 100644 --- a/src/ballistica/base/graphics/support/camera.h +++ b/src/ballistica/base/graphics/support/camera.h @@ -92,59 +92,61 @@ class Camera : public Object { void set_pan_speed_scale(float val) { pan_speed_scale_ = val; } private: - float pan_speed_scale_{1.0f}; - bool lock_panning_{}; - Vector3f vr_offset_{0.0f, 0.0f, 0.0f}; - Vector3f vr_extra_offset_{0.0f, 0.0f, 0.0f}; - Vector3f vr_offset_smooth_{0.0f, 0.0f, 0.0f}; - millisecs_t last_mode_set_time_{}; - std::list areas_of_interest_; CameraMode mode_{CameraMode::kFollow}; - bool manual_{}; - bool smooth_next_frame_{}; - bool have_real_areas_of_interest_{}; + bool manual_ : 1 {}; + bool smooth_next_frame_ : 1 {}; + bool have_real_areas_of_interest_ : 1 {}; + bool lock_panning_ : 1 {}; // Manual stuff. - bool panning_{}; - bool orbiting_{}; - bool rolling_{}; - bool trucking_{}; - bool alt_down_{}; - bool cmd_down_{}; - bool ctrl_down_{}; - bool mouse_left_down_{}; - bool mouse_middle_down_{}; - bool mouse_right_down_{}; + bool panning_ : 1 {}; + bool orbiting_ : 1 {}; + bool rolling_ : 1 {}; + bool trucking_ : 1 {}; + bool alt_down_ : 1 {}; + bool cmd_down_ : 1 {}; + bool ctrl_down_ : 1 {}; + bool mouse_left_down_ : 1 {}; + bool mouse_middle_down_ : 1 {}; + bool mouse_right_down_ : 1 {}; + + bool happy_thoughts_mode_ : 1 {}; + bool x_constrained_ : 1 {true}; + float pan_speed_scale_{1.0f}; float heading_{kInitialHeading}; - Vector3f extra_pos_{0.0f, 0.0f, 0.0f}; - Vector3f extra_pos_2_{0.0f, 0.0f, 0.0f}; float area_of_interest_bounds_[6]{-9999, -9999, -9999, 9999, 9999, 9999}; float pan_pos_{}; float pan_speed_{}; float pan_target_{}; float shake_amount_{}; - Vector3f shake_pos_{0.0f, 0.0f, 0.0f}; - Vector3f shake_vel_{0.0f, 0.0f, 0.0f}; - Vector3f position_{0.0f, 1.0f, -1.0f}; - Vector3f target_{0.0f, 1.0f, -1.0f}; - Vector3f target_smoothed_{0.0f, 0.0f, 0.0f}; - Vector3f position_offset_smoothed_{0.0f, 0.0f, 0.0f}; - Vector3f smooth_speed_{0.0f, 0.0f, 0.0f}; - Vector3f smooth_speed_2_{0.0f, 0.0f, 0.0f}; float target_radius_{2.0f}; float target_radius_smoothed_{2.0f}; float field_of_view_x_{5.0f}; float field_of_view_y_{kCameraFOVY}; float field_of_view_x_smoothed_{1.0f}; float field_of_view_y_smoothed_{1.0f}; - millisecs_t last_listener_update_time_{}; - bool happy_thoughts_mode_{}; float min_target_radius_{5.0f}; - Vector3f up_{0.0f, 1.0f, 0.0f}; float area_of_interest_near_{1.0f}; float area_of_interest_far_{2.0f}; - bool x_constrained_{true}; float xy_constrain_blend_{0.5f}; + // millisecs_t last_mode_set_time_{}; + millisecs_t last_listener_update_time_{}; + millisecs_t time_{}; + Vector3f vr_offset_{0.0f, 0.0f, 0.0f}; + Vector3f vr_extra_offset_{0.0f, 0.0f, 0.0f}; + Vector3f vr_offset_smooth_{0.0f, 0.0f, 0.0f}; + Vector3f extra_pos_{0.0f, 0.0f, 0.0f}; + Vector3f extra_pos_2_{0.0f, 0.0f, 0.0f}; + Vector3f shake_pos_{0.0f, 0.0f, 0.0f}; + Vector3f shake_vel_{0.0f, 0.0f, 0.0f}; + Vector3f position_{0.0f, 1.0f, -1.0f}; + Vector3f target_{0.0f, 1.0f, -1.0f}; + Vector3f target_smoothed_{0.0f, 0.0f, 0.0f}; + Vector3f position_offset_smoothed_{0.0f, 0.0f, 0.0f}; + Vector3f smooth_speed_{0.0f, 0.0f, 0.0f}; + Vector3f smooth_speed_2_{0.0f, 0.0f, 0.0f}; + Vector3f up_{0.0f, 1.0f, 0.0f}; + std::list areas_of_interest_; std::vector area_of_interest_points_{{0.0f, 0.0f, 0.0f}}; }; diff --git a/src/ballistica/base/input/input.cc b/src/ballistica/base/input/input.cc index 4a983659b..14b5c443c 100644 --- a/src/ballistica/base/input/input.cc +++ b/src/ballistica/base/input/input.cc @@ -244,7 +244,8 @@ void Input::ShowStandardInputDeviceConnectedMessage_(InputDevice* j) { g_base->logic->DeleteAppTimer(connect_print_timer_id_); } connect_print_timer_id_ = g_base->logic->NewAppTimer( - 500, false, NewLambdaRunnable([this] { AnnounceConnects_(); }).Get()); + 500 * 1000, false, + NewLambdaRunnable([this] { AnnounceConnects_(); }).Get()); } void Input::ShowStandardInputDeviceDisconnectedMessage_(InputDevice* j) { @@ -259,7 +260,8 @@ void Input::ShowStandardInputDeviceDisconnectedMessage_(InputDevice* j) { g_base->logic->DeleteAppTimer(disconnect_print_timer_id_); } disconnect_print_timer_id_ = g_base->logic->NewAppTimer( - 250, false, NewLambdaRunnable([this] { AnnounceDisconnects_(); }).Get()); + 250 * 1000, false, + NewLambdaRunnable([this] { AnnounceDisconnects_(); }).Get()); } void Input::PushAddInputDeviceCall(InputDevice* input_device, diff --git a/src/ballistica/base/logic/logic.cc b/src/ballistica/base/logic/logic.cc index 030229c25..a57852ec4 100644 --- a/src/ballistica/base/logic/logic.cc +++ b/src/ballistica/base/logic/logic.cc @@ -99,7 +99,7 @@ void Logic::OnGraphicsReady() { // Anyone dealing in display-time should be able to handle a wide // variety of rates anyway. NOTE: This length is currently milliseconds. headless_display_time_step_timer_ = event_loop()->NewTimer( - kHeadlessMinDisplayTimeStep / 1000, true, + kHeadlessMinDisplayTimeStep, true, NewLambdaRunnable([this] { StepDisplayTime_(); }).Get()); } else { // In gui mode, push an initial frame to the graphics server. From this @@ -134,8 +134,9 @@ void Logic::CompleteAppBootstrapping_() { // Set up our timers. process_pending_work_timer_ = event_loop()->NewTimer( 0, true, NewLambdaRunnable([this] { ProcessPendingWork_(); }).Get()); - asset_prune_timer_ = event_loop()->NewTimer( - 2345, true, NewLambdaRunnable([] { g_base->assets->Prune(); }).Get()); + // asset_prune_timer_ = event_loop()->NewTimer( + // 2345 * 1000, true, NewLambdaRunnable([] { g_base->assets->Prune(); + // }).Get()); // Let our initial dummy app-mode know it has become active. g_base->app_mode()->OnActivate(); @@ -381,9 +382,7 @@ void Logic::OnAppModeChanged() { "Resetting headless display step timer due to app-mode change."); } assert(headless_display_time_step_timer_); - // NOTE: This is currently milliseconds. - headless_display_time_step_timer_->SetLength(kHeadlessMinDisplayTimeStep - / 1000); + headless_display_time_step_timer_->SetLength(kHeadlessMinDisplayTimeStep); } } @@ -439,8 +438,8 @@ void Logic::PostUpdateDisplayTimeForHeadlessMode_() { Log(LogLevel::kDebug, buffer); } - auto sleep_millisecs = headless_display_step_microsecs / 1000; - headless_display_time_step_timer_->SetLength(sleep_millisecs); + auto sleep_microsecs = headless_display_step_microsecs; + headless_display_time_step_timer_->SetLength(sleep_microsecs); } void Logic::UpdateDisplayTimeForFrameDraw_() { @@ -581,7 +580,7 @@ void Logic::UpdatePendingWorkTimer_() { // If there's loading to do, keep at it rather vigorously. if (have_pending_loads_) { assert(process_pending_work_timer_); - process_pending_work_timer_->SetLength(1); + process_pending_work_timer_->SetLength(1000); } else { // Otherwise we've got nothing to do; go to sleep until something // changes. @@ -635,7 +634,7 @@ void Logic::NotifyOfPendingAssetLoads() { UpdatePendingWorkTimer_(); } -auto Logic::NewAppTimer(millisecs_t length, bool repeat, Runnable* runnable) +auto Logic::NewAppTimer(microsecs_t length, bool repeat, Runnable* runnable) -> int { // App-Timers simply get injected into our loop and run alongside our own // stuff. @@ -649,7 +648,7 @@ void Logic::DeleteAppTimer(int timer_id) { event_loop()->DeleteTimer(timer_id); } -void Logic::SetAppTimerLength(int timer_id, millisecs_t length) { +void Logic::SetAppTimerLength(int timer_id, microsecs_t length) { assert(g_base->InLogicThread()); Timer* t = event_loop()->GetTimer(timer_id); if (t) { @@ -660,14 +659,14 @@ void Logic::SetAppTimerLength(int timer_id, millisecs_t length) { } } -auto Logic::NewDisplayTimer(microsecs_t length, bool repeat, - const Object::Ref& runnable) -> int { +auto Logic::NewDisplayTimer(microsecs_t length, bool repeat, Runnable* runnable) + -> int { // Display-Timers go into a timer-list that we exec explicitly when we // step display-time. assert(g_base->InLogicThread()); int offset = 0; - Timer* t = display_timers_->NewTimer(g_core->GetAppTimeMicrosecs(), length, - offset, repeat ? -1 : 0, runnable.Get()); + Timer* t = display_timers_->NewTimer(display_time_microsecs_, length, offset, + repeat ? -1 : 0, runnable); return t->id(); } diff --git a/src/ballistica/base/logic/logic.h b/src/ballistica/base/logic/logic.h index 3974392bd..2e21436e6 100644 --- a/src/ballistica/base/logic/logic.h +++ b/src/ballistica/base/logic/logic.h @@ -89,12 +89,12 @@ class Logic { void HandleInterruptSignal(); void HandleTerminateSignal(); - auto NewAppTimer(millisecs_t length, bool repeat, Runnable* runnable) -> int; + auto NewAppTimer(microsecs_t length, bool repeat, Runnable* runnable) -> int; void DeleteAppTimer(int timer_id); - void SetAppTimerLength(int timer_id, millisecs_t length); + void SetAppTimerLength(int timer_id, microsecs_t length); - auto NewDisplayTimer(microsecs_t length, bool repeat, - const Object::Ref& runnable) -> int; + auto NewDisplayTimer(microsecs_t length, bool repeat, Runnable* runnable) + -> int; void DeleteDisplayTimer(int timer_id); void SetDisplayTimerLength(int timer_id, microsecs_t length); @@ -148,8 +148,6 @@ class Logic { bool shutdown_completed_ : 1 {}; bool graphics_ready_ : 1 {}; Timer* process_pending_work_timer_{}; - Timer* asset_prune_timer_{}; - Timer* debug_timer_{}; EventLoop* event_loop_{}; std::unique_ptr display_timers_; }; diff --git a/src/ballistica/base/python/class/python_class_app_timer.cc b/src/ballistica/base/python/class/python_class_app_timer.cc index 0202a91de..1ef193061 100644 --- a/src/ballistica/base/python/class/python_class_app_timer.cc +++ b/src/ballistica/base/python/class/python_class_app_timer.cc @@ -94,7 +94,7 @@ auto PythonClassAppTimer::tp_new(PyTypeObject* type, PyObject* args, auto runnable(Object::New(call_obj)); self->timer_id_ = g_base->logic->NewAppTimer( - static_cast(length * 1000.0), repeat, + static_cast(length * 1000000.0), repeat, Object::New(call_obj).Get()); self->have_timer_ = true; diff --git a/src/ballistica/base/python/class/python_class_display_timer.cc b/src/ballistica/base/python/class/python_class_display_timer.cc index eb9330bfe..d95d79188 100644 --- a/src/ballistica/base/python/class/python_class_display_timer.cc +++ b/src/ballistica/base/python/class/python_class_display_timer.cc @@ -104,7 +104,7 @@ auto PythonClassDisplayTimer::tp_new(PyTypeObject* type, PyObject* args, } self->timer_id_ = g_base->logic->NewDisplayTimer( static_cast(length * 1000000.0), repeat, - Object::New(call_obj)); + Object::New(call_obj).Get()); self->have_timer_ = true; diff --git a/src/ballistica/base/python/methods/python_methods_app.cc b/src/ballistica/base/python/methods/python_methods_app.cc index 48db42698..ba2994790 100644 --- a/src/ballistica/base/python/methods/python_methods_app.cc +++ b/src/ballistica/base/python/methods/python_methods_app.cc @@ -365,7 +365,7 @@ static auto PyAppTimer(PyObject* self, PyObject* args, PyObject* keywds) throw Exception("Timer length cannot be < 0.", PyExcType::kValue); } g_base->logic->NewAppTimer( - static_cast(length * 1000.0), false, + static_cast(length * 1000000.0), false, Object::New(call_obj).Get()); Py_RETURN_NONE; BA_PYTHON_CATCH; @@ -459,7 +459,7 @@ static auto PyDisplayTimer(PyObject* self, PyObject* args, PyObject* keywds) } g_base->logic->NewDisplayTimer( static_cast(length * 1000000.0), false, - Object::New(call_obj)); + Object::New(call_obj).Get()); Py_RETURN_NONE; BA_PYTHON_CATCH; } diff --git a/src/ballistica/base/support/app_timer.h b/src/ballistica/base/support/app_timer.h index 966ef01b3..876c3a658 100644 --- a/src/ballistica/base/support/app_timer.h +++ b/src/ballistica/base/support/app_timer.h @@ -13,21 +13,22 @@ namespace ballistica::base { class AppTimer : public Object { public: - AppTimer(millisecs_t length, bool repeat, Runnable* runnable) { + AppTimer(microsecs_t length, bool repeat, Runnable* runnable) { assert(g_base->InLogicThread()); timer_id_ = base::g_base->logic->NewAppTimer(length, repeat, runnable); } template - static auto New(millisecs_t length, bool repeat, const F& lambda) { + static auto New(microsecs_t length, bool repeat, const F& lambda) { return Object::New(length, repeat, NewLambdaRunnable(lambda).Get()); } - void SetLength(millisecs_t length) { + void SetLength(microsecs_t length) { assert(g_base->InLogicThread()); base::g_base->logic->SetAppTimerLength(timer_id_, length); } + ~AppTimer() override { assert(g_base->InLogicThread()); base::g_base->logic->DeleteAppTimer(timer_id_); diff --git a/src/ballistica/base/support/display_timer.h b/src/ballistica/base/support/display_timer.h new file mode 100644 index 000000000..1936ed8db --- /dev/null +++ b/src/ballistica/base/support/display_timer.h @@ -0,0 +1,42 @@ +// Released under the MIT License. See LICENSE for details. + +#ifndef BALLISTICA_BASE_SUPPORT_DISPLAY_TIMER_H_ +#define BALLISTICA_BASE_SUPPORT_DISPLAY_TIMER_H_ + +#include "ballistica/base/base.h" +#include "ballistica/base/logic/logic.h" +#include "ballistica/shared/ballistica.h" +#include "ballistica/shared/foundation/object.h" +#include "ballistica/shared/generic/lambda_runnable.h" + +namespace ballistica::base { + +class DisplayTimer : public Object { + public: + DisplayTimer(microsecs_t length, bool repeat, Runnable* runnable) { + assert(g_base->InLogicThread()); + timer_id_ = base::g_base->logic->NewDisplayTimer(length, repeat, runnable); + } + + template + static auto New(microsecs_t length, bool repeat, const F& lambda) { + return Object::New(length, repeat, + NewLambdaRunnable(lambda).Get()); + } + + void SetLength(microsecs_t length) { + assert(g_base->InLogicThread()); + base::g_base->logic->SetDisplayTimerLength(timer_id_, length); + } + ~DisplayTimer() override { + assert(g_base->InLogicThread()); + base::g_base->logic->DeleteDisplayTimer(timer_id_); + } + + private: + int timer_id_; +}; + +} // namespace ballistica::base + +#endif // BALLISTICA_BASE_SUPPORT_DISPLAY_TIMER_H_ diff --git a/src/ballistica/base/support/repeater.cc b/src/ballistica/base/support/repeater.cc index c7d58d5ef..8528ce12c 100644 --- a/src/ballistica/base/support/repeater.cc +++ b/src/ballistica/base/support/repeater.cc @@ -2,7 +2,7 @@ #include "ballistica/base/support/repeater.h" -#include "ballistica/base/support/app_timer.h" +#include "ballistica/base/support/display_timer.h" #include "ballistica/shared/foundation/event_loop.h" namespace ballistica::base { @@ -27,9 +27,9 @@ Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay, return; } // Kick off our initial delay timer (generally the longer one). - weak_this->timer_ = AppTimer::New( - static_cast(weak_this->initial_delay_ * 1000.0), false, - [weak_this] { + weak_this->timer_ = DisplayTimer::New( + static_cast(weak_this->initial_delay_ * 1000000.0), + false, [weak_this] { // Timer should not have fired if we died. assert(weak_this.Exists()); weak_this->runnable_->RunAndLogErrors(); @@ -38,8 +38,8 @@ Repeater::Repeater(seconds_t initial_delay, seconds_t repeat_delay, return; } // Kick off our repeat timer (generally the short one). - weak_this->timer_ = AppTimer::New( - static_cast(weak_this->repeat_delay_ * 1000.0), + weak_this->timer_ = DisplayTimer::New( + static_cast(weak_this->repeat_delay_ * 1000000.0), true, [weak_this] { // Timer should not have fired if we died. assert(weak_this.Exists()); diff --git a/src/ballistica/base/support/repeater.h b/src/ballistica/base/support/repeater.h index 19355a380..2568ac246 100644 --- a/src/ballistica/base/support/repeater.h +++ b/src/ballistica/base/support/repeater.h @@ -11,6 +11,7 @@ namespace ballistica::base { /// Runs some code immediately and then repeatedly after a delay. Useful for /// jobs such as selecting ui elements while keys or buttons are held. +/// Uses display-time so emphasizes visual smoothness over accuracy. class Repeater : public Object { public: Repeater(seconds_t initial_delay, seconds_t repeat_delay, Runnable* runnable); @@ -26,7 +27,7 @@ class Repeater : public Object { private: seconds_t initial_delay_; seconds_t repeat_delay_; - Object::Ref timer_; + Object::Ref timer_; Object::Ref runnable_; }; diff --git a/src/ballistica/base/ui/dev_console.cc b/src/ballistica/base/ui/dev_console.cc index cec733a81..793617a2b 100644 --- a/src/ballistica/base/ui/dev_console.cc +++ b/src/ballistica/base/ui/dev_console.cc @@ -85,8 +85,10 @@ static auto XOffs(DevConsoleHAnchor_ attach) -> float { } static auto IsValidHungryChar_(uint32_t this_char) -> bool { + // Include letters, numbers, and underscore. return ((this_char >= 65 && this_char <= 90) - || (this_char >= 97 && this_char <= 122)); + || (this_char >= 97 && this_char <= 122) + || (this_char >= 48 && this_char <= 57) || this_char == '_'); } static void DrawRect(RenderPass* pass, Mesh* mesh, float bottom, float x, @@ -722,7 +724,9 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { bool do_history_up{}; bool do_history_down{}; bool do_backspace{}; + bool do_forward_delete{}; bool do_hungry_backspace{}; + bool do_hungry_forward_delete{}; bool do_move_to_end{}; bool do_move_to_beginning{}; bool do_kill_line{}; @@ -735,6 +739,20 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { } break; } + case SDLK_DELETE: { + if (keysym->mod & KMOD_ALT) { + do_hungry_forward_delete = true; + } else { + do_forward_delete = true; + } + break; + } + case SDLK_HOME: + do_move_to_beginning = true; + break; + case SDLK_END: + do_move_to_end = true; + break; case SDLK_UP: do_history_up = true; break; @@ -791,6 +809,13 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { do_move_to_beginning = true; } break; + case SDLK_d: + if (keysym->mod & KMOD_CTRL) { + do_forward_delete = true; + } else if (keysym->mod & KMOD_ALT) { + do_hungry_forward_delete = true; + } + break; case SDLK_e: if (keysym->mod & KMOD_CTRL) { do_move_to_end = true; @@ -800,7 +825,6 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { if (keysym->mod & KMOD_CTRL) { do_kill_line = true; } - default: { break; } @@ -851,15 +875,18 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { carat_char_ -= 1; assert(CaratCharValid_()); } - input_string_ = Utils::UTF8FromUnicode(unichars); - input_text_dirty_ = true; + if (do_delete) { + input_string_ = Utils::UTF8FromUnicode(unichars); + input_text_dirty_ = true; + } carat_dirty_ = true; }); } - if (do_hungry_carat_right) { + if (do_hungry_forward_delete || do_hungry_carat_right) { + auto do_delete = do_hungry_forward_delete; key_repeater_ = Repeater::New( g_base->app_adapter->GetKeyRepeatDelay(), - g_base->app_adapter->GetKeyRepeatInterval(), [this] { + g_base->app_adapter->GetKeyRepeatInterval(), [this, do_delete] { auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjco38"); bool found_valid{}; // Move until we've found at least one valid char and the @@ -874,9 +901,17 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { if (is_valid) { found_valid = true; } - carat_char_ += 1; + if (do_delete) { + unichars.erase(unichars.begin() + carat_char_); + } else { + carat_char_ += 1; + } assert(CaratCharValid_()); } + if (do_delete) { + input_string_ = Utils::UTF8FromUnicode(unichars); + input_text_dirty_ = true; + } carat_dirty_ = true; }); } @@ -896,6 +931,21 @@ auto DevConsole::HandleKeyPress(const SDL_Keysym* keysym) -> bool { } }); } + if (do_forward_delete) { + key_repeater_ = Repeater::New( + g_base->app_adapter->GetKeyRepeatDelay(), + g_base->app_adapter->GetKeyRepeatInterval(), [this] { + auto unichars = Utils::UnicodeFromUTF8(input_string_, "fjco33"); + if (!unichars.empty() && carat_char_ < unichars.size()) { + assert(CaratCharValid_()); + unichars.erase(unichars.begin() + carat_char_); + input_string_ = Utils::UTF8FromUnicode(unichars); + input_text_dirty_ = true; + carat_dirty_ = true; // Didn't move but might change size. + assert(CaratCharValid_()); + } + }); + } if (do_carat_left || do_carat_right) { key_repeater_ = Repeater::New( g_base->app_adapter->GetKeyRepeatDelay(), diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index d7bbd4545..3eeb626b0 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21528; +const int kEngineBuildNumber = 21531; const char* kEngineVersion = "1.7.28"; const int kEngineApiVersion = 8; diff --git a/src/ballistica/shared/foundation/event_loop.cc b/src/ballistica/shared/foundation/event_loop.cc index f6e9850d9..c04245e71 100644 --- a/src/ballistica/shared/foundation/event_loop.cc +++ b/src/ballistica/shared/foundation/event_loop.cc @@ -217,12 +217,12 @@ void EventLoop::WaitForNextEvent_(bool single_cycle) { // If we've got active timers, wait for messages with a timeout so we can // run the next timer payload. if (!suspended_ && timers_.ActiveTimerCount() > 0) { - millisecs_t apptime = g_core->GetAppTimeMillisecs(); - millisecs_t wait_time = timers_.TimeToNextExpire(apptime); + microsecs_t apptime = g_core->GetAppTimeMicrosecs(); + microsecs_t wait_time = timers_.TimeToNextExpire(apptime); if (wait_time > 0) { std::unique_lock lock(thread_message_mutex_); if (thread_messages_.empty()) { - thread_message_cv_.wait_for(lock, std::chrono::milliseconds(wait_time), + thread_message_cv_.wait_for(lock, std::chrono::microseconds(wait_time), [this] { // Go back to sleep on spurious wakeups // if we didn't wind up with any new @@ -298,8 +298,6 @@ void EventLoop::Run_(bool single_cycle) { assert(!suspended_); RunSuspendCallbacks_(); suspended_ = true; - last_suspend_time_ = g_core->GetAppTimeMillisecs(); - messages_since_suspended_ = 0; break; } case ThreadMessage_::Type::kUnsuspend: { @@ -319,7 +317,7 @@ void EventLoop::Run_(bool single_cycle) { } if (!suspended_) { - timers_.Run(g_core->GetAppTimeMillisecs()); + timers_.Run(g_core->GetAppTimeMicrosecs()); RunPendingRunnables_(); } @@ -607,12 +605,12 @@ auto EventLoop::AreEventLoopsSuspended() -> bool { return g_core->event_loops_suspended; } -auto EventLoop::NewTimer(millisecs_t length, bool repeat, Runnable* runnable) +auto EventLoop::NewTimer(microsecs_t length, bool repeat, Runnable* runnable) -> Timer* { assert(g_core); assert(ThreadIsCurrent()); assert(Object::IsValidManagedObject(runnable)); - return timers_.NewTimer(g_core->GetAppTimeMillisecs(), length, 0, + return timers_.NewTimer(g_core->GetAppTimeMicrosecs(), length, 0, repeat ? -1 : 0, runnable); } @@ -774,8 +772,8 @@ auto EventLoop::CheckPushRunnableSafety_() -> bool { void EventLoop::AcquireGIL_() { assert(g_base_soft && g_base_soft->InLogicThread()); auto debug_timing{g_core->core_config().debug_timing}; - millisecs_t startms{debug_timing ? core::CorePlatform::GetCurrentMillisecs() - : 0}; + millisecs_t startmillisecs{ + debug_timing ? core::CorePlatform::GetCurrentMillisecs() : 0}; if (py_thread_state_) { PyEval_RestoreThread(py_thread_state_); @@ -783,10 +781,10 @@ void EventLoop::AcquireGIL_() { } if (debug_timing) { - auto duration{core::CorePlatform::GetCurrentMillisecs() - startms}; + auto duration{core::CorePlatform::GetCurrentMillisecs() - startmillisecs}; if (duration > (1000 / 120)) { - Log(LogLevel::kInfo, - "GIL acquire took too long (" + std::to_string(duration) + " ms)."); + Log(LogLevel::kInfo, "GIL acquire took too long (" + + std::to_string(duration) + " millisecs)."); } } } diff --git a/src/ballistica/shared/foundation/event_loop.h b/src/ballistica/shared/foundation/event_loop.h index 2551b00a9..5a9649e60 100644 --- a/src/ballistica/shared/foundation/event_loop.h +++ b/src/ballistica/shared/foundation/event_loop.h @@ -45,21 +45,17 @@ class EventLoop { auto thread_id() const -> std::thread::id { return thread_id_; } - // Needed in rare cases where we jump physical threads. - // (Our 'main' thread on Android can switch under us as - // rendering contexts are recreated in new threads/etc.) - // void set_thread_id(std::thread::id id) { thread_id_ = id; } - void RunToCompletion(); void RunSingleCycle(); auto identifier() const -> EventLoopID { return identifier_; } - // Register a timer to run on the thread. - auto NewTimer(millisecs_t length, bool repeat, Runnable* runnable) -> Timer*; + /// Register a timer to run on the thread. + auto NewTimer(microsecs_t length, bool repeat, Runnable* runnable) -> Timer*; Timer* GetTimer(int id); void DeleteTimer(int id); + /// Add a runnable to this thread's event-loop. /// Pass a Runnable that has been allocated with NewUnmanaged(). /// It will be owned and disposed of by the thread. @@ -160,26 +156,21 @@ class EventLoop { void* auto_release_pool_{}; #endif - bool bootstrapped_{}; - bool writing_tally_{}; - bool suspended_{}; - bool done_{}; - bool acquires_python_gil_{}; EventLoopID identifier_{EventLoopID::kInvalid}; - millisecs_t last_suspend_time_{}; - int listen_sd_{}; - int messages_since_suspended_{}; - millisecs_t last_suspended_message_report_time_{}; - millisecs_t last_complaint_time_{}; - ThreadSource source_; + ThreadSource source_{}; + bool bootstrapped_ : 1 {}; + bool writing_tally_ : 1 {}; + bool suspended_ : 1 {}; + bool done_ : 1 {}; + bool acquires_python_gil_ : 1 {}; std::thread::id thread_id_{}; + std::condition_variable thread_message_cv_; + std::condition_variable client_listener_cv_; std::list> runnables_; std::list suspend_callbacks_; std::list unsuspend_callbacks_; - std::condition_variable thread_message_cv_; - std::condition_variable client_listener_cv_; - std::mutex thread_message_mutex_; std::list thread_messages_; + std::mutex thread_message_mutex_; std::mutex client_listener_mutex_; std::list> data_to_client_; PyThreadState* py_thread_state_{};