UI is now properly saved/restored after games or appmode switches

This commit is contained in:
Eric 2024-09-24 11:33:09 -07:00
parent d1603831ae
commit f6973bac7c
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
16 changed files with 123 additions and 148 deletions

56
.efrocachemap generated
View File

@ -4096,26 +4096,26 @@
"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": "aa72881174380859e777358af1da8d1f",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "bb5c1ca60d9683f2d24d4d8d35af9121",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "89a73b9312c48ed182d54263707a0982",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "f8e25d00480757c6fef0d125fbabe7d3",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "116a9fff16cc5cefd91d24415e9b09e7",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "01a542f1515ee659f99550c34ca2f749",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "16aa91530f2abea70f8c648db20872b9",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "5c19c58e3163c2b4c21eb1cde8f2712a",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f3e54e879fe538a6f0e52c1833e03739",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "36b20cfad166d7229684cd0b88be0ca0",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "64bdc98a71e9bcb63999e7fb1c57722f",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "583086e11d495f3439bdd6029bde0466",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "701f03b8ba74493d935f795a84c13455",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "3e9f1feaf14d30f740d84280432cb236",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "31da2a14cc69755f3a8f68b17482832f",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8ef21c1df9040fb8e2d38258dc80a4d5",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "74a0b75b877954015798a6289d26c26c",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "ed2b2f673f2ed41fc24613a937a954d9",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "16824b0155479f54293cb2230553d174",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "379f72d2ce79111490ba9c87087488f3",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "21a16533b62c491d0581609132c22dd5",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "fd60f24823b5fd2951acf06ad92d124b",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "87bba2b52609ee3ae31c2b1255218d93",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "bb123af5ef4bdede5248e4d0e086d623",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "78e44932b961f079ddf15fae69fed639",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "49210bd0982bf5eda8dd1074b0b26152",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "85fcee6b23abbf1c5a8e64fd95567b6e",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "6c881b22460cb58f93249bc9f7a95724",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "625390166d0eac624f14fc1688c638e7",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "66cfb48fb1975ca32a750754d16055eb",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "b459b77672b95838742903e0afd1d9ae",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "f17dd55c15904f515e53fc676658194f",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "b1a493c944b9e60a80482e0097699695",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "018ca530ee4e8eaf78c2ea50059f2da4",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "83ef6001e1ef561a33207c396a7dc8b0",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "a00d2cff684ae4df75e52159ead85824",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "775c7f67370eff8d333eda82a626531f",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1fa9c1e758e790c263b45315b016fe11",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "8b9e532091efbf224cb410ebf66cfbcf",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "7fbbd61ecdcbb4a8e162b6045d2dcf53",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "ad908b297b41c2fdf13582e34c434245",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "086a2ce72497e44079ad6b747fc5439f",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "ad908b297b41c2fdf13582e34c434245",
@ -4132,14 +4132,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "d7a1d4deb51b0792d083737477e6833b",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "4c11b81a574aa9af593f54db4d998e61",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "d7a1d4deb51b0792d083737477e6833b",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "c6a3ce3f5dbfa705ef6d7e4b94bca8ed",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "61a4f8795d6cd96f90bc2bed25087bfe",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "0af969c789949825652e6b09020867b5",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "839ebfcfcbc87f4470b96f986485a4f6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "b161b991f68d7fc5a23e1bbf3041693f",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "48add2ca39f42cf1129fd56deac471e1",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "bd7faaa40c5b448554d524d2d5fddeb1",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "d18d44e3e100240220523f4bc54f9d85",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "564675e2f00a311387a6e621f3b67332",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "93395e2263f9ed10160dd8e80811be77",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "24445c70a851b691690803c87af33c81",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "cf286af8eb7762893ee935e08975eb60",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "33b5f0f70ad2d8775dee1fd810f319e5",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "74a2c3fa9e709ca034a106d56c3b3e36",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "8d97d249be1218c6277dc1de54e5c6b8",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "892e10ddcf3b8f1dd83e5d0303594273",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "794d258d59fd17a61752843a9a0551ad",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "efa61468cf098f77cc6a234461d8b86d",

View File

@ -1,4 +1,4 @@
### 1.7.37 (build 22009, api 9, 2024-09-23)
### 1.7.37 (build 22010, api 9, 2024-09-24)
- Bumping api version to 9. As you'll see below, there's some UI changes that
will require a bit of work for any UI mods to adapt to. If your mods don't
touch UI stuff at all you can simply bump your api version and call it a day.
@ -98,6 +98,9 @@
test UIScales are by using the UI panel in the dev-console or by setting the
`BA_UI_SCALE` env var. If we can get UIScale switches to feel seamless enough
at some point, it may be worth adding to display settings.
- There is now a `ba*.app.classic.save_ui_state()` method that should be called
right before jumping into a game/replay/etc. This will save a state that will
automatically be restored the next time the main menu activity is entered.
### 1.7.36 (build 21944, api 8, 2024-07-26)
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these

