From 04b7ba907c2b8167454d884d2f801d80e8c1bbc1 Mon Sep 17 00:00:00 2001 From: Reupen Shah Date: Sun, 20 Nov 2022 14:41:46 +0000 Subject: [PATCH] Optimise typing in playlist view to jump to items in foobar2000 2.0 This changes how typing in the playlist view to jump to items works in foobar2000 2.0 to improve performance. Previously, it formatted tracks and columns individually, including style scripts, where this information wasn't already cached. Now, it formats tracks in large batches, and only formats the display script for the first column. This performs better in foobar2000 2.0. There is also no longer any long-term caching involved. --- CHANGELOG.md | 3 ++ foo_ui_columns/ng_playlist/ng_playlist.cpp | 49 ++++++++++++++++++++++ foo_ui_columns/ng_playlist/ng_playlist.h | 30 +++++++++++++ ui_helpers | 2 +- 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f441bf6c9..b805a0fe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ This requires the SVG services component. Text is not supported. +- Performance when typing into the playlist view to jump to an item was improved + in foobar2000 2.0. [[#629](https://github.com/reupen/columns_ui/pull/629)] + ### Bug fixes - A bug where ampersands didn’t render correctly in tab names in the Playlist diff --git a/foo_ui_columns/ng_playlist/ng_playlist.cpp b/foo_ui_columns/ng_playlist/ng_playlist.cpp index 07bba8d3f..d9ad56c46 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist.cpp +++ b/foo_ui_columns/ng_playlist/ng_playlist.cpp @@ -413,6 +413,55 @@ void PlaylistView::s_redraw_all() RedrawWindow(window->get_wnd(), nullptr, nullptr, RDW_INVALIDATE); } +const char* PlaylistView::PlaylistViewSearchContext::get_item_text(size_t index) +{ + constexpr size_t max_batch_size = 1000; + + if (!m_start_index) { + m_playlist_manager->activeplaylist_get_all_items(m_tracks); + m_items.resize(m_tracks.size()); + GetLocalTime(&m_systemtime); + m_start_index = index; + } else if (m_items[index]) { + return m_items[index]->c_str(); + } + + const auto batch_end_index + = std::min(index + max_batch_size, index < *m_start_index ? *m_start_index : m_tracks.size()); + + const auto batch_size = batch_end_index - index; + const auto batch_tracks = pfc::list_partial_ref_t(m_tracks, index, batch_size); + + const bool has_global_variables = m_global_script.is_valid(); + + m_metadb->queryMulti_(batch_tracks, [this, index, has_global_variables](size_t offset, const metadb_v2_rec_t& rec) { + metadb_handle_v2::ptr track; + track &= m_tracks[index + offset]; + + GlobalVariableList global_variables; + DateTitleformatHook tf_hook_date(&m_systemtime); + PlaylistNameTitleformatHook tf_hook_playlist_name; + + if (has_global_variables) { + SetGlobalTitleformatHook tf_hook_set_global(global_variables); + SplitterTitleformatHook tf_hook(&tf_hook_set_global, &tf_hook_date, &tf_hook_playlist_name); + pfc::string8 _; + track->formatTitle_v2(rec, &tf_hook, _, m_global_script, nullptr); + } + + std::string title; + mmh::StringAdaptor adapted_title(title); + + SetGlobalTitleformatHook tf_hook_get_global(global_variables); + SplitterTitleformatHook tf_hook( + has_global_variables ? &tf_hook_get_global : nullptr, &tf_hook_date, &tf_hook_playlist_name); + track->formatTitle_v2(rec, &tf_hook, adapted_title, m_column_script, nullptr); + m_items[index + offset] = std::move(title); + }); + + return m_items[index]->c_str(); +} + void PlaylistView::s_create_message_window() { uie::container_window_v3_config config(L"{columns_ui_playlist_view_message_window_goJRO8xwg7s}", false); diff --git a/foo_ui_columns/ng_playlist/ng_playlist.h b/foo_ui_columns/ng_playlist/ng_playlist.h index 59df9a0b0..ceae50d10 100644 --- a/foo_ui_columns/ng_playlist/ng_playlist.h +++ b/foo_ui_columns/ng_playlist/ng_playlist.h @@ -384,6 +384,27 @@ class PlaylistView size_t get_group_count() { return m_groups.size(); } }; + class PlaylistViewSearchContext : public ListViewSearchContextBase { + public: + explicit PlaylistViewSearchContext(titleformat_object::ptr global_script, titleformat_object::ptr column_script) + : m_global_script(std::move(global_script)) + , m_column_script(std::move(column_script)) + { + } + + const char* get_item_text(size_t index) override; + + private: + SYSTEMTIME m_systemtime; + metadb_handle_list m_tracks; + std::vector> m_items; + std::optional m_start_index; + playlist_manager_v4::ptr m_playlist_manager{playlist_manager_v4::get()}; + metadb_v2::ptr m_metadb{metadb_v2::get()}; + titleformat_object::ptr m_global_script{}; + titleformat_object::ptr m_column_script{}; + }; + static void s_create_message_window(); static void s_destroy_message_window(); @@ -464,6 +485,15 @@ class PlaylistView void notify_update_item_data(size_t index) override; + std::unique_ptr create_search_context() override + { + if (!static_api_test_t() || m_column_data.size() == 0) { + return ListViewPanelBase::create_search_context(); + } + + return std::make_unique(m_script_global, m_column_data[0].m_display_script); + } + const style_data_t& get_style_data(size_t index); void get_insert_items(size_t start, size_t count, InsertItemsContainer& items); void flush_items(); diff --git a/ui_helpers b/ui_helpers index a1eba046f..ae7bd3f17 160000 --- a/ui_helpers +++ b/ui_helpers @@ -1 +1 @@ -Subproject commit a1eba046f3e135d61fc7448f6164778128600e56 +Subproject commit ae7bd3f172b2d2945c5356e54e004feadc486b48