diff options
Diffstat (limited to 'src/utility')
| -rw-r--r-- | src/utility/CircularBuffer.h | 51 | ||||
| -rw-r--r-- | src/utility/DirtyValue.h | 39 | ||||
| -rw-r--r-- | src/utility/LinearApproximation.h | 41 | ||||
| -rw-r--r-- | src/utility/Math.cpp | 49 | ||||
| -rw-r--r-- | src/utility/Math.h | 10 | ||||
| -rw-r--r-- | src/utility/StaticStack.h | 47 |
6 files changed, 237 insertions, 0 deletions
diff --git a/src/utility/CircularBuffer.h b/src/utility/CircularBuffer.h new file mode 100644 index 00000000..c8abe92e --- /dev/null +++ b/src/utility/CircularBuffer.h @@ -0,0 +1,51 @@ +#pragma once + +#include <array> +#include <cstddef> + +namespace Pinetime { + namespace Utility { + template <class T, size_t S> + struct CircularBuffer { + constexpr size_t Size() const { + return S; + } + + size_t Idx() const { + return idx; + } + + T& operator[](size_t n) { + return data[(idx + n) % S]; + } + + const T& operator[](size_t n) const { + return data[(idx + n) % S]; + } + + void operator++() { + idx++; + idx %= S; + } + + void operator++(int) { + operator++(); + } + + void operator--() { + if (idx > 0) { + idx--; + } else { + idx = S - 1; + } + } + + void operator--(int) { + operator--(); + } + + std::array<T, S> data; + size_t idx = 0; + }; + } +} diff --git a/src/utility/DirtyValue.h b/src/utility/DirtyValue.h new file mode 100644 index 00000000..8d5147aa --- /dev/null +++ b/src/utility/DirtyValue.h @@ -0,0 +1,39 @@ +#pragma once + +namespace Pinetime { + namespace Utility { + template <class T> + class DirtyValue { + public: + DirtyValue() = default; // Use NSDMI + + explicit DirtyValue(T const& v) : value {v} { + } // Use MIL and const-lvalue-ref + + bool IsUpdated() { + if (this->isUpdated) { + this->isUpdated = false; + return true; + } + return false; + } + + T const& Get() { + this->isUpdated = false; + return value; + } // never expose a non-const lvalue-ref + + DirtyValue& operator=(const T& other) { + if (this->value != other) { + this->value = other; + this->isUpdated = true; + } + return *this; + } + + private: + T value {}; // NSDMI - default initialise type + bool isUpdated {true}; // NSDMI - use brace initialisation + }; + } +} diff --git a/src/utility/LinearApproximation.h b/src/utility/LinearApproximation.h new file mode 100644 index 00000000..34ceb7f2 --- /dev/null +++ b/src/utility/LinearApproximation.h @@ -0,0 +1,41 @@ +#pragma once + +#include <cstddef> +#include <array> + +namespace Pinetime { + namespace Utility { + // based on: https://github.com/SHristov92/LinearApproximation/blob/main/Linear.h + template <typename Key, typename Value, std::size_t Size> + class LinearApproximation { + using Point = struct { + Key key; + Value value; + }; + + public: + LinearApproximation(const std::array<Point, Size>&& sorted_points) : points {sorted_points} { + } + + Value GetValue(Key key) const { + if (key <= points[0].key) { + return points[0].value; + } + + for (std::size_t i = 1; i < Size; i++) { + const auto& p = points[i]; + const auto& p_prev = points[i - 1]; + + if (key < p.key) { + return p_prev.value + (key - p_prev.key) * (p.value - p_prev.value) / (p.key - p_prev.key); + } + } + + return points[Size - 1].value; + } + + private: + std::array<Point, Size> points; + }; + } +} diff --git a/src/utility/Math.cpp b/src/utility/Math.cpp new file mode 100644 index 00000000..fee4f64a --- /dev/null +++ b/src/utility/Math.cpp @@ -0,0 +1,49 @@ +#include "utility/Math.h" + +#include <lvgl/src/lv_misc/lv_math.h> + +using namespace Pinetime::Utility; + +#ifndef PINETIME_IS_RECOVERY + +int16_t Pinetime::Utility::Asin(int16_t arg) { + int16_t a = arg < 0 ? -arg : arg; + + int16_t angle = 45; + int16_t low = 0; + int16_t high = 90; + while (low <= high) { + int16_t sinAngle = _lv_trigo_sin(angle); + int16_t sinAngleSub = _lv_trigo_sin(angle - 1); + int16_t sinAngleAdd = _lv_trigo_sin(angle + 1); + + if (a >= sinAngleSub && a <= sinAngleAdd) { + if (a <= (sinAngleSub + sinAngle) / 2) { + angle--; + } else if (a > (sinAngle + sinAngleAdd) / 2) { + angle++; + } + break; + } + + if (a < sinAngle) { + high = angle - 1; + } + + else { + low = angle + 1; + } + + angle = (low + high) / 2; + } + + return arg < 0 ? -angle : angle; +} + +#else + +int16_t Pinetime::Utility::Asin(int16_t /*arg*/) { + return 0; +} + +#endif diff --git a/src/utility/Math.h b/src/utility/Math.h new file mode 100644 index 00000000..e8d190c7 --- /dev/null +++ b/src/utility/Math.h @@ -0,0 +1,10 @@ +#pragma once + +#include <cstdint> + +namespace Pinetime { + namespace Utility { + // returns the arcsin of `arg`. asin(-32767) = -90, asin(32767) = 90 + int16_t Asin(int16_t arg); + } +} diff --git a/src/utility/StaticStack.h b/src/utility/StaticStack.h new file mode 100644 index 00000000..40df9354 --- /dev/null +++ b/src/utility/StaticStack.h @@ -0,0 +1,47 @@ +#include <array> +#include <cstddef> + +namespace Pinetime { + namespace Utility { + template <typename T, size_t N> + class StaticStack { + public: + T Pop(); + void Push(T element); + void Reset(); + T Top(); + + private: + std::array<T, N> elementArray; + // Number of elements in stack, points to the next empty slot + size_t stackPointer = 0; + }; + + // Returns random data when popping from empty array. + template <typename T, size_t N> + T StaticStack<T, N>::Pop() { + if (stackPointer > 0) { + stackPointer--; + } + return elementArray[stackPointer]; + } + + template <typename T, size_t N> + void StaticStack<T, N>::Push(T element) { + if (stackPointer < elementArray.size()) { + elementArray[stackPointer] = element; + stackPointer++; + } + } + + template <typename T, size_t N> + void StaticStack<T, N>::Reset() { + stackPointer = 0; + } + + template <typename T, size_t N> + T StaticStack<T, N>::Top() { + return elementArray[stackPointer - 1]; + } + } +} |
