Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/SDK/track_property.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/SDK/track_property.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,161 @@ +#include "foobar2000-sdk-pch.h" + +#include "track_property.h" +#include "metadb_info_container_impl.h" + +namespace { + class track_property_provider_v3_info_source_impl : public track_property_provider_v3_info_source { + public: + track_property_provider_v3_info_source_impl(trackListRef items) : m_items(items) {} + trackInfoContainer::ptr get_info(size_t index) { + return trackGetInfoRef(m_items, index); + } + private: + trackListRef m_items; + }; + + class track_property_callback_v2_proxy : public track_property_callback_v2 { + public: + track_property_callback_v2_proxy(track_property_callback & callback) : m_callback(callback) {} + void set_property(const char * p_group, double p_sortpriority, const char * p_name, const char * p_value) { m_callback.set_property(p_group, p_sortpriority, p_name, p_value); } + bool is_group_wanted(const char*) { return true; } + + private: + track_property_callback & m_callback; + }; + + +} + +void track_property_provider_v3::enumerate_properties(trackListRef p_tracks, track_property_callback & p_out) { + track_property_provider_v3_info_source_impl src(p_tracks); track_property_callback_v2_proxy cb(p_out); enumerate_properties_v3(p_tracks, src, cb); +} + +void track_property_provider_v3::enumerate_properties_v2(trackListRef p_tracks, track_property_callback_v2 & p_out) { + track_property_provider_v3_info_source_impl src(p_tracks); enumerate_properties_v3(p_tracks, src, p_out); +} + +void track_property_provider_v4::enumerate_properties_v3(trackListRef items, track_property_provider_v3_info_source & info, track_property_callback_v2 & callback) { + this->enumerate_properties_v4(items, info, callback, fb2k::noAbort ); +} +namespace { + class track_property_provider_v5_info_source_wrap : public track_property_provider_v5_info_source { + public: + track_property_provider_v5_info_source_wrap(track_property_provider_v3_info_source& chain, trackListRef items) : m_chain(chain), m_items(items) {} + track_property_provider_v3_info_source & m_chain; + trackListRef m_items; + + // Not very efficient but gets the job done + metadb_v2_rec_t get_info(size_t index) override { + auto ret = m_items[index]->query_v2_(); + ret.info = m_chain.get_info(index); + return ret; + } + }; +} +void track_property_provider_v5::enumerate_properties_v4(trackListRef items, track_property_provider_v3_info_source& info, track_property_callback_v2& callback, abort_callback& abort) { + track_property_provider_v5_info_source_wrap wrap(info, items); + this->enumerate_properties_v5(items, wrap, callback, abort); +} + +namespace { + class track_property_provider_v3_info_source_wrap_v5 : public track_property_provider_v3_info_source { + public: + track_property_provider_v5_info_source* chain; + trackInfoContainer::ptr get_info(size_t index) override { + auto ret = chain->get_info(index).info; + if (ret.is_empty()) { + ret = m_blank; + } + return ret; + } + metadb_info_container::ptr m_blank = fb2k::service_new<metadb_info_container_const_impl>(); + }; +} +metadb_v2_rec_t track_property_provider_v5_info_source_impl::get_info(size_t index) { +#if FOOBAR2000_TARGET_VERSION >= 81 + return m_infos[index]; +#else + if (index < m_infos.get_size()) return m_infos[index]; + else if (index < m_tracks.get_size()) return m_tracks[index]->query_v2_(); + else uBugCheck(); +#endif +} + +track_property_provider_v5_info_source_impl::track_property_provider_v5_info_source_impl(trackListRef items, abort_callback & a) { + +#if FOOBAR2000_TARGET_VERSION >= 81 + m_infos.resize(items.get_count()); + metadb_v2::get()->queryMultiParallel_(items, [this, &a](size_t idx, metadb_v2_rec_t const& rec) {a.check(); this->m_infos[idx] = rec; }); +#else + auto api = metadb_v2::tryGet(); + if (api.is_valid()) { + m_infos.resize(items.get_count()); + api->queryMultiParallel_(items, [this](size_t idx, metadb_v2_rec_t const& rec) {this->m_infos[idx] = rec; }); + return; + } + // pre-2.0 metadb, talking to metadb directly is OK, no need to get info preemptively + m_tracks = items; +#endif +} + +void track_property_provider::enumerate_properties_helper(trackListRef items, track_property_provider_v5_info_source* info, track_property_callback_v2& callback, abort_callback& abort) { + + if (info == nullptr) { + this->enumerate_properties_helper(items, nullptr, callback, abort); + } else { + { + track_property_provider_v5::ptr v5; + if (v5 &= this) { + v5->enumerate_properties_v5(items, *info, callback, abort); + return; + } + } + + track_property_provider_v3_info_source_wrap_v5 wrap; + wrap.chain = info; + this->enumerate_properties_helper(items, &wrap, callback, abort); + } +} + +void track_property_provider::enumerate_properties_helper(trackListRef items, std::nullptr_t, track_property_callback_v2& callback, abort_callback& abort) { + track_property_provider_v5::ptr v5; + if (v5 &= this) { + track_property_provider_v5_info_source_impl infoImpl(items, abort); + v5->enumerate_properties_v5(items, infoImpl, callback, abort); + return; + } + track_property_provider_v3_info_source* dummy = nullptr; + this->enumerate_properties_helper(items, dummy, callback, abort); +} + +void track_property_provider::enumerate_properties_helper(trackListRef items, track_property_provider_v3_info_source * info, track_property_callback_v2 & callback, abort_callback & abort) { + + abort.check(); + + track_property_provider_v2::ptr v2; + if ( ! this->cast( v2 ) ) { + // no v2 + PFC_ASSERT(core_api::is_main_thread()); + this->enumerate_properties( items, callback ); return; + } + + track_property_provider_v3::ptr v3; + if ( ! (v3 &= v2 ) ) { + // no v3 + PFC_ASSERT(core_api::is_main_thread()); + v2->enumerate_properties_v2( items, callback ); return; + } + + track_property_provider_v3_info_source_impl infoFallback ( items ); + if ( info == nullptr ) info = & infoFallback; + + track_property_provider_v4::ptr v4; + if (! ( v4 &= v3 ) ) { + // no v4 + PFC_ASSERT( core_api::is_main_thread() ); + v3->enumerate_properties_v3( items, *info, callback ); + } else { + v4->enumerate_properties_v4( items, *info, callback, abort ); + } +}
