project-kyoku/include/core/precisionevaluator.h

70 lines
1.8 KiB
C
Raw Normal View History

2021-12-29 09:59:18 -05:00
#pragma once
#include <numeric>
#include <type_traits>
#include <vector>
#include <cmath>
#include <iostream>
2021-12-29 09:59:18 -05:00
#include "core/time.h"
namespace kku
{
2021-06-11 12:58:44 -04:00
template<typename Grade, typename = std::enable_if_t<std::is_enum<Grade>::value>>
class PrecisionEvaluator
{
public:
2021-06-07 14:19:58 -04:00
PrecisionEvaluator(const std::vector<microsec>& intervals, microsec offset) :
_offset(offset),
2021-06-07 14:19:58 -04:00
_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;
}
2021-12-29 09:59:18 -05:00
Grade calculatePrecision(microsec odds) const
{
microsec shift_from_perfect = std::abs(odds - offset());
2021-12-29 09:59:18 -05:00
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)
{
2021-06-07 14:19:58 -04:00
if (shift_from_perfect <= _intervals.at(raw_grade))
break;
}
2021-06-11 12:58:44 -04:00
return static_cast<Grade>(raw_grade);
}
private:
microsec _offset;
microsec _start_handling_offset;
microsec _end_handling_offset;
2021-06-11 12:58:44 -04:00
/* Amount of values in enum instanced as GradeS
* represents capacity of _intervals.
2021-06-11 12:58:44 -04:00
* 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<microsec> _intervals;
};
2021-12-29 09:59:18 -05:00
}