diff options
| author | Jan Hustak <coding@journey.sk> | 2024-10-20 12:01:36 +0200 |
|---|---|---|
| committer | JF <JF002@users.noreply.github.com> | 2025-11-04 21:25:31 +0100 |
| commit | db5d4704cc4a7361c80d1eab199af268364545c7 (patch) | |
| tree | 060efe2965b0984637fc8054353c1dcea5ffb622 /src/components | |
| parent | 74cf69bb6716657575f52e0e207ff123c6e01575 (diff) | |
StopWatch: add persistence
# Conflicts:
# src/displayapp/screens/StopWatch.h
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/stopwatch/StopWatchController.cpp | 101 | ||||
| -rw-r--r-- | src/components/stopwatch/StopWatchController.h | 66 |
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; + }; + } +} |