View File

@ -49,7 +49,6 @@ class ClassicAppMode(AppMode):
@override
def on_activate(self) -> None:
print('CLASSIC ACTIVATING')
# Let the native layer do its thing.
_baclassic.classic_app_mode_activate()
@ -110,7 +109,11 @@ class ClassicAppMode(AppMode):
@override
def on_deactivate(self) -> None:
print('CLASSIC DEACTIVATING')
# Save where we were in the UI so we return there next time.
if app.classic is not None:
app.classic.save_ui_state()
# Let the native layer do its thing.
_baclassic.classic_app_mode_deactivate()

View File

@ -112,6 +112,7 @@ class ClassicAppSubsystem(babase.AppSubsystem):
self.invite_confirm_windows: list[Any] = [] # FIXME: Don't use Any.
self.party_window: weakref.ref[PartyWindow] | None = None
self.main_menu_resume_callbacks: list = []
self.saved_ui_state: bauiv1.MainWindowState | None = None
# Store.
self.store_layout: dict[str, list[dict[str, Any]]] | None = None
@ -327,6 +328,9 @@ class ClassicAppSubsystem(babase.AppSubsystem):
)
return False
# Save where we are in the UI to come back to when done.
babase.app.classic.save_ui_state()
# Ok, we're good to go.
self.coop_session_args = {
'campaign': campaignname,
@ -523,23 +527,17 @@ class ClassicAppSubsystem(babase.AppSubsystem):
tip = self.tips.pop()
return tip
def run_gpu_benchmark(self) -> None:
"""Kick off a benchmark to test gpu speeds."""
from baclassic._benchmark import run_gpu_benchmark as run
run()
def run_cpu_benchmark(self) -> None:
"""Kick off a benchmark to test cpu speeds."""
from baclassic._benchmark import run_cpu_benchmark as run
from baclassic._benchmark import run_cpu_benchmark
run()
run_cpu_benchmark()
def run_media_reload_benchmark(self) -> None:
"""Kick off a benchmark to test media reloading speeds."""
from baclassic._benchmark import run_media_reload_benchmark as run
from baclassic._benchmark import run_media_reload_benchmark
run()
run_media_reload_benchmark()
def run_stress_test(
self,
@ -551,9 +549,9 @@ class ClassicAppSubsystem(babase.AppSubsystem):
attract_mode: bool = False,
) -> None:
"""Run a stress test."""
from baclassic._benchmark import run_stress_test as run
from baclassic._benchmark import run_stress_test
run(
run_stress_test(
playlist_type=playlist_type,
playlist_name=playlist_name,
player_count=player_count,
@ -819,11 +817,20 @@ class ClassicAppSubsystem(babase.AppSubsystem):
InGameMenuWindow(), is_top_level=True, suppress_warning=True
)
def save_ui_state(self) -> None:
"""Store our current place in the UI."""
ui = babase.app.ui_v1
mainwindow = ui.get_main_window()
if mainwindow is not None:
self.saved_ui_state = ui.save_main_window_state(mainwindow)
else:
self.saved_ui_state = None
def invoke_main_menu_ui(self) -> None:
"""Bring up main menu ui."""
print('INVOKING MAIN MENU UI')
# Bring up the last place we were, or start at the main menu otherwise.
# Bring up the last place we were, or start at the main menu
# otherwise.
app = bauiv1.app
env = app.env
with bascenev1.ContextRef.empty():
@ -844,72 +851,16 @@ class ClassicAppSubsystem(babase.AppSubsystem):
app.ui_v1.set_main_window(
KioskWindow(), is_top_level=True, suppress_warning=True
)
# ..or in normal cases go back to the main menu
else:
# if main_menu_location == 'Gather':
# # pylint: disable=cyclic-import
# from bauiv1lib.gather import GatherWindow
# If there's a saved ui state, restore that.
if self.saved_ui_state is not None:
app.ui_v1.restore_main_window_state(self.saved_ui_state)
else:
# Otherwise start fresh at the main menu.
from bauiv1lib.mainmenu import MainMenuWindow
# app.ui_v1.set_main_window(
# GatherWindow(transition=None),
# from_window=False, # Disable check here.
# )
# elif main_menu_location == 'Watch':
# # pylint: disable=cyclic-import
# from bauiv1lib.watch import WatchWindow
# app.ui_v1.set_main_window(
# WatchWindow(transition=None),
# from_window=False, # Disable check here.
# )
# elif main_menu_location == 'Team Game Select':
# # pylint: disable=cyclic-import
# from bauiv1lib.playlist.browser import (
# PlaylistBrowserWindow,
# )
# app.ui_v1.set_main_window(
# PlaylistBrowserWindow(
# sessiontype=bascenev1.DualTeamSession,
# transition=None,
# ),
# from_window=False, # Disable check here.
# )
# elif main_menu_location == 'Free-for-All Game Select':
# # pylint: disable=cyclic-import
# from bauiv1lib.playlist.browser import (
# PlaylistBrowserWindow,
# )
# app.ui_v1.set_main_window(
# PlaylistBrowserWindow(
# sessiontype=bascenev1.FreeForAllSession,
# transition=None,
# ),
# from_window=False, # Disable check here.
# )
# elif main_menu_location == 'Coop Select':
# # pylint: disable=cyclic-import
# from bauiv1lib.coop.browser import CoopBrowserWindow
# app.ui_v1.set_main_window(
# CoopBrowserWindow(transition=None),
# from_window=False, # Disable check here.
# )
# elif main_menu_location == 'Benchmarks & Stress Tests':
# # pylint: disable=cyclic-import
# from bauiv1lib.debug import DebugWindow
# app.ui_v1.set_main_window(
# DebugWindow(transition=None),
# from_window=False, # Disable check here.
# )
# else:
# pylint: disable=cyclic-import
from bauiv1lib.mainmenu import MainMenuWindow
app.ui_v1.set_main_window(
MainMenuWindow(transition=None),
is_top_level=True,
suppress_warning=True,
)
app.ui_v1.set_main_window(
MainMenuWindow(transition=None),
is_top_level=True,
suppress_warning=True,
)

View File

@ -20,11 +20,14 @@ def run_cpu_benchmark() -> None:
# pylint: disable=cyclic-import
from bascenev1lib import tutorial
# Save our UI state that we'll return to when done.
if babase.app.classic is not None:
babase.app.classic.save_ui_state()
class BenchmarkSession(bascenev1.Session):
"""Session type for cpu benchmark."""
def __init__(self) -> None:
# print('FIXME: BENCHMARK SESSION WOULD CALC DEPS.')
depsets: Sequence[bascenev1.DependencySet] = []
super().__init__(depsets)
@ -99,7 +102,9 @@ def _start_stress_test(args: _StressTestArgs) -> None:
"""(internal)"""
from bascenev1 import DualTeamSession, FreeForAllSession
assert babase.app.classic is not None
classic = babase.app.classic
assert classic is not None
appconfig = babase.app.config
playlist_type = args.playlist_type
@ -116,6 +121,10 @@ def _start_stress_test(args: _StressTestArgs) -> None:
+ args.playlist_name
+ '")...'
)
# Save where we are in the UI so we'll return there when done.
classic.save_ui_state()
if playlist_type == 'Teams':
appconfig['Team Tournament Playlist Selection'] = args.playlist_name
appconfig['Team Tournament Playlist Randomize'] = 1
@ -137,11 +146,11 @@ def _start_stress_test(args: _StressTestArgs) -> None:
),
)
_baclassic.set_stress_testing(True, args.player_count, args.attract_mode)
babase.app.classic.stress_test_update_timer = babase.AppTimer(
classic.stress_test_update_timer = babase.AppTimer(
args.round_duration, babase.Call(_reset_stress_test, args)
)
if args.attract_mode:
babase.app.classic.stress_test_update_timer_2 = babase.AppTimer(
classic.stress_test_update_timer_2 = babase.AppTimer(
0.48, babase.Call(_update_attract_mode_test, args), repeat=True
)
@ -170,12 +179,6 @@ def _reset_stress_test(args: _StressTestArgs) -> None:
babase.apptimer(1.0, babase.Call(_start_stress_test, args))
def run_gpu_benchmark() -> None:
"""Kick off a benchmark to test gpu speeds."""
# FIXME: Not wired up yet.
babase.screenmessage('Not wired up yet.', color=(1, 0, 0))
def run_media_reload_benchmark() -> None:
"""Kick off a benchmark to test media reloading speeds."""
babase.reload_media()
@ -199,6 +202,6 @@ def run_media_reload_benchmark() -> None:
babase.add_clean_frame_callback(babase.Call(doit, start_time))
# The reload starts (should add a completion callback to the
# reload func to fix this).
# The reload starts (should add a completion callback to the reload
# func to fix this).
babase.apptimer(0.05, babase.Call(delay_add, babase.apptime()))

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 22009
TARGET_BALLISTICA_BUILD = 22010
TARGET_BALLISTICA_VERSION = '1.7.37'

View File

@ -57,8 +57,8 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
plus = bs.app.plus
assert plus is not None
# Throw up some text that only clients can see so they know that the
# host is navigating menus while they're just staring at an
# Throw up some text that only clients can see so they know that
# the host is navigating menus while they're just staring at an
# empty-ish screen.
tval = bs.Lstr(
resource='hostIsNavigatingMenusText',
@ -569,7 +569,6 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
vr_depth_offset: float = 0.0,
) -> None:
# pylint: disable=too-many-locals
# Temp easter goodness.
if custom_texture is None:
custom_texture = self._get_custom_logo_tex_name()
self._custom_logo_tex_name = custom_texture
@ -604,9 +603,8 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
self._logo_node = logo.node
self._word_actors.append(logo)
# Add a bit of stop-motion-y jitter to the logo
# (unless we're in VR mode in which case its best to
# leave things still).
# Add a bit of stop-motion-y jitter to the logo (unless we're in
# VR mode in which case its best to leave things still).
assert logo.node
def jitter() -> None:

View File

@ -121,16 +121,6 @@ class BenchmarksAndStressTestsWindow(bui.MainWindow):
)
v -= 60
bui.buttonwidget(
parent=self._subcontainer,
position=((self._sub_width - button_width) * 0.5, v),
size=(button_width, 60),
autoselect=True,
label=bui.Lstr(resource=f'{self._r}.runGPUBenchmarkText'),
on_activate_call=self._run_gpu_benchmark_pressed,
)
v -= 60
bui.buttonwidget(
parent=self._subcontainer,
position=((self._sub_width - button_width) * 0.5, v),
@ -369,12 +359,6 @@ class BenchmarksAndStressTestsWindow(bui.MainWindow):
return
bui.app.classic.run_cpu_benchmark()
def _run_gpu_benchmark_pressed(self) -> None:
if bui.app.classic is None:
logging.warning('run-gpu-benchmark requires classic')
return
bui.app.classic.run_gpu_benchmark()
def _run_media_reload_benchmark_pressed(self) -> None:
if bui.app.classic is None:
logging.warning('run-media-reload-benchmark requires classic')

View File

@ -871,6 +871,11 @@ class ManualGatherTab(GatherTab):
config['Last Manual Party Connect Address'] = resolved_address
config['Last Manual Party Connect Port'] = port
config.commit()
# Store UI location to return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
bs.connect_to_party(resolved_address, port=port)
def _run_addr_fetch(self) -> None:

View File

@ -53,6 +53,11 @@ class NetScanner:
self._last_selected_host = host
def _on_activate(self, host: dict[str, Any]) -> None:
# Store UI location to return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
bs.connect_to_party(host['address'])
def update(self) -> None:

View File

@ -1081,6 +1081,11 @@ class PrivateGatherTab(GatherTab):
return
self._debug_server_comm('got valid connect response')
assert cresult.address4 is not None and cresult.port is not None
# Store UI location to return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
bs.connect_to_party(cresult.address4, port=cresult.port)
except Exception:
self._debug_server_comm('got connect response error')

View File

@ -1450,6 +1450,10 @@ class PublicGatherTab(GatherTab):
address = party.address
port = party.port
# Store UI location to return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
# Rate limit this a bit.
now = time.time()
last_connect_time = self._last_connect_attempt_time

View File

@ -552,6 +552,11 @@ class PartyQueueWindow(bui.Window):
self._last_connect_attempt_time is None
or now - self._last_connect_attempt_time > 10.0
):
# Store UI location to return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
bs.connect_to_party(
address=self._address,
port=self._port,

View File

@ -529,6 +529,11 @@ class PlayOptionsWindow(PopupWindow):
def _run_selected_playlist(self) -> None:
bui.unlock_all_input()
# Save our place in the UI that we'll return to when done.
if bs.app.classic is not None:
bs.app.classic.save_ui_state()
try:
bs.new_host_session(self._sessiontype)
except Exception:

View File

@ -355,6 +355,10 @@ class WatchWindow(bui.MainWindow):
return
bui.increment_analytics_count('Replay watch')
# Save our place in the UI so we return there when done.
if bui.app.classic is not None:
bui.app.classic.save_ui_state()
def do_it() -> None:
try:
# Reset to normal speed.

View File

@ -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 = 22009;
const int kEngineBuildNumber = 22010;
const char* kEngineVersion = "1.7.37";
const int kEngineApiVersion = 9;