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 | 72 +++++++------- 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, 294 insertions(+), 190 deletions(-) create mode 100644 src/ballistica/base/support/display_timer.h diff --git a/.efrocachemap b/.efrocachemap index 95a2a68d..3dcc07ae 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 1a6d0354..a0bab389 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 443a6adc..c4d1ed64 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 3a4e6a25..fc194878 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 90ed3d40..078cbd38 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 7b5fa892..b4f73ad3 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 90ed3d40..078cbd38 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 55329257..1d1469c6 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ if TYPE_CHECKING: # 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 9c89f00e..aaf27ba5 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 adcdee40..a7a9ad1a 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 07ab3f2e..f4b04101 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 d12ad130..050057b1 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 7b13bb4c..f6fe6504 100644 --- a/src/ballistica/base/graphics/support/camera.h +++ b/src/ballistica/base/graphics/support/camera.h @@ -92,37 +92,51 @@ 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_{}; + 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}; + float min_target_radius_{5.0f}; + float area_of_interest_near_{1.0f}; + float area_of_interest_far_{2.0f}; + 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}; @@ -131,20 +145,8 @@ class Camera : public Object { 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}; + 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 4a983659..14b5c443 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 030229c2..a57852ec 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 3974392b..2e21436e 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 0202a91d..1ef19306 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 eb9330bf..d95d7918 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 48db4269..ba299479 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 966ef01b..876c3a65 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 00000000..1936ed8d --- /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 c7d58d5e..8528ce12 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 19355a38..2568ac24 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 cec733a8..793617a2 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 d7bbd454..3eeb626b 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 f6e9850d..c04245e7 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 2551b00a..5a9649e6 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_{};