F.E.I.S/src/better_chart.cpp

105 lines
3.5 KiB
C++
Raw Normal View History

#include "better_chart.hpp"
2022-04-03 15:59:05 +02:00
#include <cstdint>
#include <json.hpp>
2022-04-03 15:59:05 +02:00
#include <optional>
namespace better {
2022-04-02 04:10:09 +02:00
nlohmann::ordered_json Chart::dump_to_memon_1_0_0(
const nlohmann::ordered_json& fallback_timing_object
) const {
nlohmann::ordered_json json_chart;
if (level) {
json_chart["level"] = level->format("f");
}
2022-04-03 15:59:05 +02:00
if (timing) {
auto chart_timing = dump_memon_1_0_0_timing_object(*timing, hakus, fallback_timing_object);
if (not chart_timing.empty()) {
json_chart["timing"] = chart_timing;
}
}
2022-04-02 04:10:09 +02:00
json_chart["notes"] = notes.dump_to_memon_1_0_0();
2022-04-03 15:59:05 +02:00
return json_chart;
};
2022-04-03 15:59:05 +02:00
Chart Chart::load_from_memon_1_0_0(const nlohmann::json& json, const nlohmann::json& fallback_timing) {
std::optional<Decimal> level;
if (json.contains("level")) {
const auto string_level = json["level"].get<std::string>();
level = Decimal{string_level};
}
std::uint64_t chart_resolution = 240;
if (json.contains("resolution")) {
chart_resolution = json["resolution"].get<std::uint64_t>();
}
std::optional<Timing> timing;
std::optional<Hakus> hakus;
if (json.contains("timing")) {
auto chart_timing = fallback_timing;
chart_timing.update(json["timing"]);
timing = Timing::load_from_memon_1_0_0(chart_timing);
/*
Don't re-use the merged 'chart_timing' here :
'fallback_timing' might contain hakus from the song-wise timing
object and we don't want to take these into account when looking
for chart-specific ones
*/
hakus = load_hakus(json["timing"]);
}
2022-04-11 01:50:25 +02:00
return Chart{
2022-04-03 15:59:05 +02:00
.level = level,
.timing = timing,
.hakus = hakus,
2022-04-11 01:50:25 +02:00
.notes = Notes::load_from_memon_1_0_0(json.at("notes"), chart_resolution)
2022-04-03 15:59:05 +02:00
};
}
Chart Chart::load_from_memon_legacy(const nlohmann::json& json) {
2022-04-11 01:50:25 +02:00
return Chart{
2022-04-02 04:10:09 +02:00
.level = Decimal{json["level"].get<int>()},
2022-04-03 15:59:05 +02:00
.timing = {},
2022-04-02 04:10:09 +02:00
.hakus = {},
2022-04-11 01:50:25 +02:00
.notes = Notes::load_from_memon_legacy(
json.at("notes"),
json.at("resolution").get<std::uint64_t>()
)
2022-04-02 04:10:09 +02:00
};
}
2022-04-14 01:26:31 +02:00
std::ostream& operator<<(std::ostream& out, const better::Chart& c) {
out << fmt::format("{}", c);
return out;
};
2022-04-03 15:59:05 +02:00
nlohmann::ordered_json remove_keys_already_in_fallback(
const nlohmann::ordered_json& object,
const nlohmann::ordered_json& fallback
) {
nlohmann::ordered_json j;
for (const auto& [key, value] : object.items()) {
if (not fallback.contains(key)) {
j[key] = value;
} else {
if (fallback[key] != value) {
j[key] = value;
}
}
}
return j;
};
nlohmann::ordered_json dump_memon_1_0_0_timing_object(
const better::Timing& timing,
const std::optional<Hakus>& hakus,
const nlohmann::ordered_json& fallback_timing_object
) {
auto complete_song_timing = nlohmann::ordered_json::object();
2022-04-02 04:10:09 +02:00
complete_song_timing.update(timing.dump_to_memon_1_0_0());
if (hakus) {
complete_song_timing["hakus"] = dump_hakus(*hakus);
}
2022-04-03 15:59:05 +02:00
return remove_keys_already_in_fallback(complete_song_timing, fallback_timing_object);
};
}