#pragma once #include #include #include #include #include #include "core/time.h" namespace kku { template::value>> class PrecisionEvaluator { public: PrecisionEvaluator(const std::vector& intervals, microsec offset) : _offset(offset), _intervals(intervals) { _start_handling_offset = _offset - intervals.back(); _end_handling_offset = _offset + intervals.back(); } inline microsec offset() const noexcept { return _offset; } inline bool isActive(microsec music_play_offset) const noexcept { return music_play_offset > _start_handling_offset && music_play_offset < _end_handling_offset; } Grade calculatePrecision(microsec odds) const { microsec shift_from_perfect = std::abs(odds - offset()); std::cout << "Shift " << ((odds > _offset) ? "late: " : "early: ") << shift_from_perfect << "\n"; std::size_t raw_grade; for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade) { if (shift_from_perfect <= _intervals.at(raw_grade)) break; } return static_cast(raw_grade); } private: microsec _offset; microsec _start_handling_offset; microsec _end_handling_offset; /* Amount of values in enum instanced as GradeS * represents capacity of _intervals. * So, for each V value in GradeS enum, _intervals[V] * should return time shift from V - 1. * V0 is PERFECT SCORE and the last V represents the worst * grades which is death of note by expiration */ const std::vector _intervals; }; }