comparison 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
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 #include "foobar2000-sdk-pch.h"
2
3 #include "track_property.h"
4 #include "metadb_info_container_impl.h"
5
6 namespace {
7 class track_property_provider_v3_info_source_impl : public track_property_provider_v3_info_source {
8 public:
9 track_property_provider_v3_info_source_impl(trackListRef items) : m_items(items) {}
10 trackInfoContainer::ptr get_info(size_t index) {
11 return trackGetInfoRef(m_items, index);
12 }
13 private:
14 trackListRef m_items;
15 };
16
17 class track_property_callback_v2_proxy : public track_property_callback_v2 {
18 public:
19 track_property_callback_v2_proxy(track_property_callback & callback) : m_callback(callback) {}
20 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); }
21 bool is_group_wanted(const char*) { return true; }
22
23 private:
24 track_property_callback & m_callback;
25 };
26
27
28 }
29
30 void track_property_provider_v3::enumerate_properties(trackListRef p_tracks, track_property_callback & p_out) {
31 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);
32 }
33
34 void track_property_provider_v3::enumerate_properties_v2(trackListRef p_tracks, track_property_callback_v2 & p_out) {
35 track_property_provider_v3_info_source_impl src(p_tracks); enumerate_properties_v3(p_tracks, src, p_out);
36 }
37
38 void track_property_provider_v4::enumerate_properties_v3(trackListRef items, track_property_provider_v3_info_source & info, track_property_callback_v2 & callback) {
39 this->enumerate_properties_v4(items, info, callback, fb2k::noAbort );
40 }
41 namespace {
42 class track_property_provider_v5_info_source_wrap : public track_property_provider_v5_info_source {
43 public:
44 track_property_provider_v5_info_source_wrap(track_property_provider_v3_info_source& chain, trackListRef items) : m_chain(chain), m_items(items) {}
45 track_property_provider_v3_info_source & m_chain;
46 trackListRef m_items;
47
48 // Not very efficient but gets the job done
49 metadb_v2_rec_t get_info(size_t index) override {
50 auto ret = m_items[index]->query_v2_();
51 ret.info = m_chain.get_info(index);
52 return ret;
53 }
54 };
55 }
56 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) {
57 track_property_provider_v5_info_source_wrap wrap(info, items);
58 this->enumerate_properties_v5(items, wrap, callback, abort);
59 }
60
61 namespace {
62 class track_property_provider_v3_info_source_wrap_v5 : public track_property_provider_v3_info_source {
63 public:
64 track_property_provider_v5_info_source* chain;
65 trackInfoContainer::ptr get_info(size_t index) override {
66 auto ret = chain->get_info(index).info;
67 if (ret.is_empty()) {
68 ret = m_blank;
69 }
70 return ret;
71 }
72 metadb_info_container::ptr m_blank = fb2k::service_new<metadb_info_container_const_impl>();
73 };
74 }
75 metadb_v2_rec_t track_property_provider_v5_info_source_impl::get_info(size_t index) {
76 #if FOOBAR2000_TARGET_VERSION >= 81
77 return m_infos[index];
78 #else
79 if (index < m_infos.get_size()) return m_infos[index];
80 else if (index < m_tracks.get_size()) return m_tracks[index]->query_v2_();
81 else uBugCheck();
82 #endif
83 }
84
85 track_property_provider_v5_info_source_impl::track_property_provider_v5_info_source_impl(trackListRef items, abort_callback & a) {
86
87 #if FOOBAR2000_TARGET_VERSION >= 81
88 m_infos.resize(items.get_count());
89 metadb_v2::get()->queryMultiParallel_(items, [this, &a](size_t idx, metadb_v2_rec_t const& rec) {a.check(); this->m_infos[idx] = rec; });
90 #else
91 auto api = metadb_v2::tryGet();
92 if (api.is_valid()) {
93 m_infos.resize(items.get_count());
94 api->queryMultiParallel_(items, [this](size_t idx, metadb_v2_rec_t const& rec) {this->m_infos[idx] = rec; });
95 return;
96 }
97 // pre-2.0 metadb, talking to metadb directly is OK, no need to get info preemptively
98 m_tracks = items;
99 #endif
100 }
101
102 void track_property_provider::enumerate_properties_helper(trackListRef items, track_property_provider_v5_info_source* info, track_property_callback_v2& callback, abort_callback& abort) {
103
104 if (info == nullptr) {
105 this->enumerate_properties_helper(items, nullptr, callback, abort);
106 } else {
107 {
108 track_property_provider_v5::ptr v5;
109 if (v5 &= this) {
110 v5->enumerate_properties_v5(items, *info, callback, abort);
111 return;
112 }
113 }
114
115 track_property_provider_v3_info_source_wrap_v5 wrap;
116 wrap.chain = info;
117 this->enumerate_properties_helper(items, &wrap, callback, abort);
118 }
119 }
120
121 void track_property_provider::enumerate_properties_helper(trackListRef items, std::nullptr_t, track_property_callback_v2& callback, abort_callback& abort) {
122 track_property_provider_v5::ptr v5;
123 if (v5 &= this) {
124 track_property_provider_v5_info_source_impl infoImpl(items, abort);
125 v5->enumerate_properties_v5(items, infoImpl, callback, abort);
126 return;
127 }
128 track_property_provider_v3_info_source* dummy = nullptr;
129 this->enumerate_properties_helper(items, dummy, callback, abort);
130 }
131
132 void track_property_provider::enumerate_properties_helper(trackListRef items, track_property_provider_v3_info_source * info, track_property_callback_v2 & callback, abort_callback & abort) {
133
134 abort.check();
135
136 track_property_provider_v2::ptr v2;
137 if ( ! this->cast( v2 ) ) {
138 // no v2
139 PFC_ASSERT(core_api::is_main_thread());
140 this->enumerate_properties( items, callback ); return;
141 }
142
143 track_property_provider_v3::ptr v3;
144 if ( ! (v3 &= v2 ) ) {
145 // no v3
146 PFC_ASSERT(core_api::is_main_thread());
147 v2->enumerate_properties_v2( items, callback ); return;
148 }
149
150 track_property_provider_v3_info_source_impl infoFallback ( items );
151 if ( info == nullptr ) info = & infoFallback;
152
153 track_property_provider_v4::ptr v4;
154 if (! ( v4 &= v3 ) ) {
155 // no v4
156 PFC_ASSERT( core_api::is_main_thread() );
157 v3->enumerate_properties_v3( items, *info, callback );
158 } else {
159 v4->enumerate_properties_v4( items, *info, callback, abort );
160 }
161 }