aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorJan Hustak <coding@journey.sk>2024-10-20 12:01:36 +0200
committerJF <JF002@users.noreply.github.com>2025-11-04 21:25:31 +0100
commitdb5d4704cc4a7361c80d1eab199af268364545c7 (patch)
tree060efe2965b0984637fc8054353c1dcea5ffb622 /src/components
parent74cf69bb6716657575f52e0e207ff123c6e01575 (diff)
StopWatch: add persistence
# Conflicts: # src/displayapp/screens/StopWatch.h
Diffstat (limited to 'src/components')
-rw-r--r--src/components/stopwatch/StopWatchController.cpp101
-rw-r--r--src/components/stopwatch/StopWatchController.h66
2 files changed, 167 insertions, 0 deletions
diff --git a/src/components/stopwatch/StopWatchController.cpp b/src/components/stopwatch/StopWatchController.cpp
new file mode 100644
index 00000000..200919f4
--- /dev/null
+++ b/src/components/stopwatch/StopWatchController.cpp
@@ -0,0 +1,101 @@
+#include "components/stopwatch/StopWatchController.h"
+
+using namespace Pinetime::Controllers;
+
+namespace {
+ TickType_t CalculateDelta(const TickType_t startTime, const TickType_t currentTime) {
+ TickType_t delta = 0;
+ // Take care of overflow
+ if (startTime > currentTime) {
+ delta = 0xffffffff - startTime;
+ delta += (currentTime + 1);
+ } else {
+ delta = currentTime - startTime;
+ }
+ return delta;
+ }
+}
+
+StopWatchController::StopWatchController() {
+ Clear();
+}
+
+// State Change
+
+void StopWatchController::Start() {
+ currentState = StopWatchStates::Running;
+ startTime = xTaskGetTickCount();
+}
+
+void StopWatchController::Pause() {
+ currentState = StopWatchStates::Paused;
+ timeElapsedPreviously += CalculateDelta(startTime, xTaskGetTickCount());
+}
+
+void StopWatchController::Clear() {
+ currentState = StopWatchStates::Cleared;
+ timeElapsedPreviously = 0;
+
+ for (int i = 0; i < LAP_CAPACITY; i++) {
+ laps[i].count = 0;
+ laps[i].time = 0;
+ }
+ lapCount = 0;
+ lapHead = 0;
+}
+
+// Lap
+
+void StopWatchController::PushLap() {
+ TickType_t lapEnd = GetElapsedTime();
+ laps[lapHead].time = lapEnd;
+ laps[lapHead].count = lapCount + 1;
+ lapCount += 1;
+ lapHead = lapCount % LAP_CAPACITY;
+}
+
+int StopWatchController::GetLapNum() {
+ if (lapCount < LAP_CAPACITY)
+ return lapCount;
+ else
+ return LAP_CAPACITY;
+}
+
+int StopWatchController::GetLapCount() {
+ return lapCount;
+}
+
+int Wrap(int index) {
+ return ((index % LAP_CAPACITY) + LAP_CAPACITY) % LAP_CAPACITY;
+}
+
+LapInfo* StopWatchController::LastLap(int lap) {
+ if (lap >= LAP_CAPACITY || lap > lapCount || lapCount == 0) {
+ // Return "empty" LapInfo_t
+ return &emptyLapInfo;
+ }
+ // Index backwards
+ int index = Wrap(lapHead - lap);
+ return &laps[index];
+}
+
+// Data / State acess
+
+TickType_t StopWatchController::GetElapsedTime() {
+ if (!IsRunning()) {
+ return timeElapsedPreviously;
+ }
+ return timeElapsedPreviously + CalculateDelta(startTime, xTaskGetTickCount());
+}
+
+bool StopWatchController::IsRunning() {
+ return currentState == StopWatchStates::Running;
+}
+
+bool StopWatchController::IsCleared() {
+ return currentState == StopWatchStates::Cleared;
+}
+
+bool StopWatchController::IsPaused() {
+ return currentState == StopWatchStates::Paused;
+}
diff --git a/src/components/stopwatch/StopWatchController.h b/src/components/stopwatch/StopWatchController.h
new file mode 100644
index 00000000..0aaeb5ca
--- /dev/null
+++ b/src/components/stopwatch/StopWatchController.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <FreeRTOS.h>
+#include <timers.h>
+
+#define LAP_CAPACITY 2
+
+namespace Pinetime {
+ namespace System {
+ class SystemTask;
+ }
+ namespace Controllers {
+
+ enum class StopWatchStates { Cleared, Running, Paused };
+
+ struct LapInfo {
+ int count = 0; // Used to label the lap
+ TickType_t time = 0; // Delta time from beginning of stopwatch
+ };
+
+ class StopWatchController {
+ public:
+ StopWatchController();
+
+ // StopWatch functionality and data
+ void Start();
+ void Pause();
+ void Clear();
+
+ TickType_t GetElapsedTime();
+
+ // Lap functionality
+
+ /// Only the latest laps are stored, the lap count is saved until reset
+ void PushLap();
+
+ /// Returns actual count of stored laps
+ int GetLapNum();
+
+ /// Returns lapCount
+ int GetLapCount();
+
+ /// Indexes into lap history, with 0 being the latest lap.
+ /// If the lap is unavailable, count and time will be 0. If there is a
+ /// real value, count should be above 0
+ LapInfo* LastLap(int lap = 0);
+
+ bool IsRunning();
+ bool IsCleared();
+ bool IsPaused();
+
+ private:
+ // Current state of stopwatch
+ StopWatchStates currentState = StopWatchStates::Cleared;
+ // Start time of current duration
+ TickType_t startTime = 0;
+ // How much time was elapsed before current duration
+ TickType_t timeElapsedPreviously = 0;
+ // Stores lap times
+ LapInfo laps[LAP_CAPACITY];
+ LapInfo emptyLapInfo = {.count = 0, .time = 0};
+ int lapCount = 0;
+ int lapHead = 0;
+ };
+ }
+}