From 58ffd551440e4fd5835f3581b6026054610ed9a5 Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Mon, 24 Jul 2023 22:40:30 +0200 Subject: [PATCH] cache collision notes --- src/better_notes.cpp | 2 -- src/chart_state.cpp | 12 ++++++++++++ src/chart_state.hpp | 6 ++++++ src/editor_state.cpp | 20 +++++++++++++++++++- src/editor_state.hpp | 1 + src/history_item.cpp | 5 +++++ src/widgets/linear_view.cpp | 7 ++++--- 7 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/better_notes.cpp b/src/better_notes.cpp index c6a4fa8..a279bdf 100644 --- a/src/better_notes.cpp +++ b/src/better_notes.cpp @@ -82,8 +82,6 @@ namespace better { Old comment dating back to a time when "collision_zone" was set to a fixed value of 1000ms : - --- - Two notes collide if they are within ~one second of each other : Approach and burst animations of original jubeat markers last 16 frames at (supposedly) 30 fps, which means a note needs (a bit more than) half diff --git a/src/chart_state.cpp b/src/chart_state.cpp index 2ce9535..fb891d1 100644 --- a/src/chart_state.cpp +++ b/src/chart_state.cpp @@ -328,6 +328,18 @@ void ChartState::update_visible_notes(const sf::Time& playback_position, const b } }; +void ChartState::update_colliding_notes( + const better::Timing &timing, + const sf::Time &collision_zone +) { + colliding_notes.clear(); + for (const auto& [_, note] : *chart.notes) { + if (chart.notes->is_colliding(note, timing, collision_zone)) { + colliding_notes.insert(note); + } + } +} + void ChartState::toggle_note( const sf::Time& playback_position, std::uint64_t snap, diff --git a/src/chart_state.hpp b/src/chart_state.hpp index 6d648c5..ab68e6f 100644 --- a/src/chart_state.hpp +++ b/src/chart_state.hpp @@ -62,6 +62,12 @@ struct ChartState { Interval visible_bars; std::map note_numbers; + void update_colliding_notes( + const better::Timing &timing, + const sf::Time &collision_zone + ); + better::Notes colliding_notes; + void toggle_note( const sf::Time& playback_position, std::uint64_t snap, diff --git a/src/editor_state.cpp b/src/editor_state.cpp index 01437c0..802d062 100644 --- a/src/editor_state.cpp +++ b/src/editor_state.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -606,6 +607,7 @@ void EditorState::display_playfield(const Markers::marker_type& opt_marker, Judg ); reload_sounds_that_depend_on_notes(); reload_editable_range(); + reload_colliding_notes(); } } // Deal with long note creation stuff @@ -635,7 +637,7 @@ void EditorState::display_playfield(const Markers::marker_type& opt_marker, Judg // then display them std::array collisions = {}; for (const auto& [_, note] : chart_state->visible_notes) { - if (chart_state->chart.notes->is_colliding(note, *applicable_timing, config.editor.collision_zone)) { + if (chart_state->colliding_notes.contains(note)) { collisions[note.get_position().index()] = true; } } @@ -1250,6 +1252,7 @@ void EditorState::display_editor_settings() { config.editor.collision_zone = sf::milliseconds(collision_zone_ms); if (chart_state) { chart_state->density_graph.should_recompute = true; + reload_colliding_notes(); } } ImGui::SameLine(); @@ -1270,6 +1273,7 @@ void EditorState::display_editor_settings() { config.editor.collision_zone = value; if (chart_state) { chart_state->density_graph.should_recompute = true; + reload_colliding_notes(); } } } @@ -1515,6 +1519,7 @@ void EditorState::insert_long_note_just_created() { chart_state->insert_long_note_just_created(snap); reload_sounds_that_depend_on_notes(); reload_editable_range(); + reload_colliding_notes(); } void EditorState::move_backwards_in_time() { @@ -1553,12 +1558,14 @@ void EditorState::cut(NotificationsQueue& nq) { if (chart_state) { chart_state->cut(nq, *applicable_timing, timing_origin()); reload_all_sounds(); + reload_colliding_notes(); } } void EditorState::copy(NotificationsQueue& nq) { if (chart_state) { chart_state->copy(nq); + reload_colliding_notes(); } } @@ -1570,12 +1577,14 @@ void EditorState::paste(NotificationsQueue& nq) { *applicable_timing, timing_origin() ); + reload_colliding_notes(); } } void EditorState::delete_(NotificationsQueue& nq) { if (chart_state) { chart_state->delete_(nq, *applicable_timing, timing_origin()); + reload_colliding_notes(); } } @@ -1631,6 +1640,7 @@ void EditorState::open_chart(const std::string& name) { reload_editable_range(); reload_applicable_timing(); reload_all_sounds(); + reload_colliding_notes(); }; void EditorState::close_chart() { @@ -1655,6 +1665,12 @@ void EditorState::reload_editable_range() { } }; +void EditorState::reload_colliding_notes() { + if (chart_state) { + chart_state->update_colliding_notes(*applicable_timing, config.editor.collision_zone); + } +} + void EditorState::frame_hook() { if (tempo_candidates_loader.valid()) { if (tempo_candidates_loader.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { @@ -1674,6 +1690,7 @@ void EditorState::replace_applicable_timing_with(const better::Timing& new_timin if (chart_state) { chart_state->density_graph.should_recompute = true; } + reload_colliding_notes(); } bool EditorState::note_clap_stream_is_on() const { @@ -1890,6 +1907,7 @@ void EditorState::reload_applicable_timing() { } else { applicable_timing = song.timing; } + reload_colliding_notes(); }; TimingOrigin EditorState::timing_origin() { diff --git a/src/editor_state.hpp b/src/editor_state.hpp index 89542bd..bac44c7 100644 --- a/src/editor_state.hpp +++ b/src/editor_state.hpp @@ -246,6 +246,7 @@ public: void reload_sounds_that_depend_on_timing(); void reload_all_sounds(); void reload_editable_range(); + void reload_colliding_notes(); void frame_hook(); diff --git a/src/history_item.cpp b/src/history_item.cpp index c8a27e8..b73d191 100644 --- a/src/history_item.cpp +++ b/src/history_item.cpp @@ -46,6 +46,7 @@ void AddNotes::do_action(EditorState& ed) const { } ed.chart_state->density_graph.should_recompute = true; ed.chart_state->selected_stuff.notes = notes; + ed.reload_colliding_notes(); } } @@ -60,6 +61,7 @@ void AddNotes::undo_action(EditorState& ed) const { } ed.chart_state->density_graph.should_recompute = true; ed.chart_state->selected_stuff.notes.clear(); + ed.reload_colliding_notes(); } } @@ -128,6 +130,7 @@ void RemoveThenAddNotes::do_action(EditorState& ed) const { } ed.chart_state->density_graph.should_recompute = true; ed.chart_state->selected_stuff.notes = added; + ed.reload_colliding_notes(); } } @@ -145,6 +148,7 @@ void RemoveThenAddNotes::undo_action(EditorState& ed) const { } ed.chart_state->density_graph.should_recompute = true; ed.chart_state->selected_stuff.notes = removed; + ed.reload_colliding_notes(); } } @@ -379,6 +383,7 @@ void ChangeTiming::set_value(EditorState& ed, const better::Timing& value) const std::visit(set_value_, origin); ed.reload_applicable_timing(); ed.reload_sounds_that_depend_on_timing(); + ed.reload_colliding_notes(); if (ed.chart_state) { ed.chart_state->density_graph.should_recompute = true; } diff --git a/src/widgets/linear_view.cpp b/src/widgets/linear_view.cpp index ffa363b..c4c3731 100644 --- a/src/widgets/linear_view.cpp +++ b/src/widgets/linear_view.cpp @@ -518,8 +518,9 @@ void LinearView::draw_tap_note( computed_sizes.collizion_zone_width, collision_zone_height }; + const auto collides = args.chart_state.colliding_notes.contains(tap_note); const auto collision_zone_color = [&](){ - if (args.chart_state.chart.notes->is_colliding(tap_note, args.timing, collision_zone)) { + if (collides) { return colors.conflicting_collision_zone; } else { return colors.normal_collision_zone; @@ -528,7 +529,7 @@ void LinearView::draw_tap_note( const auto tap_note_color = [&](){ if (use_quantization_colors) { return quantization_colors.color_at_beat(tap_note.get_time()); - } else if (args.chart_state.chart.notes->is_colliding(tap_note, args.timing, collision_zone)) { + } else if (collides) { return colors.conflicting_tap_note; } else { return colors.normal_tap_note; @@ -587,7 +588,7 @@ void LinearView::draw_long_note( } }(); auto long_note_color = colors.normal_long_note; - if (args.chart_state.chart.notes->is_colliding(long_note, args.timing, collision_zone)) { + if (args.chart_state.colliding_notes.contains(long_note)) { collision_zone_color = colors.conflicting_collision_zone; if (not use_quantization_colors) { tap_note_color = colors.conflicting_tap_note;