Mercurial > foo_out_sdl
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/cfg_objList.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,160 @@ +#pragma once + +#include <SDK/cfg_var.h> + +#if FOOBAR2020 +#include <SDK/configStore.h> +namespace cfg_var_modern { + template<typename obj_t> + class cfg_objList : private cfg_var_common { + public: + cfg_objList(const GUID& guid) : cfg_var_common(guid) { } + template<typename source_t, unsigned source_count> cfg_objList(const GUID& guid, const source_t(&source)[source_count]) : cfg_var_common(guid) { + m_defaults.resize(source_count); + for( unsigned walk = 0; walk < source_count; ++ walk) m_defaults[walk] = source[walk]; + } + + void clear() { set(std::vector<obj_t>()); } + void remove_all() { clear(); } + size_t remove_mask(pfc::bit_array const& arg) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + size_t gone = pfc::remove_mask_t(m_list, arg); + if (gone > 0) save(); + return gone; + } + //! Returns number of items removed. + template<typename pred_t> size_t remove_if(pred_t&& p) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + const auto nBefore = m_list.size(); + const size_t nAfter = pfc::remove_if_t(m_list, std::forward<pred_t>(p)); + const auto gone = nAfter - nBefore; + if (gone > 0) save(); + return gone; + } + bool remove_item(obj_t const& v) { + return remove_if([&v](const obj_t& arg) { return v == arg; }) != 0; + } + size_t size() { init(); PFC_INSYNC_READ(m_listGuard);return m_list.size(); } + size_t get_count() { return size(); } + size_t get_size() { return size(); } + + obj_t get(size_t idx) { init(); PFC_INSYNC_READ(m_listGuard); return m_list[idx]; } + + obj_t operator[] (size_t idx) { return get(idx); } + + template<typename arg_t> + void set(size_t idx, arg_t&& v) { + init(); + PFC_INSYNC_WRITE(m_listGuard); m_list[idx] = std::forward<arg_t>(v); save(); + } + bool have_item(obj_t const& arg) { + return find_item(arg) != SIZE_MAX; + } + size_t find_item(obj_t const& arg) { + init(); + PFC_INSYNC_READ(m_listGuard); + for (size_t idx = 0; idx < m_list.size(); ++idx) { + if (m_list[idx] == arg) return idx; + } + return SIZE_MAX; + } + template<typename arg_t> + void insert_item(size_t idx, arg_t&& arg) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + m_list.insert(m_list.begin() + idx, std::forward<arg_t>(arg)); + save(); + } + template<typename arg_t> + void set_items(arg_t&& arg) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + m_list.clear(); + for (auto& item : arg) m_list.push_back(item); + save(); + } + template<typename arg_t> + void insert_items(arg_t&& arg, size_t at) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + m_list.insert(m_list.begin() + at, arg.begin(), arg.end()); + save(); + } + template<typename arg_t> + void add_items(arg_t&& arg) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + + m_list.insert(m_list.end(), arg.begin(), arg.end()); + save(); + } + template<typename arg_t> + void add_item(arg_t&& arg) { + init(); + PFC_INSYNC_WRITE(m_listGuard); + m_list.push_back(std::forward<arg_t>(arg)); + save(); + } + template<typename arg_t> + void set(arg_t&& arg) { + init(); + set_(std::forward<arg_t>(arg)); + } + std::vector<obj_t> get() { + init(); + PFC_INSYNC_READ(m_listGuard); + return m_list; + } + + + private: + void init() { + std::call_once(m_init, [this] { + auto blob = fb2k::configStore::get()->getConfigBlob(formatName(), nullptr); + if (blob.is_valid()) try { + stream_reader_formatter_simple<> reader(blob->data(), blob->size()); + std::vector<obj_t> data; + uint32_t count; reader >> count; data.resize(count); + for (auto& v : data) reader >> v; + set_(std::move(data), false); + return; + } catch(...) {} // fall through, set defaults + set_(m_defaults, false); + }); + } + template<typename arg_t> + void set_(arg_t&& arg, bool bSave = true) { + PFC_INSYNC_WRITE(m_listGuard); + m_list = std::forward<arg_t>(arg); + if (bSave) save(); + } + void save() { + // assumes write sync + stream_writer_formatter_simple<> out; + out << (uint32_t)m_list.size(); + for (auto& v : m_list) out << v; + fb2k::configStore::get()->setConfigBlob(formatName(), out.m_buffer.get_ptr(), out.m_buffer.get_size()); + } +#ifdef FOOBAR2000_HAVE_CFG_VAR_LEGACY + void set_data_raw(stream_reader* p_stream, t_size p_sizehint, abort_callback& p_abort) override { + stream_reader_formatter<> reader(*p_stream, p_abort); + std::vector<obj_t> data; + uint32_t count; reader >> count; data.resize(count); + for (auto& v : data) reader >> v; + set(std::move(data)); + } +#endif + + std::vector<obj_t> m_list; + pfc::readWriteLock m_listGuard; + + std::once_flag m_init; + + std::vector<obj_t> m_defaults; + }; + +} +#endif // FOOBAR2020 +
