Go back to using a Notes object to store stuff because now move assignament works for interval trees !

This commit is contained in:
Stepland 2022-04-19 02:07:56 +02:00
parent 44a19ad452
commit 7e93ea6845
7 changed files with 94 additions and 41 deletions

View File

@ -95,11 +95,8 @@ Interval<Fraction> ChartState::visible_beats(const sf::Time& playback_position,
}
void ChartState::update_visible_notes(const sf::Time& playback_position, const better::Timing& timing) {
this->visible_notes.clear();
const auto bounds = visible_beats(playback_position, timing);
chart.notes.in(bounds.start, bounds.end, [this](const better::Notes::const_iterator& it){
this->visible_notes.push_back(it->second);
});
visible_notes = chart.notes.between(bounds);
};
void ChartState::toggle_note(

View File

@ -27,7 +27,7 @@ struct ChartState {
Interval<Fraction> visible_beats(const sf::Time& playback_position, const better::Timing& timing);
void update_visible_notes(const sf::Time& playback_position, const better::Timing& timing);
std::vector<better::Note> visible_notes;
better::Notes visible_notes;
void toggle_note(
const sf::Time& playback_position,

View File

@ -251,7 +251,7 @@ void EditorState::display_playfield(Marker& marker, Judgement markerEndingState)
},
};
for (const auto& note : chart_state->visible_notes) {
for (const auto& [_, note] : chart_state->visible_notes) {
note.visit(display);
}
@ -302,7 +302,7 @@ void EditorState::display_playfield(Marker& marker, Judgement markerEndingState)
if (chart_state) {
// Check for collisions then display them
std::array<bool, 16> collisions = {};
for (const auto& note : chart_state->visible_notes) {
for (const auto& [_, note] : chart_state->visible_notes) {
if (chart_state->chart.notes.is_colliding(note, applicable_timing)) {
collisions[note.get_position().index()] = true;
}
@ -320,7 +320,7 @@ void EditorState::display_playfield(Marker& marker, Judgement markerEndingState)
}
// Display selected notes
for (const auto& note : chart_state->visible_notes) {
for (const auto& [_, note] : chart_state->visible_notes) {
if (chart_state->selected_notes.contains(note)) {
ImGui::SetCursorPos({
note.get_position().get_x() * squareSize,
@ -768,29 +768,33 @@ void EditorState::update_visible_notes() {
void EditorState::reload_editable_range() {
auto old_range = this->editable_range;
Interval<sf::Time> new_range;
if (music) {
new_range += music->getDuration();
}
if (chart_state and not chart_state->chart.notes.empty()) {
const auto beat_of_last_event = chart_state->chart.notes.crbegin()->second.get_end();
new_range += applicable_timing.time_at(beat_of_last_event);
}
new_range.end += sf::seconds(10);
// If there is no music, make sure we can edit at least the first whole minute
if (not music) {
new_range += sf::seconds(60);
}
this->editable_range = new_range;
if (old_range != new_range and this->chart_state.has_value()) {
const auto old_range = this->editable_range;
this->editable_range = choose_editable_range();
if (old_range != this->editable_range and this->chart_state.has_value()) {
chart_state->density_graph.should_recompute = true;
}
};
Interval<sf::Time> EditorState::choose_editable_range() {
Interval<sf::Time> new_range{sf::Time::Zero, sf::Time::Zero};
if (music) {
// If there is music, allow editing up to the end, but no further
// You've put notes *after* the end of the music ? fuck 'em.
new_range += music->getDuration();
return new_range;
} else {
// If there is no music :
// make sure we can edit 10 seconds after the end of the current chart
if (chart_state and not chart_state->chart.notes.empty()) {
const auto beat_of_last_event = chart_state->chart.notes.crbegin()->second.get_end();
new_range += time_at(beat_of_last_event) + sf::seconds(10);
}
// and at at least the first whole minute in any case
new_range += sf::seconds(60);
return new_range;
}
}
/*
* Reloads the album cover from what's indicated in the "album cover path" field
* of the song Resets the album cover state if anything fails

View File

@ -157,6 +157,7 @@ private:
*/
Interval<sf::Time> editable_range;
void reload_editable_range();
Interval<sf::Time> choose_editable_range();
void reload_jacket();
void reload_music();
void reload_preview_audio();

View File

@ -187,7 +187,7 @@ int main() {
case sf::Keyboard::Tab:
if (editor_state and editor_state->chart_state) {
editor_state->chart_state->handle_time_selection_tab(
editor_state->current_snaped_beats()
editor_state->current_exact_beats()
);
}
break;
@ -432,7 +432,7 @@ int main() {
}
if (noteTick.shouldPlay and editor_state->chart_state) {
int note_count = 0;
for (const auto& note : editor_state->chart_state->visible_notes) {
for (const auto& [_, note] : editor_state->chart_state->visible_notes) {
if (note.get_time() >= editor_state->previous_exact_beats() and note.get_time() <= editor_state->current_exact_beats()) {
note_count++;
}

View File

@ -9,7 +9,7 @@
#include "variant_visitor.hpp"
/*
Stores a vector of notes with times relative to the first note in the vector,
Stores a collection of notes with times relative to the first note in the vector,
to allow pasting notes at another time in the chart by simply shifting
all the note starting times.
*/

View File

@ -4,24 +4,75 @@
TEST_CASE("better::Notes") {
better::Notes original;
original.insert(better::TapNote{0, {0,0}});
original.insert(better::TapNote{1, {1,0}});
original.insert(better::TapNote{2, {2,0}});
original.insert(better::TapNote{3, {3,0}});
better::Notes reference_copy;
reference_copy.insert(better::TapNote{1, {1,0}});
reference_copy.insert(better::TapNote{2, {2,0}});
SUBCASE("can be copied on a subrange") {
SUBCASE("can be copied on a subrange using .between()") {
better::Notes original;
original.insert(better::TapNote{0, {0,0}});
original.insert(better::TapNote{1, {1,0}});
original.insert(better::TapNote{2, {2,0}});
original.insert(better::TapNote{3, {3,0}});
better::Notes reference_copy;
reference_copy.insert(better::TapNote{1, {1,0}});
reference_copy.insert(better::TapNote{2, {2,0}});
better::Notes copy = original.between({1,2});
CHECK(copy == reference_copy);
CHECK(copy.begin()->second == better::TapNote{1, {1,0}});
CHECK(copy.rbegin()->second == better::TapNote{2, {2,0}});
SUBCASE("the copy survives the destruction of the original") {
original.interval_tree::~interval_tree();
}
SUBCASE("a copy created with .between()") {
better::Notes copy;
better::Notes reference_copy;
reference_copy.insert(better::TapNote{1, {1,0}});
reference_copy.insert(better::TapNote{2, {2,0}});
SUBCASE("survivres the original's destruction") {
{
better::Notes original;
original.insert(better::TapNote{0, {0,0}});
original.insert(better::TapNote{1, {1,0}});
original.insert(better::TapNote{2, {2,0}});
original.insert(better::TapNote{3, {3,0}});
copy = original.between({1,2});
}
CHECK(copy == reference_copy);
CHECK(copy.begin()->second == better::TapNote{1, {1,0}});
CHECK(copy.rbegin()->second == better::TapNote{2, {2,0}});
}
SUBCASE("survivres being created in another scope") {
better::Notes original;
original.insert(better::TapNote{0, {0,0}});
original.insert(better::TapNote{1, {1,0}});
original.insert(better::TapNote{2, {2,0}});
original.insert(better::TapNote{3, {3,0}});
{
copy = original.between({1,2});
}
CHECK(copy == reference_copy);
CHECK(copy.begin()->second == better::TapNote{1, {1,0}});
CHECK(copy.rbegin()->second == better::TapNote{2, {2,0}});
}
}
SUBCASE("can be searched with .contains()") {
better::Notes original;
original.insert(better::TapNote{0, {0,0}});
better::TapNote a = {0, {0,0}};
better::TapNote b = {0, {1,0}};
better::LongNote c = {0, {0,0}, 1, {0,1}};
CHECK(original.contains(a));
CHECK_FALSE(original.contains(b));
CHECK_FALSE(original.contains(c));
}
}