annotate foosdk/sdk/foobar2000/helpers/cfg_objList.h @ 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <SDK/cfg_var.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #if FOOBAR2020
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include <SDK/configStore.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 namespace cfg_var_modern {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 template<typename obj_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 class cfg_objList : private cfg_var_common {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 cfg_objList(const GUID& guid) : cfg_var_common(guid) { }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 template<typename source_t, unsigned source_count> cfg_objList(const GUID& guid, const source_t(&source)[source_count]) : cfg_var_common(guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 m_defaults.resize(source_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 for( unsigned walk = 0; walk < source_count; ++ walk) m_defaults[walk] = source[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 void clear() { set(std::vector<obj_t>()); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 void remove_all() { clear(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 size_t remove_mask(pfc::bit_array const& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 size_t gone = pfc::remove_mask_t(m_list, arg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 if (gone > 0) save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 return gone;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 //! Returns number of items removed.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 template<typename pred_t> size_t remove_if(pred_t&& p) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 const auto nBefore = m_list.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 const size_t nAfter = pfc::remove_if_t(m_list, std::forward<pred_t>(p));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 const auto gone = nAfter - nBefore;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 if (gone > 0) save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 return gone;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 bool remove_item(obj_t const& v) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 return remove_if([&v](const obj_t& arg) { return v == arg; }) != 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 size_t size() { init(); PFC_INSYNC_READ(m_listGuard);return m_list.size(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 size_t get_count() { return size(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 size_t get_size() { return size(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 obj_t get(size_t idx) { init(); PFC_INSYNC_READ(m_listGuard); return m_list[idx]; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 obj_t operator[] (size_t idx) { return get(idx); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 void set(size_t idx, arg_t&& v) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 PFC_INSYNC_WRITE(m_listGuard); m_list[idx] = std::forward<arg_t>(v); save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 bool have_item(obj_t const& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 return find_item(arg) != SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 size_t find_item(obj_t const& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 PFC_INSYNC_READ(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 for (size_t idx = 0; idx < m_list.size(); ++idx) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 if (m_list[idx] == arg) return idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 return SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 void insert_item(size_t idx, arg_t&& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 m_list.insert(m_list.begin() + idx, std::forward<arg_t>(arg));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 void set_items(arg_t&& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 m_list.clear();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 for (auto& item : arg) m_list.push_back(item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 void insert_items(arg_t&& arg, size_t at) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 m_list.insert(m_list.begin() + at, arg.begin(), arg.end());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 void add_items(arg_t&& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 m_list.insert(m_list.end(), arg.begin(), arg.end());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 void add_item(arg_t&& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 m_list.push_back(std::forward<arg_t>(arg));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 void set(arg_t&& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 set_(std::forward<arg_t>(arg));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 std::vector<obj_t> get() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 init();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 PFC_INSYNC_READ(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 return m_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 void init() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 std::call_once(m_init, [this] {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 auto blob = fb2k::configStore::get()->getConfigBlob(formatName(), nullptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 if (blob.is_valid()) try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 stream_reader_formatter_simple<> reader(blob->data(), blob->size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 std::vector<obj_t> data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 uint32_t count; reader >> count; data.resize(count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 for (auto& v : data) reader >> v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 set_(std::move(data), false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 } catch(...) {} // fall through, set defaults
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 set_(m_defaults, false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 });
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 void set_(arg_t&& arg, bool bSave = true) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 PFC_INSYNC_WRITE(m_listGuard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 m_list = std::forward<arg_t>(arg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 if (bSave) save();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 void save() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 // assumes write sync
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 stream_writer_formatter_simple<> out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 out << (uint32_t)m_list.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 for (auto& v : m_list) out << v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 fb2k::configStore::get()->setConfigBlob(formatName(), out.m_buffer.get_ptr(), out.m_buffer.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 #ifdef FOOBAR2000_HAVE_CFG_VAR_LEGACY
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 void set_data_raw(stream_reader* p_stream, t_size p_sizehint, abort_callback& p_abort) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 stream_reader_formatter<> reader(*p_stream, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 std::vector<obj_t> data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 uint32_t count; reader >> count; data.resize(count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 for (auto& v : data) reader >> v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 set(std::move(data));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 std::vector<obj_t> m_list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 pfc::readWriteLock m_listGuard;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 std::once_flag m_init;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 std::vector<obj_t> m_defaults;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 #endif // FOOBAR2020
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160