Program Listing for File PDJE_Note_OBJ.hpp
↰ Return to documentation for file (include/judge/NoteOBJ/PDJE_Note_OBJ.hpp)
#pragma once
#include "Input_State.hpp"
#include "PDJE_EXPORT_SETTER.hpp"
#include "PDJE_Input_Device_Data.hpp"
#include <cstdint>
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace PDJE_JUDGE {
constexpr int BUFFER_MAIN = 0;
constexpr int BUFFER_SUB = 1;
using GLOBAL_TIME = uint64_t;
using LOCAL_TIME = uint64_t;
struct PDJE_API NOTE {
std::string type;
uint16_t detail;
std::string first;
std::string second;
std::string third;
LOCAL_TIME microsecond = 0;
bool used = false;
bool isDown = true;
};
using NOTE_VEC = std::vector<NOTE>;
using P_NOTE_VEC = std::vector<NOTE *>;
struct PDJE_API NOTE_ITR {
NOTE_VEC vec;
NOTE_VEC::iterator itr;
};
using DEVID_TO_NOTE = std::unordered_map<uint64_t, NOTE_ITR>;
class PDJE_API OBJ {
private:
DEVID_TO_NOTE Buffer_Main;
DEVID_TO_NOTE Buffer_Sub;
template <int I>
DEVID_TO_NOTE *
pick_dan()
{
if constexpr (I == BUFFER_MAIN) {
return &Buffer_Main;
} else {
return &Buffer_Sub;
}
}
public:
void
Sort(); // use only for init
template <int I>
void
Fill(const NOTE &data, uint64_t rail_id)
{
static_assert(I == BUFFER_MAIN || I == BUFFER_SUB,
"invalid use of fill.");
DEVID_TO_NOTE *dan = pick_dan<I>();
(*dan)[rail_id].vec.push_back(data);
}
template <int I>
void
Get(const LOCAL_TIME limit, uint64_t railID, P_NOTE_VEC &found)
{
static_assert(I == BUFFER_MAIN || I == BUFFER_SUB,
"invalid use of get.");
DEVID_TO_NOTE *dan = pick_dan<I>();
found.clear();
auto ¬e = (*dan)[railID];
if (note.vec.empty()) {
return;
}
while (true) { // pull iterator
if (note.itr != note.vec.end() && note.itr->used) {
++note.itr;
} else {
break;
}
}
auto titr = note.itr;
while (true) {
if ((titr != note.vec.end()) && titr->microsecond <= limit &&
!titr->used) {
found.push_back(std::addressof(*titr));
++titr;
} else {
break;
}
}
}
template <int I>
void
Cut(const LOCAL_TIME limit, std::unordered_map<uint64_t, NOTE_VEC> &cuts)
{
static_assert(I == BUFFER_MAIN || I == BUFFER_SUB,
"invalid use of cut.");
DEVID_TO_NOTE *dan = pick_dan<I>();
for (auto &rail : *dan) {
if (rail.second.vec.empty()) {
continue;
}
auto titr = rail.second.itr;
while (titr != rail.second.vec.end() &&
titr->microsecond <= limit) {
if (!titr->used) {
cuts[rail.first].push_back(*titr);
titr->used = true;
}
++titr;
}
}
}
OBJ() = default;
~OBJ() = default;
};
}; // namespace PDJE_JUDGE