Skip to content

Commit

Permalink
app-modes now discoverable for testing via meta-tags
Browse files Browse the repository at this point in the history
  • Loading branch information
efroemling committed Nov 15, 2024
1 parent 8b88d62 commit d9024b9
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 100 deletions.
72 changes: 36 additions & 36 deletions .efrocachemap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### 1.7.37 (build 22101, api 9, 2024-11-13)
### 1.7.37 (build 22102, api 9, 2024-11-14)
- 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.
Expand Down Expand Up @@ -156,6 +156,14 @@
up `make preflight` to use this to keep things moving a bit faster. If you are
not familiar with it, the `preflight` target is handy to run before committing
code to git.
- The app-modes tab in the dev-console now uses the meta tag system to discover
testable app-modes. Previously this would simply list the `default_app_modes`
listed in the projectconfig.json. So now it is possible to make and explicitly
test new app modes via mod scripts on vanilla game builds. Note that the game
still uses the `default_app_modes` projectconfig.json value when selecting
app-modes at runtime; to change this you need to either change your
projectconfig and rebuild or replace `ba*.app.mode_selector` at runtime with
a custom selector that selects your custom app-mode(s).

### 1.7.36 (build 21944, api 8, 2024-07-26)
- Wired up Tokens, BombSquad's new purchasable currency. The first thing these
Expand Down
2 changes: 2 additions & 0 deletions src/assets/ba_data/python/babase/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"""
# pylint: disable=redefined-builtin

# ba_meta require api 9

# The stuff we expose here at the top level is our 'public' api for use
# from other modules/packages. Code *within* this package should import
# things from this package's submodules directly to reduce the chance of
Expand Down
18 changes: 0 additions & 18 deletions src/assets/ba_data/python/babase/_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,6 @@ def app_mode_for_intent(

# __DEFAULT_APP_MODE_SELECTION_END__

@override
def testable_app_modes(self) -> list[type[AppMode]]:
# pylint: disable=cyclic-import

# __DEFAULT_TESTABLE_APP_MODES_BEGIN__
# This section generated by batools.appmodule; do not edit.

# Return all our default_app_modes as testable.
# (generated from 'default_app_modes' in projectconfig).
import baclassic
import babase

return [
baclassic.ClassicAppMode,
babase.EmptyAppMode,
]
# __DEFAULT_TESTABLE_APP_MODES_END__

def __init__(self) -> None:
"""(internal)
Expand Down
12 changes: 0 additions & 12 deletions src/assets/ba_data/python/babase/_appmodeselector.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,3 @@ def app_mode_for_intent(self, intent: AppIntent) -> type[AppMode] | None:
limited to logic thread use/etc.
"""
raise NotImplementedError()

def testable_app_modes(self) -> list[type[AppMode]]:
"""Return a list of modes to appear in the dev-console app-mode ui.
The user can switch between these app modes for testing. App-modes
will be passed an AppIntentDefault when selected by the user.
Note that in normal circumstances AppModes should never be
selected explicitly by the user but rather determined implicitly
based on AppIntents.
"""
raise NotImplementedError()
39 changes: 35 additions & 4 deletions src/assets/ba_data/python/babase/_devconsoletabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,43 @@ def refresh(self) -> None:
class DevConsoleTabAppModes(DevConsoleTab):
"""Tab to switch app modes."""

def __init__(self) -> None:
self._app_modes: list[type[AppMode]] | None = None
self._app_modes_loading = False

def _on_app_modes_loaded(self, modes: list[type[AppMode]]) -> None:
from babase._appintent import AppIntentDefault

intent = AppIntentDefault()

# Limit to modes that can handle default intents since that's
# what we use.
self._app_modes = [
mode for mode in modes if mode.can_handle_intent(intent)
]
self.request_refresh()

@override
def refresh(self) -> None:
from babase import AppMode

# Kick off a load if applicable.
if self._app_modes is None and not self._app_modes_loading:
_babase.app.meta.load_exported_classes(
AppMode, self._on_app_modes_loaded
)

# Just say 'loading' if we don't have app-modes yet.
if self._app_modes is None:
self.text(
'Loading...', pos=(0, 30), h_anchor='center', h_align='center'
)
return

bwidth = 260
bpadding = 5
modes = _babase.app.mode_selector.testable_app_modes()
xoffs = -0.5 * bwidth * len(modes)

xoffs = -0.5 * bwidth * len(self._app_modes)

self.text(
'Available AppModes:',
Expand All @@ -49,7 +79,7 @@ def refresh(self) -> None:
v_align='center',
)
# pylint: disable=protected-access
for i, mode in enumerate(modes):
for i, mode in enumerate(self._app_modes):
self.button(
f'{mode.__module__}.{mode.__qualname__}',
pos=(xoffs + i * bwidth + bpadding, 10),
Expand Down Expand Up @@ -78,7 +108,8 @@ def _set_app_mode(self, mode: type[AppMode]) -> None:
_babase.app.set_intent(intent)

# Slight hackish: need to wait a moment before refreshing to
# pick up the new mode, as mode switches are asynchronous.
# pick up the newly current mode, as mode switches are
# asynchronous.
_babase.apptimer(0.1, self.request_refresh)


Expand Down
1 change: 1 addition & 0 deletions src/assets/ba_data/python/babase/_emptyappmode.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from babase import AppIntent


# ba_meta export babase.AppMode
class EmptyAppMode(AppMode):
"""An AppMode that does not do much at all."""

Expand Down
18 changes: 11 additions & 7 deletions src/assets/ba_data/python/babase/_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def run(self) -> None:
except Exception:
logging.exception("metascan: Error scanning '%s'.", subpath)

# Sort our results
# Sort our results.
for exportlist in self.results.exports.values():
exportlist.sort()

Expand Down Expand Up @@ -384,12 +384,16 @@ def _process_module_meta_tags(
# meta_lines is just anything containing '# ba_meta '; make sure
# the ba_meta is in the right place.
if mline[0] != 'ba_meta':
logging.warning(
'metascan: %s:%d: malformed ba_meta statement.',
subpath,
lindex + 1,
)
self.results.announce_errors_occurred = True
# Make an exception for this specific file, otherwise we
# get lots of warnings about ba_meta showing up in weird
# places here.
if str(subpath) not in ('babase/_meta.py',):
logging.warning(
'metascan: %s:%d: malformed ba_meta statement.',
subpath,
lindex + 1,
)
self.results.announce_errors_occurred = True
elif (
len(mline) == 4 and mline[1] == 'require' and mline[2] == 'api'
):
Expand Down
2 changes: 1 addition & 1 deletion src/assets/ba_data/python/babase/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def on_meta_scan_complete(self) -> None:
# that weren't covered by the meta stuff above, either creating
# plugin-specs for them or clearing them out. This covers
# plugins with api versions not matching ours, plugins without
# ba_meta tags, and plugins that have since disappeared.
# ba_*meta tags, and plugins that have since disappeared.
assert isinstance(plugstates, dict)
wrong_api_prefixes = [f'{m}.' for m in results.incorrect_api_modules]

Expand Down
3 changes: 2 additions & 1 deletion src/assets/ba_data/python/baclassic/_appmode.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from bauiv1 import UIV1AppSubsystem, MainWindow, MainWindowState


# ba_meta export babase.AppMode
class ClassicAppMode(AppMode):
"""AppMode for the classic BombSquad experience."""

Expand Down Expand Up @@ -156,7 +157,7 @@ def update_for_primary_account(
"""Update subscriptions/etc. for a new primary account state."""
assert in_logic_thread()

if bool(False):
if bool(True):
assert app.plus is not None
if account is None:
self._test_sub = None
Expand Down
2 changes: 1 addition & 1 deletion src/assets/ba_data/python/baenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 22101
TARGET_BALLISTICA_BUILD = 22102
TARGET_BALLISTICA_VERSION = '1.7.37'


Expand Down
2 changes: 1 addition & 1 deletion src/ballistica/shared/ballistica.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 22101;
const int kEngineBuildNumber = 22102;
const char* kEngineVersion = "1.7.37";
const int kEngineApiVersion = 9;

Expand Down
39 changes: 21 additions & 18 deletions tools/batools/appmodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,24 +226,27 @@ def _is_valid_app_mode(amode: str) -> bool:
keep_markers=True,
)

contents = (
'# Return all our default_app_modes as testable.\n'
"# (generated from 'default_app_modes' in projectconfig).\n"
)
for mode in default_app_modes:
contents += f'import {_module_for_app_mode(mode)}\n'
contents += '\n'
contents += 'return [\n'
for mode in default_app_modes:
contents += f' {mode},\n'
contents += ']'
out = replace_section(
out,
f'{indent}# __DEFAULT_TESTABLE_APP_MODES_BEGIN__\n',
f'{indent}# __DEFAULT_TESTABLE_APP_MODES_END__\n',
textwrap.indent(f'{info}\n\n{contents}\n', indent),
keep_markers=True,
)
# Disabling this for now; will probably remove permanently. Testable
# app mode discovery now uses meta discovery system.
if bool(False):
contents = (
'# Return all our default_app_modes as testable.\n'
"# (generated from 'default_app_modes' in projectconfig).\n"
)
for mode in default_app_modes:
contents += f'import {_module_for_app_mode(mode)}\n'
contents += '\n'
contents += 'return [\n'
for mode in default_app_modes:
contents += f' {mode},\n'
contents += ']'
out = replace_section(
out,
f'{indent}# __DEFAULT_TESTABLE_APP_MODES_BEGIN__\n',
f'{indent}# __DEFAULT_TESTABLE_APP_MODES_END__\n',
textwrap.indent(f'{info}\n\n{contents}\n', indent),
keep_markers=True,
)

# Note: we *should* format this string, but because this code
# runs with every project update I'm just gonna try to keep the
Expand Down

0 comments on commit d9024b9

Please sign in to comment.