summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-13 08:01:10 +0300
committerPaul Buetow <paul@buetow.org>2026-04-13 08:01:10 +0300
commit2a5855992e96940fdcba90e66132fdf0db1b41a2 (patch)
tree95fcf1d74939d62b79618d8011f19c521c8944aa /src
parent63c33d373eedd6a6974438250f183a0828aa6794 (diff)
n2: extract Pebble-free fasting logic module
Diffstat (limited to 'src')
-rw-r--r--src/c/fastforge.c2
-rw-r--r--src/c/fastforge_core.c78
-rw-r--r--src/c/fastforge_internal.h8
-rw-r--r--src/c/fastforge_logic.c88
-rw-r--r--src/c/fastforge_logic.h18
5 files changed, 111 insertions, 83 deletions
diff --git a/src/c/fastforge.c b/src/c/fastforge.c
index 9554971..cf2c588 100644
--- a/src/c/fastforge.c
+++ b/src/c/fastforge.c
@@ -968,7 +968,7 @@ static void running_fast_edit_apply_delta_minutes(int delta_minutes) {
current_fast.max_stage_reached = stage_level_for_elapsed(elapsed);
save_all_data();
schedule_alarm_if_needed();
- if (!running_fast_is_at_target(now) && window_stack_contains_window(s_goal_window)) {
+ if (!running_current_fast_is_at_target(now) && window_stack_contains_window(s_goal_window)) {
window_stack_remove(s_goal_window, false);
}
refresh_all_ui_state();
diff --git a/src/c/fastforge_core.c b/src/c/fastforge_core.c
index 3d9eeb8..39d9ea8 100644
--- a/src/c/fastforge_core.c
+++ b/src/c/fastforge_core.c
@@ -49,25 +49,6 @@ static void normalize_loaded_data(void) {
}
}
-time_t local_day_start(time_t timestamp) {
- if (timestamp <= 0) {
- return 0;
- }
-
- struct tm tm_copy;
- struct tm *tm_info = localtime(&timestamp);
- if (!tm_info) {
- return 0;
- }
-
- tm_copy = *tm_info;
- tm_copy.tm_hour = 0;
- tm_copy.tm_min = 0;
- tm_copy.tm_sec = 0;
- tm_copy.tm_isdst = -1;
- return mktime(&tm_copy);
-}
-
static int compare_time_t_ascending(const void *a, const void *b) {
const time_t time_a = *(const time_t *)a;
const time_t time_b = *(const time_t *)b;
@@ -297,32 +278,6 @@ bool fast_is_running(void) {
return current_fast.start_time != 0;
}
-void format_hhmmss(time_t seconds, char *buffer, size_t size) {
- if (seconds < 0) {
- seconds = 0;
- }
- snprintf(buffer, size, "%02d:%02d:%02d",
- (int)(seconds / 3600),
- (int)((seconds % 3600) / 60),
- (int)(seconds % 60));
-}
-
-void format_duration_hours_minutes(time_t seconds, char *buffer, size_t size) {
- if (seconds < 0) {
- seconds = 0;
- }
- int hours = (int)(seconds / 3600);
- int minutes = (int)((seconds % 3600) / 60);
- snprintf(buffer, size, "%dh %02dm", hours, minutes);
-}
-
-time_t entry_duration_seconds(const FastEntry *entry) {
- if (!entry || entry->start_time == 0 || entry->end_time <= entry->start_time) {
- return 0;
- }
- return entry->end_time - entry->start_time;
-}
-
void format_entry_datetime(time_t timestamp, char *buffer, size_t size) {
if (!buffer || size == 0) {
return;
@@ -340,32 +295,6 @@ void format_entry_datetime(time_t timestamp, char *buffer, size_t size) {
strftime(buffer, size, "%b %d %H:%M", tm_info);
}
-uint8_t stage_level_for_elapsed(time_t elapsed_seconds) {
- if (elapsed_seconds >= 24 * 3600) {
- return 3;
- }
- if (elapsed_seconds >= 18 * 3600) {
- return 2;
- }
- if (elapsed_seconds >= 12 * 3600) {
- return 1;
- }
- return 0;
-}
-
-const char *stage_text_for_elapsed(time_t elapsed_seconds) {
- if (elapsed_seconds >= 24 * 3600) {
- return "DEEP KETOSIS";
- }
- if (elapsed_seconds >= 18 * 3600) {
- return "EARLY KETOSIS";
- }
- if (elapsed_seconds >= 12 * 3600) {
- return "FAT BURN";
- }
- return "GLYCOGEN";
-}
-
void update_max_stage_if_needed(time_t elapsed_seconds) {
if (!fast_is_running()) {
return;
@@ -378,11 +307,8 @@ void update_max_stage_if_needed(time_t elapsed_seconds) {
}
}
-bool running_fast_is_at_target(time_t now) {
- if (!fast_is_running() || current_fast.target_minutes == 0) {
- return false;
- }
- return now >= current_fast.start_time + (time_t)current_fast.target_minutes * 60;
+bool running_current_fast_is_at_target(time_t now) {
+ return running_fast_is_at_target(&current_fast, now);
}
static void append_history_entry(const FastEntry *entry) {
diff --git a/src/c/fastforge_internal.h b/src/c/fastforge_internal.h
index c0a2463..980c00d 100644
--- a/src/c/fastforge_internal.h
+++ b/src/c/fastforge_internal.h
@@ -2,6 +2,7 @@
#define FASTFORGE_INTERNAL_H
#include "fastforge.h"
+#include "fastforge_logic.h"
extern bool s_fake_time_enabled;
extern int32_t s_fake_time_offset_seconds;
@@ -14,13 +15,8 @@ void recompute_streak_data_for_today(void);
bool refresh_streak_if_day_changed(void);
void update_max_stage_if_needed(time_t elapsed_seconds);
void schedule_alarm_if_needed(void);
-time_t entry_duration_seconds(const FastEntry *entry);
-void format_hhmmss(time_t seconds, char *buffer, size_t size);
-void format_duration_hours_minutes(time_t seconds, char *buffer, size_t size);
+bool running_current_fast_is_at_target(time_t now);
void format_entry_datetime(time_t timestamp, char *buffer, size_t size);
-uint8_t stage_level_for_elapsed(time_t elapsed_seconds);
-const char *stage_text_for_elapsed(time_t elapsed_seconds);
-bool running_fast_is_at_target(time_t now);
void sort_history_by_end_time(void);
int history_index_for_row(int row);
const char *milestone_badge_label_for_level(uint8_t stage_level);
diff --git a/src/c/fastforge_logic.c b/src/c/fastforge_logic.c
new file mode 100644
index 0000000..64fe776
--- /dev/null
+++ b/src/c/fastforge_logic.c
@@ -0,0 +1,88 @@
+#include "fastforge_logic.h"
+
+#if defined(__has_include)
+#if __has_include(<pebble.h>)
+#include <pebble.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+time_t entry_duration_seconds(const FastEntry *entry) {
+ if (!entry || entry->start_time == 0 || entry->end_time <= entry->start_time) {
+ return 0;
+ }
+ return entry->end_time - entry->start_time;
+}
+
+uint8_t stage_level_for_elapsed(time_t elapsed_seconds) {
+ if (elapsed_seconds >= 24 * 3600) {
+ return 3;
+ }
+ if (elapsed_seconds >= 18 * 3600) {
+ return 2;
+ }
+ if (elapsed_seconds >= 12 * 3600) {
+ return 1;
+ }
+ return 0;
+}
+
+const char *stage_text_for_elapsed(time_t elapsed_seconds) {
+ if (elapsed_seconds >= 24 * 3600) {
+ return "DEEP KETOSIS";
+ }
+ if (elapsed_seconds >= 18 * 3600) {
+ return "EARLY KETOSIS";
+ }
+ if (elapsed_seconds >= 12 * 3600) {
+ return "FAT BURN";
+ }
+ return "GLYCOGEN";
+}
+
+void format_hhmmss(time_t seconds, char *buffer, size_t size) {
+ if (seconds < 0) {
+ seconds = 0;
+ }
+ snprintf(buffer, size, "%02d:%02d:%02d",
+ (int)(seconds / 3600),
+ (int)((seconds % 3600) / 60),
+ (int)(seconds % 60));
+}
+
+void format_duration_hours_minutes(time_t seconds, char *buffer, size_t size) {
+ if (seconds < 0) {
+ seconds = 0;
+ }
+ int hours = (int)(seconds / 3600);
+ int minutes = (int)((seconds % 3600) / 60);
+ snprintf(buffer, size, "%dh %02dm", hours, minutes);
+}
+
+time_t local_day_start(time_t timestamp) {
+ if (timestamp <= 0) {
+ return 0;
+ }
+
+ struct tm tm_copy;
+ struct tm *tm_info = localtime(&timestamp);
+ if (!tm_info) {
+ return 0;
+ }
+
+ tm_copy = *tm_info;
+ tm_copy.tm_hour = 0;
+ tm_copy.tm_min = 0;
+ tm_copy.tm_sec = 0;
+ tm_copy.tm_isdst = -1;
+ return mktime(&tm_copy);
+}
+
+bool running_fast_is_at_target(const FastEntry *entry, time_t now) {
+ if (!entry || entry->start_time == 0 || entry->end_time != 0 || entry->target_minutes == 0) {
+ return false;
+ }
+ return now >= entry->start_time + (time_t)entry->target_minutes * 60;
+}
diff --git a/src/c/fastforge_logic.h b/src/c/fastforge_logic.h
new file mode 100644
index 0000000..4ccaba7
--- /dev/null
+++ b/src/c/fastforge_logic.h
@@ -0,0 +1,18 @@
+#ifndef FASTFORGE_LOGIC_H
+#define FASTFORGE_LOGIC_H
+
+#include "fastforge_types.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <time.h>
+
+time_t entry_duration_seconds(const FastEntry *entry);
+uint8_t stage_level_for_elapsed(time_t elapsed_seconds);
+const char *stage_text_for_elapsed(time_t elapsed_seconds);
+void format_hhmmss(time_t seconds, char *buffer, size_t size);
+void format_duration_hours_minutes(time_t seconds, char *buffer, size_t size);
+time_t local_day_start(time_t timestamp);
+bool running_fast_is_at_target(const FastEntry *entry, time_t now);
+
+#endif