st3m.application module

At their heart, flow3r applications are single threaded. The execution model is a simple conditional round robin:

# this is very simplified and does not include initializing/entering/exiting applications
while True:
    ins = input_backend.collect()
    delta_ms = get_time_since_last_calling_this()
    if os.needs_to_do_things(ins):
        os.do_things()
    application.think(ins, delta_ms)
    if graphics_backend.can_receive_data_for_next_frame():
        application.draw(graphics_backend.ctx)

Note that the .draw() method merely provides list of draw instructions for the backend and doesn’t block during rendering so that the .think() cycle can resume quickly.

The exact time when delta_ms is collected is not defined behavior at this point in time. We’ll see if we can move it closer to Application.think() at some point in the future, it would make more sense.

class st3m.application.Application
think(ins: InputState, delta_ms: int) None

Override this method. Please call super().think(ins, delta_ms) at the start of your implementation.

This is the main loop of the application. The operating system provides the state of all hardware inputs ins as well as the time since the method got called last delta_ms.

input: st3m.input.InputController

Provides edges for button-like objects to be processed by .think().

draw(ctx: ctx.Context) None

Override this method.

This method generates a drawlist for the next display update. Note that the display isn’t cleared in between, so partial redraws are possible and recommended for best framerates. However, during the enter and exit animation this is not true; do full redraws in-between .on_enter() and .on_enter_done() as well as .on_exit() and .on_exit_done().

get_help() str

Override this method.

The flow3r OS provides a help text reader that users can open when they are in an application. Whenever it is opened, this method is called to request help text that may be specific to the state of the application.

In the simplest case you can just return a static string that provides a quick description and manual. Many flow3r applications are not quite obvious to the user, so we recommend putting at least a tiny bit in here. If you have a complicated UI state machine or just many features, go nuts with changing output depending on what the user is actually seeing at the moment :D!

__init__(app_ctx: ApplicationContext) None

Override this method. Please call super().__init__(app_ctx) at the start of your implementation.

This initializer is called only when the application is opened for the first time. The application object is never destroyed under normal circumstances. This has two important implications:

  • Since all data stored in the application object is retained, state isn’t lost when the application is exited.

  • Since the application object is not garbage collected upon exit, the memory used by the application is not freed by default. Equally, backend resources such as open files or bl00mbox channels are not being returned to the operating system. Please make sure to use the .on_enter()/.on_exit() methods to keep the idle footprint of the application low.

In practice, this can be easily achieved by moving most parts of a naive .__init__() into .on_enter() and use the corresponding destructor of resources, in case of data structures setting all references to None is a comfortable approach to allow them to be garbage collected.

Every .__init__() call by the operating system is followed up by an .on_enter() call.

on_enter(vm) None

Override this method. Please call super().on_enter(vm) at the start of your implementation.

This method is called each time the application is entered before the first .think() call. Use this to initialize resources and load application save data.

on_exit() None

Override this method.

This method is called each time the application is exited. Use this to destroy resources initalized by .on_enter() and save application save data.

on_enter_done() None

Override this method.

The flow3r OS does a little slide-in animation when entering an application. This method is called when this animation is done, whereas .on_enter() is called at the beginning.

on_exit_done() None

Override this method.

Analogous to .on_enter_done(), called when the exit animation is finished.

override_os_button_back: bool = False

By default, applications are exited when a user presses the back button (i.e., OS button down). You can override this behavior by setting this attribute to True. Set it back to False to terminate the override and allow users to exit.

The design philosophy of flow3r entails that users shouldn’t get stuck in applications and be forced to restart. Ideally, all applications should exit if you hit the back button often enough. Kindly try to respect this design goal in your application design, and if not possible provide another reasonably obvious way to exit.

override_os_button_volume: bool = False

Similar to .override_os_button_back, but for the volume control feature (i.e., OS button left/right).

Due to future plans for this button on the OS side we strongly discourage overriding this button if you are writing any type of music applications, it will collide with another feature that we do not dare to announce yet :P.

app_ctx: ApplicationContext

Created by super().__init__(app_ctx). Contains paths and other metadata. Not related to the ctx module (or the argument of .draw()).

class st3m.application.ApplicationContext
bundle_path: str

The path to the application code directory. For example, the __init__.py that is executed by the OS is located at the root of this directory.

This directory is deleted when the app is uninstalled, you might want to save userdata elsewhere. TODO (moon2): add API for userdata save/load paths (sadly complicated :/)