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