diff --git a/python_payload/main.py b/python_payload/main.py index 4ba77cbffb0d025915727e2d298e821aba6563c0..51fb0c396be75622570185dcf80584405a06f866 100644 --- a/python_payload/main.py +++ b/python_payload/main.py @@ -1,118 +1,3 @@ -import time, gc +from st3m.run import run_main -ts_start = time.time() - -from st3m import logging - -log = logging.Log(__name__, level=logging.INFO) -log.info(f"starting main") -log.info(f"free memory: {gc.mem_free()}") - -import st3m - -from st3m.goose import Optional, List, ABCBase, abstractmethod - -from st3m import settings - -settings.load_all() - -from st3m.ui.view import View, ViewManager, ViewTransitionBlend -from st3m.ui.menu import ( - MenuItem, - MenuItemBack, - MenuItemForeground, - MenuItemNoop, -) - -from st3m.ui.elements.menus import FlowerMenu, SimpleMenu, SunMenu -from st3m.ui.elements import overlays - -log.info("import apps done") -log.info(f"free memory: {gc.mem_free()}") -ts_end = time.time() -log.info(f"boot took {ts_end-ts_start} seconds") - -# TODO persistent settings -from st3m.system import audio, captouch - -log.info("calibrating captouch, reset volume") -captouch.calibration_request() -audio.set_volume_dB(0) - -import leds - -leds.set_rgb(0, 255, 0, 0) - -vm = ViewManager(ViewTransitionBlend()) - -from st3m.application import discover_bundles - -bundles = discover_bundles("/flash/sys/apps") - -# Build menu structure - -menu_settings = settings.build_menu() - - -def _make_bundle_menu(kind: str) -> SimpleMenu: - entries: List[MenuItem] = [MenuItemBack()] - for bundle in bundles: - entries += bundle.menu_entries(kind) - return SimpleMenu(entries) - - -menu_system = SimpleMenu( - [ - MenuItemBack(), - MenuItemForeground("Settings", menu_settings), - MenuItemNoop("Disk Mode"), - MenuItemNoop("About"), - MenuItemNoop("Reboot"), - ], -) - -menu_main = SunMenu( - [ - MenuItemForeground("Badge", _make_bundle_menu("Badge")), - MenuItemForeground("Music", _make_bundle_menu("Music")), - MenuItemForeground("Apps", _make_bundle_menu("Apps")), - MenuItemForeground("System", menu_system), - ], -) - - -vm.push(menu_main) - -reactor = st3m.Reactor() - -# Set up top-level compositor (for combining viewmanager with overlays). -compositor = overlays.Compositor(vm) - - -# Tie compositor's debug overlay to setting. -def _onoff_debug_update() -> None: - compositor.enabled[overlays.OverlayKind.Debug] = settings.onoff_debug.value - - -_onoff_debug_update() -settings.onoff_debug.subscribe(_onoff_debug_update) - -# Configure debug overlay fragments. -debug = overlays.OverlayDebug() -debug.add_fragment(overlays.DebugReactorStats(reactor)) -compositor.add_overlay(debug) - -debug_touch = overlays.OverlayCaptouch() - - -# Tie compositor's debug touch overlay to setting. -def _onoff_debug_touch_update() -> None: - compositor.enabled[overlays.OverlayKind.Touch] = settings.onoff_debug_touch.value - - -_onoff_debug_touch_update() -settings.onoff_debug_touch.subscribe(_onoff_debug_touch_update) -compositor.add_overlay(debug_touch) - -reactor.set_top(compositor) -reactor.run() +run_main() diff --git a/python_payload/st3m/run.py b/python_payload/st3m/run.py new file mode 100644 index 0000000000000000000000000000000000000000..23e480a8f1b7e130c7a76e21bc9aba284fb343c6 --- /dev/null +++ b/python_payload/st3m/run.py @@ -0,0 +1,115 @@ +from st3m.reactor import Reactor, Responder +from st3m.goose import List +from st3m.ui.menu import MenuItem, MenuItemBack, MenuItemForeground, MenuItemNoop +from st3m.ui.elements import overlays +from st3m.ui.view import View, ViewManager, ViewTransitionBlend +from st3m.ui.elements.menus import SimpleMenu, SunMenu +from st3m.application import discover_bundles, BundleMetadata +from st3m import settings, logging + +import captouch, audio, leds, gc + +log = logging.Log(__name__, level=logging.INFO) + + +def run_responder(r: Responder) -> None: + """ + Run a given Responder in the foreground, without any menu or main firmware running in the background. + + This is useful for debugging trivial applications from the REPL. + """ + reactor = Reactor() + reactor.set_top(r) + reactor.run() + + +def _make_bundle_menu(bundles: List[BundleMetadata], kind: str) -> SimpleMenu: + entries: List[MenuItem] = [MenuItemBack()] + for bundle in bundles: + entries += bundle.menu_entries(kind) + return SimpleMenu(entries) + + +def _make_compositor(reactor: Reactor, r: Responder) -> overlays.Compositor: + """ + Set up top-level compositor (for combining viewmanager with overlays). + """ + compositor = overlays.Compositor(r) + + # Tie compositor's debug overlay to setting. + def _onoff_debug_update() -> None: + compositor.enabled[overlays.OverlayKind.Debug] = settings.onoff_debug.value + + _onoff_debug_update() + settings.onoff_debug.subscribe(_onoff_debug_update) + + # Configure debug overlay fragments. + debug = overlays.OverlayDebug() + debug.add_fragment(overlays.DebugReactorStats(reactor)) + compositor.add_overlay(debug) + + debug_touch = overlays.OverlayCaptouch() + + # Tie compositor's debug touch overlay to setting. + def _onoff_debug_touch_update() -> None: + compositor.enabled[ + overlays.OverlayKind.Touch + ] = settings.onoff_debug_touch.value + + _onoff_debug_touch_update() + settings.onoff_debug_touch.subscribe(_onoff_debug_touch_update) + compositor.add_overlay(debug_touch) + return compositor + + +def run_view(v: View) -> None: + """ + Run a given View in the foreground, with an empty ViewManager underneath. + + This is useful for debugging simple applications from the REPL. + """ + vm = ViewManager(ViewTransitionBlend()) + vm.push(v) + reactor = Reactor() + compositor = _make_compositor(reactor, vm) + reactor.set_top(compositor) + reactor.run() + + +def run_main() -> None: + log.info(f"starting main") + log.info(f"free memory: {gc.mem_free()}") + + captouch.calibration_request() + audio.set_volume_dB(0) + leds.set_rgb(0, 255, 0, 0) + leds.update() + bundles = discover_bundles("/flash/sys/apps") + + settings.load_all() + menu_settings = settings.build_menu() + menu_system = SimpleMenu( + [ + MenuItemBack(), + MenuItemForeground("Settings", menu_settings), + MenuItemNoop("Disk Mode"), + MenuItemNoop("About"), + MenuItemNoop("Reboot"), + ], + ) + menu_main = SunMenu( + [ + MenuItemForeground("Badge", _make_bundle_menu(bundles, "Badge")), + MenuItemForeground("Music", _make_bundle_menu(bundles, "Music")), + MenuItemForeground("Apps", _make_bundle_menu(bundles, "Apps")), + MenuItemForeground("System", menu_system), + ], + ) + run_view(menu_main) + + +__all__ = [ + "run_responder", + "run_view", + "run_main", +]