Stuck in boilerplate hell

This commit is contained in:
Stepland 2022-04-14 01:26:31 +02:00
parent d19eaae95e
commit 5a6855564f
9 changed files with 151 additions and 12 deletions

View File

@ -3,7 +3,6 @@
#include <cstdint> #include <cstdint>
#include <json.hpp> #include <json.hpp>
#include <optional> #include <optional>
#include "src/better_hakus.hpp"
namespace better { namespace better {
nlohmann::ordered_json Chart::dump_to_memon_1_0_0( nlohmann::ordered_json Chart::dump_to_memon_1_0_0(
@ -69,6 +68,11 @@ namespace better {
}; };
} }
std::ostream& operator<<(std::ostream& out, const better::Chart& c) {
out << fmt::format("{}", c);
return out;
};
nlohmann::ordered_json remove_keys_already_in_fallback( nlohmann::ordered_json remove_keys_already_in_fallback(
const nlohmann::ordered_json& object, const nlohmann::ordered_json& object,
const nlohmann::ordered_json& fallback const nlohmann::ordered_json& fallback

View File

@ -4,6 +4,7 @@
#include <optional> #include <optional>
#include <set> #include <set>
#include <fmt/core.h>
#include <json.hpp> #include <json.hpp>
#include "better_hakus.hpp" #include "better_hakus.hpp"
@ -26,6 +27,8 @@ namespace better {
static Chart load_from_memon_1_0_0(const nlohmann::json& json, const nlohmann::json& fallback_timing); static Chart load_from_memon_1_0_0(const nlohmann::json& json, const nlohmann::json& fallback_timing);
static Chart load_from_memon_legacy(const nlohmann::json& json); static Chart load_from_memon_legacy(const nlohmann::json& json);
friend std::ostream& operator<<(std::ostream& out, const Chart& n);
}; };
/* /*
@ -42,4 +45,33 @@ namespace better {
const std::optional<Hakus>& hakus, const std::optional<Hakus>& hakus,
const nlohmann::ordered_json& fallback_timing_object const nlohmann::ordered_json& fallback_timing_object
); );
} }
template <class T>
struct fmt::formatter<std::optional<T>>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const std::optional<T>& opt, FormatContext& ctx) {
if (opt) {
return format_to(ctx.out(), "{}", *opt);
} else {
return format_to(ctx.out(), "");
}
}
};
template <>
struct fmt::formatter<better::Chart>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const better::Chart& c, FormatContext& ctx) {
return format_to(
ctx.out(),
"LongNote(level: {}, timing: {}, hakus: {}, notes: {})",
c.level,
c.timing,
c.hakus,
c.notes
);
}
};

View File

@ -4,6 +4,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <iostream> #include <iostream>
#include "fmt/core.h"
#include "json.hpp" #include "json.hpp"
namespace better { namespace better {
@ -153,4 +154,9 @@ namespace better {
} }
return notes; return notes;
}; };
std::ostream& operator<<(std::ostream& out, const Notes& n) {
out << fmt::format("{}", n);
return out;
};
} }

View File

@ -3,11 +3,14 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cstddef> #include <cstddef>
#include <interval_tree.hpp>
#include <json.hpp>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <interval_tree.hpp>
#include <json.hpp>
#include "better_note.hpp" #include "better_note.hpp"
#include "better_timing.hpp" #include "better_timing.hpp"
#include "generic_interval.hpp" #include "generic_interval.hpp"
@ -40,5 +43,25 @@ namespace better {
static Notes load_from_memon_1_0_0(const nlohmann::json& json, std::uint64_t resolution = 240); static Notes load_from_memon_1_0_0(const nlohmann::json& json, std::uint64_t resolution = 240);
static Notes load_from_memon_legacy(const nlohmann::json& json, std::uint64_t resolution); static Notes load_from_memon_legacy(const nlohmann::json& json, std::uint64_t resolution);
friend std::ostream& operator<<(std::ostream& out, const Notes& n);
}; };
} }
template <>
struct fmt::formatter<better::Notes>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const better::Notes& n, FormatContext& ctx) {
std::vector<better::Note> notes;
std::transform(n.begin(), n.end(), notes.begin(), [](const auto& p){return p.second;});
return format_to(
ctx.out(),
"[{}]",
fmt::join(
notes,
", "
)
);
}
};

View File

@ -8,9 +8,9 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <json.hpp>
#include <SFML/System/Time.hpp> #include <SFML/System/Time.hpp>
#include "json.hpp"
#include "special_numeric_types.hpp" #include "special_numeric_types.hpp"
namespace better { namespace better {
@ -87,4 +87,20 @@ namespace better {
std::set<BPMEvent, OrderByBeats> events_by_beats; std::set<BPMEvent, OrderByBeats> events_by_beats;
std::set<BPMEvent, OrderBySeconds> events_by_seconds; std::set<BPMEvent, OrderBySeconds> events_by_seconds;
}; };
} }
template <>
struct fmt::formatter<better::Chart>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
template <typename FormatContext>
auto format(const better::Chart& c, FormatContext& ctx) {
return format_to(
ctx.out(),
"LongNote(level: {}, timing: {}, hakus: {}, notes: {})",
c.level,
c.timing,
c.hakus,
c.notes
);
}
};

View File

@ -1,3 +1,4 @@
#include <string>
#define IMGUI_USER_CONFIG "imconfig-SFML.h" #define IMGUI_USER_CONFIG "imconfig-SFML.h"
#include <filesystem> #include <filesystem>
@ -26,7 +27,7 @@ int main() {
// TODO : Make the linear preview display the end of the chart // TODO : Make the linear preview display the end of the chart
// TODO : Make the linear preview timebar height movable // TODO : Make the linear preview timebar height movable
auto executable_folder = std::filesystem::path{whereami::executable_dir()}; auto executable_folder = std::filesystem::u8path(whereami::executable_dir());
auto assets_folder = executable_folder / "assets"; auto assets_folder = executable_folder / "assets";
auto settings_folder = executable_folder / "settings"; auto settings_folder = executable_folder / "settings";
@ -98,6 +99,8 @@ int main() {
if (editor_state->save_if_needed_and_user_wants_to() != EditorState::SaveOutcome::UserCanceled) { if (editor_state->save_if_needed_and_user_wants_to() != EditorState::SaveOutcome::UserCanceled) {
window.close(); window.close();
} }
} else {
window.close();
} }
break; break;
case sf::Event::Resized: case sf::Event::Resized:

View File

@ -1,18 +1,24 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <optional>
#include <rapidcheck.h> #include <rapidcheck.h>
#include <rapidcheck/gen/Arbitrary.h> #include <rapidcheck/gen/Arbitrary.h>
#include <rapidcheck/gen/Build.h>
#include <rapidcheck/gen/Container.h>
#include <rapidcheck/gen/Exec.h>
#include <rapidcheck/gen/Numeric.h> #include <rapidcheck/gen/Numeric.h>
#include <rapidcheck/gen/Predicate.h>
#include <rapidcheck/gen/Transform.h>
#include "../../better_chart.hpp"
#include "../../better_hakus.hpp"
#include "../../better_note.hpp" #include "../../better_note.hpp"
#include "../../better_notes.hpp" #include "../../better_notes.hpp"
#include "../../better_timing.hpp" #include "../../better_timing.hpp"
#include "../../variant_visitor.hpp" #include "../../variant_visitor.hpp"
#include "rapidcheck/gen/Build.h"
#include "rapidcheck/gen/Container.h"
#include "rapidcheck/gen/Exec.h"
#include "rapidcheck/gen/Predicate.h"
namespace rc { namespace rc {
template<> template<>
@ -160,4 +166,39 @@ namespace rc {
); );
} }
}; };
template<>
struct Arbitrary<Hakus> {
static Gen<Hakus> arbitrary() {
return gen::container<std::set<Fraction>>(gen::positive<Fraction>());
}
};
template<class T>
struct Arbitrary<std::optional<T>> {
static Gen<std::optional<T>> arbitrary() {
return gen::mapcat(
gen::arbitrary<bool>(),
[](bool engaged) {
if (not engaged) {
return gen::construct<std::optional<T>>();
} else {
return gen::construct<std::optional<T>>(gen::arbitrary<T>());
}
}
);
}
};
template<>
struct Arbitrary<better::Chart> {
static Gen<better::Chart> arbitrary() {
return gen::construct<better::Chart>(
gen::arbitrary<std::optional<Decimal>>(),
gen::arbitrary<std::optional<better::Timing>>(),
gen::arbitrary<std::optional<Hakus>>(),
gen::arbitrary<better::Notes>()
);
}
};
} }

View File

@ -8,6 +8,7 @@
#include "../../better_note.hpp" #include "../../better_note.hpp"
#include "../../better_notes.hpp" #include "../../better_notes.hpp"
#include "../../better_timing.hpp" #include "../../better_timing.hpp"
#include "json.hpp"
int main() { int main() {
@ -41,5 +42,16 @@ int main() {
RC_ASSERT(original == recovered); RC_ASSERT(original == recovered);
} }
); );
rc::check(
"A Chart object survives being converted to json and back",
[](const better::Chart& original) {
const auto fallback_timing = nlohmann::ordered_json::object();
const auto j = original.dump_to_memon_1_0_0(fallback_timing);
RC_LOG("json dump : "+j.dump());
const auto recovered = better::Chart::load_from_memon_1_0_0(j, fallback_timing);
RC_ASSERT(original == recovered);
}
);
return 0; return 0;
} }

View File

@ -3,6 +3,8 @@ rapidcheck_tests = executable(
'generators.cpp', 'generators.cpp',
'main.cpp', 'main.cpp',
'../../better_beats.cpp', '../../better_beats.cpp',
'../../better_chart.cpp',
'../../better_hakus.cpp',
'../../better_note.cpp', '../../better_note.cpp',
'../../better_notes.cpp', '../../better_notes.cpp',
'../../better_timing.cpp', '../../better_timing.cpp',