allow watch faces to advise of other things in addition to needing a background task

This commit is contained in:
joeycastillo 2024-09-29 21:43:07 -04:00
parent 40455847a3
commit f843156968
4 changed files with 39 additions and 21 deletions

View File

@ -92,16 +92,24 @@ static inline void _movement_disable_fast_tick_if_possible(void) {
}
}
static void _movement_handle_background_tasks(void) {
static void _movement_handle_advisories(void) {
for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) {
// For each face, if the watch face wants a background task...
if (watch_faces[i].wants_background_task != NULL && watch_faces[i].wants_background_task(watch_face_contexts[i])) {
// ...we give it one. pretty straightforward!
movement_event_t background_event = { EVENT_BACKGROUND_TASK, 0 };
watch_faces[i].loop(background_event, watch_face_contexts[i]);
// For each face that offers an advisory...
if (watch_faces[i].advise != NULL) {
// ...we ask for one.
movement_watch_face_advisory_t advisory = watch_faces[i].advise(watch_face_contexts[i]);
// If it wants a background task...
if (advisory.wants_background_task) {
// we give it one. pretty straightforward!
movement_event_t background_event = { EVENT_BACKGROUND_TASK, 0 };
watch_faces[i].loop(background_event, watch_face_contexts[i]);
}
// TODO: handle other advisory types
}
}
movement_state.needs_background_tasks_handled = false;
movement_state.needs_advisories_handled = false;
}
static void _movement_handle_scheduled_tasks(void) {
@ -539,7 +547,7 @@ static void _sleep_mode_app_loop(void) {
// as long as le_mode_ticks is -1 (i.e. we are in low energy mode), we wake up here, update the screen, and go right back to sleep.
while (movement_state.le_mode_ticks == -1) {
// we also have to handle background tasks here in the mini-runloop
if (movement_state.needs_background_tasks_handled) _movement_handle_background_tasks();
if (movement_state.needs_advisories_handled) _movement_handle_advisories();
event.event_type = EVENT_LOW_ENERGY_UPDATE;
watch_faces[movement_state.current_face_idx].loop(event, watch_face_contexts[movement_state.current_face_idx]);
@ -581,8 +589,8 @@ bool app_loop(void) {
}
}
// handle background tasks, if the alarm handler told us we need to
if (movement_state.needs_background_tasks_handled) _movement_handle_background_tasks();
// handle advisories, if the alarm handler told us we need to
if (movement_state.needs_advisories_handled) _movement_handle_advisories();
// if we have a scheduled background task, handle that here:
if (event.event_type == EVENT_TICK && movement_state.has_scheduled_background_task) _movement_handle_scheduled_tasks();
@ -740,7 +748,7 @@ void cb_alarm_btn_extwake(void) {
}
void cb_alarm_fired(void) {
movement_state.needs_background_tasks_handled = true;
movement_state.needs_advisories_handled = true;
}
void cb_fast_tick(void) {

View File

@ -29,6 +29,13 @@
#include "watch.h"
#include "utz.h"
/// @brief A struct that allows a watch face to report its state back to Movement.
typedef struct {
uint8_t wants_background_task: 1;
uint8_t has_active_alarm: 1;
uint8_t responds_to_dst_change: 1;
} movement_watch_face_advisory_t;
// Movement Preferences
// These four 32-bit structs store information about the wearer and their preferences. Tentatively, the plan is
// for Movement to use four 32-bit registers for these preferences and to store them in the RTC's backup registers
@ -204,7 +211,7 @@ typedef void (*watch_face_activate)(void *context);
**Your watch face MUST NOT wake up peripherals in response to a low power tick.** The purpose of this
mode is to consume as little energy as possible during the (potentially long) intervals when it's
unlikely the user is wearing or looking at the watch.
EVENT_BACKGROUND_TASK is also a special case. @see watch_face_wants_background_task for details.
EVENT_BACKGROUND_TASK is also a special case. @see watch_face_advise for details.
*/
typedef bool (*watch_face_loop)(movement_event_t event, void *context);
@ -237,14 +244,14 @@ typedef void (*watch_face_resign)(void *context);
* @param context A pointer to your application's context. @see watch_face_setup.
* @return true to request a background task; false otherwise.
*/
typedef bool (*watch_face_wants_background_task)(void *context);
typedef movement_watch_face_advisory_t (*watch_face_advise)(void *context);
typedef struct {
watch_face_setup setup;
watch_face_activate activate;
watch_face_loop loop;
watch_face_resign resign;
watch_face_wants_background_task wants_background_task;
watch_face_advise advise;
} watch_face_t;
typedef struct {
@ -272,7 +279,7 @@ typedef struct {
uint16_t alarm_down_timestamp;
// background task handling
bool needs_background_tasks_handled;
bool needs_advisories_handled;
bool has_scheduled_background_task;
bool needs_wake;

View File

@ -277,11 +277,14 @@ void clock_face_resign(void *context) {
(void) context;
}
bool clock_face_wants_background_task(void *context) {
movement_watch_face_advisory_t clock_face_advise(void *context) {
movement_watch_face_advisory_t retval = { 0 };
clock_state_t *state = (clock_state_t *) context;
if (!state->time_signal_enabled) return false;
watch_date_time date_time = watch_rtc_get_date_time();
if (state->time_signal_enabled) {
watch_date_time date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
return date_time.unit.minute == 0;
return retval;
}

View File

@ -47,14 +47,14 @@ void clock_face_setup(uint8_t watch_face_index, void ** context_ptr);
void clock_face_activate(void *context);
bool clock_face_loop(movement_event_t event, void *context);
void clock_face_resign(void *context);
bool clock_face_wants_background_task(void *context);
movement_watch_face_advisory_t clock_face_advise(void *context);
#define clock_face ((const watch_face_t) { \
clock_face_setup, \
clock_face_activate, \
clock_face_loop, \
clock_face_resign, \
clock_face_wants_background_task, \
clock_face_advise, \
})
#endif // CLOCK_FACE_H_