From 9c90d3a9816e828c8f3d5727532dbf3a258e78e8 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 14 Jun 2023 06:27:04 -0700 Subject: [PATCH] hardened base::Input against events pushed before loop creation --- .efrocachemap | 56 ++++++++++---------- CHANGELOG.md | 2 +- config/spinoffconfig.py | 1 - src/assets/ba_data/python/baenv.py | 2 +- src/ballistica/base/base.cc | 14 +++-- src/ballistica/base/input/input.cc | 79 ++++++++++++++++------------- src/ballistica/shared/ballistica.cc | 2 +- 7 files changed, 85 insertions(+), 71 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index a70cf17e..e07d058e 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4072,26 +4072,26 @@ "build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/18/4b/787a9267e17be3c49966072581a5", "build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/20/f6/4ce9bc3c1f3732f6adf8237fbe9b", "build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/a5/30/9058181df0b1255bf6950cbc7813", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/27/a8/33cd74136139a19f09f3f9f39d51", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/20/21/c2f44e526f0f9ec1c8b04c46deeb", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/f9/45/137171d8ee3d4a0d5119299629f8", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/42/05/4006777cd3ce386c5e6832d6a2dd", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/4b/a3/4313bb82f8a9a39a2bad6c872031", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/e1/46/e5090c7e86ed94c5da68d9b6685e", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2f/76/dfb2e09294a3b542ced81b47b037", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/68/0c/31a2da9dc8ac7ced3ef102be8a07", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/03/da/632945cffca4871a57c52d80a38c", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/08/3f/6bb63eee6aad1d1312c69ec28f2a", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/00/da/82ea5bc2b564c0e17d2443ea7596", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/31/68/877798059bc4c11ac3a76368f0b4", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/d0/d5/4b4e51c281e5336c1674deffb7d8", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/0e/0e/d929a9023e5c1ce3e78b66381b0e", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/1e/56/3c04354880ab54a489429df69485", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7a/e7/d3ee482ed06428fea2abaf400511", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/5a/7a/dc269e5c70e012486057bee889a2", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/69/a2/65fcc17851de08201e84e6359d09", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/5e/7b/157d9ea9b402334e5c3cb0f3b2c2", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/13/b4/62765b06ad73228e2acef65c9da4", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/0f/96/2c1115507d811a9700c9a189d0ff", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/10/bc/042bcd64c7c25812495f32ffe676", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7c/4a/3ebed71b2d5ec2426d410d349d90", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/1a/62/201368775081eacc28f2e9b01f9a", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/8f/38/acfc4a64d6b5bf22ef6fe4178c5e", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/c9/46/e9e737f0b53afc1dc4210c32109c", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/89/21/242947b6f7473e6c4086650e7ab3", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/f1/f1/60763fedeabfb36963d1f04c4992", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/5c/40/a6477683bc54386dd4f55f0a3dc3", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/43/5a/4821729b6acff1e5c9b966773d51", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/29/90/a9e78e8dc092013bacad27224d31", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/4b/87/0cb2824755db706d9a70db93aff1", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/80/7c/944dbaaadd92e156673e05189c65", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/9d/dd/359445178c190356c0c44ed3205f", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/a9/a6/3c1cad0e6e1d73b05f20032f740f", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b1/3b/afbdc71a34c16199751dacbf733c", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/a1/52/deaef111e5a2c310ea588d670043", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/53/2e/ab897b1d065a3f0fc45e02513a34", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/13/08/8cbaefd2b09209559ccb98570253", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/87/ce/b99cff2d428e327c64e4bdf8b0c3", "build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/29/dc/e5b08aae2dbe3222082aaa1e90e7", "build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/ce/bb/5796a83ce9d1c9cf58e08f3ff351", "build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/31/65/014221e46f7974f40aa84c8922dc", @@ -4108,14 +4108,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/14/4b/68a0ece3c1f191183b695cf45a4d", "build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/1f/3f/d899a46cc0dc8bc4f1b38f9318a5", "build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/de/99/95fdcb3f614a7b83ada148bca38d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/23/eb/094b2e7b488473e3f2270869f0fe", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/c7/9e/26cce979164cb005a170bf8660b2", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/4a/82/fa2dbbd612ea22d98d154d9d369e", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/f8/76/5216f4b0c076a02d92d82731e492", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/7f/34/239a4e0a25a2ca79c5b8b87e35da", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/cc/a7/a14d676a89ecfe6603b88f2629c0", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/6c/37/fbe1d3584826744c84366c18ddca", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/38/43/15e41853d3cac83d6e982894965e", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/ef/d4/f49c526f2344ce7618c41a441287", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/0f/ec/2f13d6e6c702e18622bdfe931072", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/02/a9/4a4121ab7aa9c9855b047c00f6ab", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/59/41/f357e7726c85efd014597d2c36a9", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/a5/50/10ccb7ec0caca05a8151bf1da3c4", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/fd/c1/a5372ecd9a97190391425a061278", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/10/dd/5b6e16ab1252afaf1b317af27124", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/dd/2c/9c4760956a5d62bbee8f6921d0fa", "src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa", "src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1", "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/ea/6a/6a4721b144e5e297b542d2a0eea2", diff --git a/CHANGELOG.md b/CHANGELOG.md index b4bfc543..006898b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.20 (build 21099, api 8, 2023-06-13) +### 1.7.20 (build 21102, api 8, 2023-06-14) - This seems like a good time for a `refactoring` release in anticipation of changes coming in 1.8. Basically this means that a lot of things will be diff --git a/config/spinoffconfig.py b/config/spinoffconfig.py index 5d105d72..f85e290f 100644 --- a/config/spinoffconfig.py +++ b/config/spinoffconfig.py @@ -49,7 +49,6 @@ ctx.cruft_file_names = {'.DS_Store'} ctx.src_omit_paths = { '.gitignore', 'config/spinoffconfig.py', - 'ballisticakit-android/build', 'tools/spinoff', '.editorconfig', 'src/assets/workspace', diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 3fb9a039..3eaea64e 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -28,7 +28,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21099 +TARGET_BALLISTICA_BUILD = 21102 TARGET_BALLISTICA_VERSION = '1.7.20' _g_env_config: EnvConfig | None = None diff --git a/src/ballistica/base/base.cc b/src/ballistica/base/base.cc index 5e2c8c20..1e6a5ec8 100644 --- a/src/ballistica/base/base.cc +++ b/src/ballistica/base/base.cc @@ -621,10 +621,16 @@ void BaseFeatureSet::DoPushObjCall(const PythonObjectSetBase* objset, int id) { // should fix them at the source. assert(IsAppRunning()); - logic->event_loop()->PushCall([objset, id] { - ScopedSetContext ssc(nullptr); - objset->Obj(id).Call(); - }); + if (auto* loop = logic->event_loop()) { + logic->event_loop()->PushCall([objset, id] { + ScopedSetContext ssc(nullptr); + objset->Obj(id).Call(); + }); + } else { + BA_LOG_ONCE( + LogLevel::kError, + "BaseFeatureSet::DoPushObjCall called before event loop created."); + } } void BaseFeatureSet::DoPushObjCall(const PythonObjectSetBase* objset, int id, diff --git a/src/ballistica/base/input/input.cc b/src/ballistica/base/input/input.cc index fdc682e9..e2a39f4b 100644 --- a/src/ballistica/base/input/input.cc +++ b/src/ballistica/base/input/input.cc @@ -21,9 +21,23 @@ namespace ballistica::base { Input::Input() = default; +template +void SafePushCall(const char* desc, const F& lambda) { + if (!g_base) { + BA_LOG_ONCE(LogLevel::kError, + std::string(desc) + " called with null g_base."); + return; + } + if (auto* loop = g_base->logic->event_loop()) { + loop->PushCall(lambda); + } else { + BA_LOG_ONCE(LogLevel::kError, + std::string(desc) + " called before logic event loop created."); + } +} + void Input::PushCreateKeyboardInputDevices() { - g_base->logic->event_loop()->PushCall( - [this] { CreateKeyboardInputDevices(); }); + SafePushCall(__func__, [this] { CreateKeyboardInputDevices(); }); } void Input::CreateKeyboardInputDevices() { @@ -40,8 +54,7 @@ void Input::CreateKeyboardInputDevices() { } void Input::PushDestroyKeyboardInputDevices() { - g_base->logic->event_loop()->PushCall( - [this] { DestroyKeyboardInputDevices(); }); + SafePushCall(__func__, [this] { DestroyKeyboardInputDevices(); }); } void Input::DestroyKeyboardInputDevices() { @@ -254,7 +267,7 @@ void Input::ShowStandardInputDeviceDisconnectedMessage(InputDevice* j) { void Input::PushAddInputDeviceCall(InputDevice* input_device, bool standard_message) { - g_base->logic->event_loop()->PushCall([this, input_device, standard_message] { + SafePushCall(__func__, [this, input_device, standard_message] { AddInputDevice(input_device, standard_message); }); } @@ -338,7 +351,7 @@ void Input::AddInputDevice(InputDevice* device, bool standard_message) { void Input::PushRemoveInputDeviceCall(InputDevice* input_device, bool standard_message) { - g_base->logic->event_loop()->PushCall([this, input_device, standard_message] { + SafePushCall(__func__, [this, input_device, standard_message] { RemoveInputDevice(input_device, standard_message); }); } @@ -795,7 +808,7 @@ void Input::ProcessStressTesting(int player_count) { } void Input::PushTextInputEvent(const std::string& text) { - g_base->logic->event_loop()->PushCall([this, text] { + SafePushCall(__func__, [this, text] { mark_input_active(); // Ignore if input is locked. @@ -813,7 +826,7 @@ void Input::PushTextInputEvent(const std::string& text) { void Input::PushJoystickEvent(const SDL_Event& event, InputDevice* input_device) { - g_base->logic->event_loop()->PushCall([this, event, input_device] { + SafePushCall(__func__, [this, event, input_device] { HandleJoystickEvent(event, input_device); }); } @@ -847,13 +860,11 @@ void Input::HandleJoystickEvent(const SDL_Event& event, } void Input::PushKeyPressEvent(const SDL_Keysym& keysym) { - g_base->logic->event_loop()->PushCall( - [this, keysym] { HandleKeyPress(&keysym); }); + SafePushCall(__func__, [this, keysym] { HandleKeyPress(&keysym); }); } void Input::PushKeyReleaseEvent(const SDL_Keysym& keysym) { - g_base->logic->event_loop()->PushCall( - [this, keysym] { HandleKeyRelease(&keysym); }); + SafePushCall(__func__, [this, keysym] { HandleKeyRelease(&keysym); }); } void Input::CaptureKeyboardInput(HandleKeyPressCall* press_call, @@ -924,10 +935,11 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) { case SDLK_RETURN: case SDLK_KP_ENTER: case SDLK_BACKSPACE: { - // FIXME: I don't remember what this was put here for, but now that we + // FIXME: I don't remember what this was put here for, but now that + // we // have hardware keyboards it crashes text fields by sending them a - // TEXT_INPUT message with no string.. I made them resistant to that - // case but wondering if we can take this out?... + // TEXT_INPUT message with no string.. I made them resistant to + // that case but wondering if we can take this out?... g_base->ui->SendWidgetMessage( WidgetMessage(WidgetMessage::Type::kTextInput, keysym)); break; @@ -1004,14 +1016,13 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) { } case SDLK_F7: - g_base->logic->event_loop()->PushCall( - [] { g_base->graphics->ToggleManualCamera(); }); + SafePushCall(__func__, [] { g_base->graphics->ToggleManualCamera(); }); handled = true; break; case SDLK_F8: - g_base->logic->event_loop()->PushCall( - [] { g_base->graphics->ToggleNetworkDebugDisplay(); }); + SafePushCall(__func__, + [] { g_base->graphics->ToggleNetworkDebugDisplay(); }); handled = true; break; @@ -1022,8 +1033,7 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) { break; case SDLK_F10: - g_base->logic->event_loop()->PushCall( - [] { g_base->graphics->ToggleDebugDraw(); }); + SafePushCall(__func__, [] { g_base->graphics->ToggleDebugDraw(); }); handled = true; break; @@ -1032,8 +1042,8 @@ void Input::HandleKeyPress(const SDL_Keysym* keysym) { if (!g_base->ui->MainMenuVisible()) { // There's no main menu up. Ask for one. - // Note: keyboard_input_ may be nullptr but escape key should still - // function for menus; it just won't claim ownership. + // Note: keyboard_input_ may be nullptr but escape key should + // still function for menus; it just won't claim ownership. g_base->ui->PushMainMenuPressCall(keyboard_input_); } else { // Ok there *is* a main menu up. Send it a cancel message. @@ -1132,8 +1142,7 @@ void Input::UpdateModKeyStates(const SDL_Keysym* keysym, bool press) { } void Input::PushMouseScrollEvent(const Vector2f& amount) { - g_base->logic->event_loop()->PushCall( - [this, amount] { HandleMouseScroll(amount); }); + SafePushCall(__func__, [this, amount] { HandleMouseScroll(amount); }); } void Input::HandleMouseScroll(const Vector2f& amount) { @@ -1165,7 +1174,7 @@ void Input::HandleMouseScroll(const Vector2f& amount) { void Input::PushSmoothMouseScrollEvent(const Vector2f& velocity, bool momentum) { - g_base->logic->event_loop()->PushCall([this, velocity, momentum] { + SafePushCall(__func__, [this, velocity, momentum] { HandleSmoothMouseScroll(velocity, momentum); }); } @@ -1197,8 +1206,7 @@ void Input::HandleSmoothMouseScroll(const Vector2f& velocity, bool momentum) { } void Input::PushMouseMotionEvent(const Vector2f& position) { - g_base->logic->event_loop()->PushCall( - [this, position] { HandleMouseMotion(position); }); + SafePushCall(__func__, [this, position] { HandleMouseMotion(position); }); } void Input::HandleMouseMotion(const Vector2f& position) { @@ -1250,8 +1258,8 @@ void Input::HandleMouseMotion(const Vector2f& position) { } void Input::PushMouseDownEvent(int button, const Vector2f& position) { - g_base->logic->event_loop()->PushCall( - [this, button, position] { HandleMouseDown(button, position); }); + SafePushCall(__func__, + [this, button, position] { HandleMouseDown(button, position); }); } void Input::HandleMouseDown(int button, const Vector2f& position) { @@ -1326,8 +1334,8 @@ void Input::HandleMouseDown(int button, const Vector2f& position) { } void Input::PushMouseUpEvent(int button, const Vector2f& position) { - g_base->logic->event_loop()->PushCall( - [this, button, position] { HandleMouseUp(button, position); }); + SafePushCall(__func__, + [this, button, position] { HandleMouseUp(button, position); }); } void Input::HandleMouseUp(int button, const Vector2f& position) { @@ -1378,7 +1386,7 @@ void Input::HandleMouseUp(int button, const Vector2f& position) { } void Input::PushTouchEvent(const TouchEvent& e) { - g_base->logic->event_loop()->PushCall([e, this] { HandleTouchEvent(e); }); + SafePushCall(__func__, [e, this] { HandleTouchEvent(e); }); } void Input::HandleTouchEvent(const TouchEvent& e) { @@ -1412,8 +1420,9 @@ void Input::HandleTouchEvent(const TouchEvent& e) { "Got touch labeled first but will not be our single."); } - // Also: if the OS tells us that this is the end of an overall multi-touch - // gesture, it should mean that our single_touch_ has ended or will be. + // Also: if the OS tells us that this is the end of an overall + // multi-touch gesture, it should mean that our single_touch_ has ended + // or will be. if ((e.type == TouchEvent::Type::kUp || e.type == TouchEvent::Type::kCanceled) && single_touch_ != nullptr && single_touch_ != e.touch) { diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 932234b5..ff13ac5f 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 = 21099; +const int kEngineBuildNumber = 21102; const char* kEngineVersion = "1.7.20"; auto MonolithicMain(const core::CoreConfig& core_config) -> int {