ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_app.h File Reference

Zero-heap app framework: lifecycle + static registry + launcher (#146). More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_widget.h"
Include dependency graph for ra8_app.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_app_vtable_t
 App lifecycle callbacks (shared by all instances of one app). More...
struct  ra8_app
struct  ra8_app_registry_t
 Fixed table of registered apps + the focused index. More...
struct  ra8_app_nav_t
 A bounded back-stack of app ids layered over a registry (zero-heap). More...

Typedefs

typedef struct ra8_app ra8_app_t

Enumerations

enum  ra8_app_const_t : int16_t { k_ra8_app_none = -1 }
 Sentinels for the app registry. More...
enum  ra8_app_state_t : uint8_t {
  k_ra8_app_state_unmounted = 0U ,
  k_ra8_app_state_background = 1U ,
  k_ra8_app_state_foreground = 2U
}
 Lifecycle state of one app within the framework's state machine. More...

Functions

ra8_err_t ra8_app_registry_init (ra8_app_registry_t *reg, ra8_app_t **storage, uint16_t cap)
 Bind a registry to caller-owned pointer storage (empty, no focus).
ra8_err_t ra8_app_register (ra8_app_registry_t *reg, ra8_app_t *app)
 Register an app (calls its init once) and add it to the registry.
ra8_err_t ra8_app_find (const ra8_app_registry_t *reg, uint16_t id, int16_t *out_idx)
 Find a registered app's index by id.
ra8_err_t ra8_app_launch (ra8_app_registry_t *reg, uint16_t id)
 Launch (focus) the app with id, running the focus lifecycle.
ra8_err_t ra8_app_active (const ra8_app_registry_t *reg, ra8_app_t **out_app)
 Get the currently focused app.
ra8_err_t ra8_app_route_input (ra8_app_registry_t *reg, const ra8_widget_event_t *ev, bool *out_handled)
 Route an input event to the focused app.
ra8_err_t ra8_app_tick (ra8_app_registry_t *reg)
 Run the focused app's per-frame tick (no-op if none / NULL).
ra8_err_t ra8_app_render (ra8_app_registry_t *reg)
 Run the focused app's render (on-target; no-op if none / NULL).
ra8_err_t ra8_app_count (const ra8_app_registry_t *reg, uint16_t *out_count)
 Number of registered apps (for the launcher to list).
ra8_err_t ra8_app_at (const ra8_app_registry_t *reg, uint16_t idx, ra8_app_t **out_app)
 Get the app at registry index idx (launcher enumeration).
ra8_err_t ra8_app_state (const ra8_app_registry_t *reg, uint16_t id, ra8_app_state_t *out_state)
 Report an app's lifecycle state, derived from the registry.
ra8_err_t ra8_app_uninstall (ra8_app_registry_t *reg, uint16_t id)
 Uninstall (unmount) a removable, non-focused app from the registry.
ra8_err_t ra8_app_nav_init (ra8_app_nav_t *nav, ra8_app_registry_t *reg, uint16_t *storage, uint16_t cap)
 Bind a navigation back-stack to a registry + caller-owned storage.
ra8_err_t ra8_app_nav_go (ra8_app_nav_t *nav, uint16_t id)
 Focus app id, pushing the outgoing app onto the back-stack.
ra8_err_t ra8_app_nav_go_index (ra8_app_nav_t *nav, uint16_t idx)
 Focus the app at registry index idx (launcher select-by-position).
ra8_err_t ra8_app_nav_back (ra8_app_nav_t *nav, bool *out_popped)
 Return to the most recently pushed app (pop the back-stack).
ra8_err_t ra8_app_nav_depth (const ra8_app_nav_t *nav, uint16_t *out_depth)
 Current back-stack depth (apps the user can still go back through).

Detailed Description

Zero-heap app framework: lifecycle + static registry + launcher (#146).

ra8_app makes each major function a first-class app with a lifecycle, launched from the chrome (issue #146): opening a book launches the EPUB reader app; the library organizer is an app; settings is an app. The framework owns nothing but the routing – it calls the active app's lifecycle, forwards input + render, and tracks focus. Each app builds its UI by composing ra8_widgets (issue #145), so an "app = a widget tree".

Zero-heap (NASA Rule 3): apps are static instances registered into a caller-owned pointer array. Nothing is allocated; the registry is a fixed table of ra8_app_t*.

Core uninstallable. Issue #146's headline rule – "core functionality should be able to be uninstalled" – is enforced two ways:

  • Build time: a Kconfig-style guard around the registration call (e.g. #if RA8_APP_SETTINGS) excludes an app from the registry, so the firmware ships only the apps you want. The framework needs no special support: an unregistered app is simply absent, and ra8_app_count / ra8_app_find never see it.
  • Run time: ra8_app_uninstall unmounts a removable app (its deinit runs and it leaves the registry) but refuses a core app (removable == false). The removable flag thereby has teeth: a launcher offers "remove" only on removable apps, and the framework guarantees a core app can never be torn down at run time.

The lifecycle / registration / routing logic is pure (no framebuffer), so it is host-unit-tested; the per-app render is the only on-target callback. ra8_app_state reports each app's place in the state machine below, derived from the registry so it can never drift from the real focus / membership.

State Machine

[Ring 5 / UI] {World: NS}

Since
0.1.0

Definition in file ra8_app.h.

Typedef Documentation

◆ ra8_app_t

typedef struct ra8_app ra8_app_t

Enumeration Type Documentation

◆ ra8_app_const_t

enum ra8_app_const_t : int16_t

Sentinels for the app registry.

Enumerator
k_ra8_app_none 

No active app / not found.

Definition at line 83 of file ra8_app.h.

◆ ra8_app_state_t

enum ra8_app_state_t : uint8_t

Lifecycle state of one app within the framework's state machine.

Every app moves through a small, explicit state machine the framework drives: an unregistered app is mounted by ra8_app_register (its init runs), entering k_ra8_app_state_background; ra8_app_launch focuses it into k_ra8_app_state_foreground (and suspends the outgoing app back to k_ra8_app_state_background); ra8_app_uninstall unmounts a background app (its deinit runs) back to k_ra8_app_state_unmounted. The state is not a stored field: ra8_app_state derives it from the registry (membership + focused index), so the single source of truth is the registry and the reported state can never drift from the real focus / membership.

Invariant
At most one app is k_ra8_app_state_foreground at a time (the registry's active index).
State table:
Reported state Condition
k_ra8_app_state_unmounted id not registered (or after uninstall)
k_ra8_app_state_background registered, not the focused app
k_ra8_app_state_foreground registered and the focused (active) app
See also
ra8_app_state
Since
0.1.0
Enumerator
k_ra8_app_state_unmounted 

Not registered (initial / after uninstall).

k_ra8_app_state_background 

Mounted (init ran), not focused.

k_ra8_app_state_foreground 

Mounted and focused (the active app).

Definition at line 115 of file ra8_app.h.

Function Documentation

◆ ra8_app_active()

ra8_err_t ra8_app_active ( const ra8_app_registry_t * reg,
ra8_app_t ** out_app )
nodiscard

Get the currently focused app.

Parameters
[in]regRegistry.
[out]out_appReceives the active app pointer, or NULL if none.
Returns
ra8_err_t
Return values
k_ra8_okReported (see *out_app).
k_ra8_err_null_ptrreg or out_app is NULL.
Precondition
reg and out_app non-NULL.
Postcondition
*out_app == NULL iff no app is focused.
Note
Pure read; not thread-safe vs concurrent mutation.
Since
0.1.0

Definition at line 115 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, k_ra8_app_none, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_selfcheck(), app_shell_selfcheck(), ra8_app_nav_go(), wd_active_name(), and wd_service_request().

◆ ra8_app_at()

ra8_err_t ra8_app_at ( const ra8_app_registry_t * reg,
uint16_t idx,
ra8_app_t ** out_app )
nodiscard

Get the app at registry index idx (launcher enumeration).

Parameters
[in]regRegistry.
[in]idxIndex in [0, count).
[out]out_appReceives the app pointer.
Returns
ra8_err_t
Return values
k_ra8_okReported.
k_ra8_err_null_ptrreg or out_app is NULL.
k_ra8_err_out_of_rangeidx >= count.
Precondition
reg and out_app non-NULL.
Postcondition
On success *out_app is reg->apps[idx].
Note
Pure read.
Since
0.1.0

Definition at line 174 of file ra8_app.c.

References ra8_app_registry_t::apps, ra8_app_registry_t::count, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_shell_log_menu(), ra8_app_nav_go_index(), wd_neighbor_id(), wd_tabbar_on_input(), and wd_tabbar_render().

◆ ra8_app_count()

ra8_err_t ra8_app_count ( const ra8_app_registry_t * reg,
uint16_t * out_count )
nodiscard

Number of registered apps (for the launcher to list).

Parameters
[in]regRegistry.
[out]out_countReceives reg->count.
Returns
ra8_err_t k_ra8_ok, or k_ra8_err_null_ptr.
Precondition
reg and out_count non-NULL.
Postcondition
*out_count == reg->count.
Note
Pure read.
Since
0.1.0

Definition at line 166 of file ra8_app.c.

References ra8_app_registry_t::count, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_banner(), app_shell_banner(), app_shell_log_menu(), app_shell_uninstall_demo(), wd_check_touch_dispatch(), wd_neighbor_id(), wd_print_banner(), wd_tabbar_on_input(), and wd_tabbar_render().

◆ ra8_app_find()

ra8_err_t ra8_app_find ( const ra8_app_registry_t * reg,
uint16_t id,
int16_t * out_idx )
nodiscard

Find a registered app's index by id.

Parameters
[in]regRegistry.
[in]idApp id to find.
[out]out_idxReceives the index in [0, count), or k_ra8_app_none.
Returns
ra8_err_t
Return values
k_ra8_okSearch done (see *out_idx).
k_ra8_err_null_ptrreg or out_idx is NULL.
Precondition
reg and out_idx non-NULL.
Postcondition
*out_idx == k_ra8_app_none iff no app has id.
Note
Pure; not thread-safe vs concurrent mutation.
Since
0.1.0

Definition at line 34 of file ra8_app.c.

References ra8_app_registry_t::apps, ra8_app_registry_t::count, ra8_app::id, k_ra8_app_none, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_app_launch(), ra8_app_register(), ra8_app_state(), and ra8_app_uninstall().

◆ ra8_app_launch()

ra8_err_t ra8_app_launch ( ra8_app_registry_t * reg,
uint16_t id )
nodiscard

Launch (focus) the app with id, running the focus lifecycle.

If a different app is focused, its on_leave runs first; then the target becomes active and its on_enter runs. Launching the already-active app is an idempotent no-op (no lifecycle calls) so a re-tap on the current app does not flicker.

Parameters
[in,out]regRegistry.
[in]idApp id to focus.
Returns
ra8_err_t
Return values
k_ra8_okFocused (or already focused).
k_ra8_err_null_ptrreg is NULL.
k_ra8_err_not_foundNo app has id.
Precondition
reg non-NULL.
Postcondition
On success reg->active indexes the app whose id is id.
Note
Not thread-safe.
Since
0.1.0

Definition at line 78 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, k_ra8_app_none, k_ra8_err_not_found, k_ra8_ok, ra8_app_find(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by er_render_current(), er_render_nag_region(), main(), ra8_app_nav_back(), ra8_app_nav_go(), wa_run_two_apps(), wd_selfcheck(), and wd_service_request().

◆ ra8_app_nav_back()

ra8_err_t ra8_app_nav_back ( ra8_app_nav_t * nav,
bool * out_popped )
nodiscard

Return to the most recently pushed app (pop the back-stack).

Pops the top of the back-stack and focuses that app through ra8_app_launch, firing the focus lifecycle. An empty back-stack is not an error – it reports *out_popped == false so a chrome can decide what "back" means at the root (exit, no-op, etc.). The pop is committed only after the launch succeeds.

Parameters
[in,out]navNavigation state.
[out]out_poppedReceives true if an app was popped + focused.
Returns
ra8_err_t
Return values
k_ra8_okDone (see out_popped); false at the root.
k_ra8_err_null_ptrnav, nav->reg, or out_popped is NULL.
k_ra8_err_not_foundThe popped id is no longer registered.
Precondition
nav, nav->reg, and out_popped non-NULL.
Postcondition
On *out_popped == true the registry's active app is the popped id and nav->depth shrank by one; otherwise both are unchanged.
Note
Not thread-safe.
See also
ra8_app_nav_go
Since
0.1.0

Definition at line 251 of file ra8_app.c.

References ra8_app_nav_t::depth, k_ra8_ok, ra8_app_launch(), RA8_CHECK_NULL_PTR, ra8_app_nav_t::reg, s_tag, and ra8_app_nav_t::stack.

Referenced by app_launch_switch_and_back(), app_shell_back_to_root(), and app_shell_settings_round_trip().

◆ ra8_app_nav_depth()

ra8_err_t ra8_app_nav_depth ( const ra8_app_nav_t * nav,
uint16_t * out_depth )
nodiscard

Current back-stack depth (apps the user can still go back through).

Parameters
[in]navNavigation state.
[out]out_depthReceives nav->depth.
Returns
ra8_err_t
Return values
k_ra8_okReported.
k_ra8_err_null_ptrnav or out_depth is NULL.
Precondition
nav and out_depth non-NULL.
Postcondition
*out_depth == nav->depth.
No navigation state is modified.
Note
Pure read; not thread-safe vs concurrent mutation.
Since
0.1.0

Definition at line 270 of file ra8_app.c.

References ra8_app_nav_t::depth, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_enter_reader(), app_launch_switch_and_back(), app_shell_back_to_root(), app_shell_launch_library(), app_shell_open_reader(), and app_shell_settings_round_trip().

◆ ra8_app_nav_go()

ra8_err_t ra8_app_nav_go ( ra8_app_nav_t * nav,
uint16_t id )
nodiscard

Focus app id, pushing the outgoing app onto the back-stack.

Composes ra8_app_launch (so the focus lifecycle fires) and remembers the app that lost focus so ra8_app_nav_back can return to it. The outgoing app is pushed only when a different app was focused: launching the already focused app, or the very first launch (no prior focus), pushes nothing – the trail records real navigation, not idempotent re-taps. Capacity is checked before the launch so a full back-stack leaves the focus unchanged.

Parameters
[in,out]navNavigation state.
[in]idApp id to focus.
Returns
ra8_err_t
Return values
k_ra8_okFocused (and pushed if a different app left).
k_ra8_err_null_ptrnav or nav->reg is NULL.
k_ra8_err_no_memA push was required but the back-stack is full.
k_ra8_err_not_foundNo app has id (focus + trail unchanged).
Precondition
nav and nav->reg non-NULL.
Postcondition
On success the registry's active app is the one whose id is id.
nav->depth grew by one iff a different app was previously focused.
Note
Not thread-safe.
See also
ra8_app_nav_back
Since
0.1.0

Definition at line 201 of file ra8_app.c.

References ra8_app_nav_t::cap, ra8_app_nav_t::depth, k_ra8_err_no_mem, k_ra8_ok, ra8_app_active(), ra8_app_launch(), RA8_CHECK_NULL_PTR, ra8_app_nav_t::reg, s_tag, and ra8_app_nav_t::stack.

Referenced by app_launch_enter_reader(), app_launch_switch_and_back(), app_shell_open_reader(), app_shell_settings_round_trip(), and ra8_app_nav_go_index().

◆ ra8_app_nav_go_index()

ra8_err_t ra8_app_nav_go_index ( ra8_app_nav_t * nav,
uint16_t idx )
nodiscard

Focus the app at registry index idx (launcher select-by-position).

A home/launcher (the chrome) enumerates apps by positionra8_app_count gives the tile count and ra8_app_at maps a tile back to its app – then lets the user pick the n-th tile. This is the bridge that resolves that position to the app's id and focuses it through ra8_app_nav_go, so the outgoing app is pushed onto the back-stack exactly as a by-id navigation would. It is the by-index sibling of ra8_app_nav_go: the launcher thinks in indices, the back-stack records ids, and this couples the two. A NULL slot at idx (a caller-cleared storage entry) is rejected rather than focused.

Parameters
[in,out]navNavigation state.
[in]idxRegistry index in [0, count) of the app to focus.
Returns
ra8_err_t
Return values
k_ra8_okFocused (and pushed if a different app left).
k_ra8_err_null_ptrnav, nav->reg, or the slot at idx is NULL.
k_ra8_err_out_of_rangeidx >= count.
k_ra8_err_no_memA push was required but the back-stack is full.
k_ra8_err_not_foundThe resolved id is no longer registered.
Precondition
nav is non-NULL.
nav->reg is non-NULL (the navigation is bound to a registry).
Postcondition
On success the registry's active app is reg->apps[idx].
nav->depth grew by one iff a different app was previously focused.
Note
Not thread-safe.
See also
ra8_app_nav_go The by-id navigation this composes.
ra8_app_at The index enumeration a launcher pairs with this.
Since
0.1.0

Definition at line 238 of file ra8_app.c.

References k_ra8_ok, ra8_app_at(), ra8_app_nav_go(), RA8_CHECK_NULL_PTR, ra8_app_nav_t::reg, and s_tag.

Referenced by app_shell_launch_library().

◆ ra8_app_nav_init()

ra8_err_t ra8_app_nav_init ( ra8_app_nav_t * nav,
ra8_app_registry_t * reg,
uint16_t * storage,
uint16_t cap )
nodiscard

Bind a navigation back-stack to a registry + caller-owned storage.

Parameters
[out]navNavigation state to initialise.
[in]regRegistry the navigation focuses apps in (non-NULL).
[in]storageArray of uint16_t the back-stack fills with app ids.
[in]capCapacity of storage (>= 1).
Returns
ra8_err_t
Return values
k_ra8_okInitialised.
k_ra8_err_null_ptrnav, reg, or storage is NULL.
k_ra8_err_invalid_argcap is 0.
Precondition
nav, reg, and storage non-NULL; cap >= 1.
Postcondition
nav->depth == 0 (empty trail).
nav->reg == reg and nav->cap == cap.
Note
Not thread-safe.
See also
ra8_app_nav_go
Since
0.1.0

Definition at line 186 of file ra8_app.c.

References ra8_app_nav_t::cap, ra8_app_nav_t::depth, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_app_nav_t::reg, s_tag, and ra8_app_nav_t::stack.

Referenced by app_launch_register(), and app_shell_register().

◆ ra8_app_register()

ra8_err_t ra8_app_register ( ra8_app_registry_t * reg,
ra8_app_t * app )
nodiscard

Register an app (calls its init once) and add it to the registry.

Rejects a duplicate id. On success the app's init (if any) runs; a non-ok init leaves the app unregistered and returns its error. This is the point a build-time guard (#if RA8_APP_X) wraps to exclude an app.

Parameters
[in,out]regRegistry.
[in]appApp instance (non-NULL, vt non-NULL).
Returns
ra8_err_t
Return values
k_ra8_okRegistered + initialised.
k_ra8_err_null_ptrreg or app (or app->vt) is NULL.
k_ra8_err_no_memRegistry already at cap.
k_ra8_err_conflictAn app with the same id is registered.
<init'serror> app->vt->init returned non-ok.
Precondition
app->vt non-NULL.
Postcondition
On success reg->count grew by one and app->initialized == true.
On any failure the registry is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 48 of file ra8_app.c.

References ra8_app_registry_t::apps, ra8_app_registry_t::cap, ra8_app_registry_t::count, k_ra8_app_none, k_ra8_err_conflict, k_ra8_err_no_mem, k_ra8_ok, ra8_app_find(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_register(), app_shell_add(), er_apps_init(), main(), and wd_register_apps().

◆ ra8_app_registry_init()

ra8_err_t ra8_app_registry_init ( ra8_app_registry_t * reg,
ra8_app_t ** storage,
uint16_t cap )
nodiscard

Bind a registry to caller-owned pointer storage (empty, no focus).

Parameters
[out]regRegistry to initialise.
[in]storageArray of ra8_app_t* the registry fills.
[in]capCapacity of storage (>= 1).
Returns
ra8_err_t
Return values
k_ra8_okInitialised.
k_ra8_err_null_ptrreg or storage is NULL.
k_ra8_err_invalid_argcap is 0.
Precondition
reg and storage non-NULL; cap >= 1.
Postcondition
reg->count == 0 and reg->active == k_ra8_app_none.
Note
Not thread-safe.
Since
0.1.0

Definition at line 20 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, ra8_app_registry_t::cap, ra8_app_registry_t::count, k_ra8_app_none, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_register(), app_shell_register(), er_apps_init(), main(), and wd_register_apps().

◆ ra8_app_render()

ra8_err_t ra8_app_render ( ra8_app_registry_t * reg)
nodiscard

Run the focused app's render (on-target; no-op if none / NULL).

Parameters
[in,out]regRegistry.
Returns
ra8_err_t k_ra8_ok, or k_ra8_err_null_ptr if reg is NULL.
Precondition
reg non-NULL.
Postcondition
The active app's render ran (if any).
The registry's focus / membership state is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 153 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, k_ra8_app_none, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_enter_reader(), app_shell_launch_library(), app_shell_open_reader(), app_shell_settings_round_trip(), er_render_current(), er_render_nag_region(), wa_run_two_apps(), wd_render_active(), and wd_selfcheck().

◆ ra8_app_route_input()

ra8_err_t ra8_app_route_input ( ra8_app_registry_t * reg,
const ra8_widget_event_t * ev,
bool * out_handled )
nodiscard

Route an input event to the focused app.

Parameters
[in,out]regRegistry.
[in]evThe event.
[out]out_handledReceives true if the active app consumed it.
Returns
ra8_err_t
Return values
k_ra8_okRouted (see *out_handled); false if no focus.
k_ra8_err_null_ptrreg, ev, or out_handled is NULL.
Precondition
ev and out_handled non-NULL.
Postcondition
*out_handled is the active app's on_input result, or false.
Note
Not thread-safe.
Since
0.1.0

Definition at line 124 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, k_ra8_app_none, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_launch_route_back(), app_shell_open_reader(), wd_check_touch_dispatch(), and wd_route_button().

◆ ra8_app_state()

ra8_err_t ra8_app_state ( const ra8_app_registry_t * reg,
uint16_t id,
ra8_app_state_t * out_state )
nodiscard

Report an app's lifecycle state, derived from the registry.

Maps id to a ra8_app_state_t: an id that is not registered reports k_ra8_app_state_unmounted; a registered app reports k_ra8_app_state_foreground when it is the registry's focused (active) app and k_ra8_app_state_background otherwise. Nothing is stored per app – the state is computed from membership plus the focused index, so it cannot disagree with ra8_app_active or ra8_app_find. A launcher uses this to draw the focused tile differently and to decide whether a "remove" affordance applies (only background apps can be uninstalled).

Parameters
[in]regRegistry.
[in]idApp id to query.
[out]out_stateReceives the derived ra8_app_state_t.
Returns
ra8_err_t
Return values
k_ra8_okReported (see out_state).
k_ra8_err_null_ptrreg or out_state is NULL.
Precondition
reg and out_state non-NULL.
Postcondition
*out_state == k_ra8_app_state_unmounted iff no app has id.
*out_state == k_ra8_app_state_foreground iff id is the active app.
Note
Pure read; not thread-safe vs concurrent mutation.
See also
ra8_app_launch
ra8_app_uninstall
Since
0.1.0

Definition at line 279 of file ra8_app.c.

References ra8_app_registry_t::active, k_ra8_app_none, k_ra8_app_state_background, k_ra8_app_state_foreground, k_ra8_app_state_unmounted, k_ra8_ok, ra8_app_find(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_shell_uninstall_demo().

◆ ra8_app_tick()

ra8_err_t ra8_app_tick ( ra8_app_registry_t * reg)
nodiscard

Run the focused app's per-frame tick (no-op if none / NULL).

Parameters
[in,out]regRegistry.
Returns
ra8_err_t k_ra8_ok, or k_ra8_err_null_ptr if reg is NULL.
Precondition
reg non-NULL.
Postcondition
The active app's tick ran (if any).
No app state other than what tick itself mutates is touched.
Note
Not thread-safe.
Since
0.1.0

Definition at line 140 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, k_ra8_app_none, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_app_uninstall()

ra8_err_t ra8_app_uninstall ( ra8_app_registry_t * reg,
uint16_t id )
nodiscard

Uninstall (unmount) a removable, non-focused app from the registry.

The run-time half of #146's "core uninstallable" rule. Resolves id and:

  • refuses a core app (removable == false) with k_ra8_err_not_supported – the framework guarantees a core app can never be torn down at run time;
  • refuses the focused app with k_ra8_err_busy – the chrome must navigate away first, so the active-app and back-stack invariants stay intact;
  • otherwise unmounts it: runs its deinit (if any), then removes it from the registry table by compacting the later slots down one place and decrementing count. If the focused app sat after the removed slot, its active index is adjusted so it keeps pointing at the same app.

After a successful uninstall the app is absent (ra8_app_find / ra8_app_count no longer see it) and ra8_app_state reports k_ra8_app_state_unmounted for its id. The app instance itself is caller-owned static storage and is left intact apart from initialized being cleared, so it may be re-registered later.

Warning
If the uninstalled app's id still sits on an ra8_app_nav_t back-stack, a later ra8_app_nav_back to it forwards k_ra8_err_not_found (the id no longer resolves); the chrome should not uninstall an app it can still navigate back to.
Parameters
[in,out]regRegistry.
[in]idApp id to uninstall.
Returns
ra8_err_t
Return values
k_ra8_okUnmounted; the app left the registry.
k_ra8_err_null_ptrreg (or the resolved registry slot) is NULL.
k_ra8_err_not_foundNo app has id.
k_ra8_err_not_supportedid is a core app (removable == false).
k_ra8_err_busyid is the focused app (navigate away first).
Precondition
reg non-NULL.
Postcondition
On k_ra8_ok reg->count shrank by one and id is no longer registered.
On any failure the registry is unchanged.
Note
Not thread-safe.
See also
ra8_app_register
ra8_app_state
Since
0.1.0

Definition at line 329 of file ra8_app.c.

References ra8_app_registry_t::active, ra8_app_registry_t::apps, internal_app_remove_at(), k_ra8_app_none, k_ra8_err_busy, k_ra8_err_not_found, k_ra8_err_not_supported, k_ra8_ok, ra8_app_find(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by app_shell_uninstall_demo().