diff --git a/src/c/main.c b/src/c/main.c index 593e205..fe759c5 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -74,6 +74,9 @@ static Animation *s_butt_raise_template; static Animation *s_butt_out_template; static Animation *s_butt_in_template; +// guards for the swap scheduling +static struct tm s_last_swap_time; + // declare lookup tables #if PBL_DISPLAY_WIDTH <= 180 static const uint8_t s_ones_offset[] = {0, 3, 6, 9, 12}; @@ -173,6 +176,10 @@ static void update_minute_60_out_handler(Animation *animation, bool finished, vo bitmap_layer_set_bitmap(s_guy_butt_layer, s_butt); } +static bool is_same_minute(const struct tm *a, const struct tm *b) { + return a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && a->tm_min == b->tm_min; +} + static void minute_handler(struct tm *tick_time, TimeUnits units_changed) { // time update static char s_time_buffer[8]; @@ -225,11 +232,17 @@ static void minute_handler(struct tm *tick_time, TimeUnits units_changed) { } // animate swaps on half-hour boundaries (but not on first tick) - if (units_changed) { - if (tick_time->tm_min % 60 == 0) { - schedule_guy_animation(s_head_raise_template, s_head_out_template, s_head_in_template, update_minute_60_out_handler); - } else if (tick_time->tm_min % 30 == 0) { - schedule_guy_animation(s_butt_raise_template, s_butt_out_template, s_butt_in_template, update_minute_30_out_handler); + if (units_changed & MINUTE_UNIT) { + // ignore repeated callbacks for a minute that was already swapped: a duplicate + // tick or a clock correction can move the clock back onto :00/:30 + if (!is_same_minute(tick_time, &s_last_swap_time)) { + if (tick_time->tm_min == 0) { + s_last_swap_time = *tick_time; + schedule_guy_animation(s_head_raise_template, s_head_out_template, s_head_in_template, update_minute_60_out_handler); + } else if (tick_time->tm_min == 30) { + s_last_swap_time = *tick_time; + schedule_guy_animation(s_butt_raise_template, s_butt_out_template, s_butt_in_template, update_minute_30_out_handler); + } } } } @@ -307,8 +320,10 @@ static void main_window_unload(Window *window) { // destroy animation templates animation_destroy(s_butt_raise_template); animation_destroy(s_butt_out_template); + animation_destroy(s_butt_in_template); animation_destroy(s_head_raise_template); animation_destroy(s_head_out_template); + animation_destroy(s_head_in_template); } static void bluetooth_callback(bool connected) {