Mercurial > foo_out_sdl
view foosdk/sdk/foobar2000/SDK/utility.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 source
#include "foobar2000-sdk-pch.h" #include "foosort.h" #include <functional> namespace pfc { /* Redirect PFC methods to shared.dll If you're getting linker multiple-definition errors on these, change build configuration of PFC from "Debug" / "Release" to "Debug FB2K" / "Release FB2K" */ #ifdef _WIN32 BOOL winFormatSystemErrorMessageHook(pfc::string_base & p_out, DWORD p_code) { return uFormatSystemErrorMessage(p_out, p_code); } #endif void crashHook() { uBugCheck(); } } // file_lock_manager.h functionality #include "file_lock_manager.h" namespace { class file_lock_interrupt_impl : public file_lock_interrupt { public: void interrupt( abort_callback & a ) { f(a); } std::function<void (abort_callback&)> f; }; } file_lock_interrupt::ptr file_lock_interrupt::create( std::function< void (abort_callback&)> f ) { service_ptr_t<file_lock_interrupt_impl> i = new service_impl_t<file_lock_interrupt_impl>(); i->f = f; return i; } // file_info_filter.h functionality #include "file_info_filter.h" namespace { class file_info_filter_lambda : public file_info_filter { public: bool apply_filter(trackRef p_track,t_filestats p_stats,file_info & p_info) override { return f(p_track, p_stats, p_info); } func_t f; }; } file_info_filter::ptr file_info_filter::create(func_t f) { auto o = fb2k::service_new<file_info_filter_lambda>(); o->f = f; return o; } // threadPool.h functionality #include "threadPool.h" namespace fb2k { void inWorkerThread(std::function<void()> f) { fb2k::splitTask(f); } void inCpuWorkerThread(std::function<void()> f) { cpuThreadPool::get()->runSingle(threadEntry::make(f)); } } namespace { class threadEntryImpl : public fb2k::threadEntry { public: void run() override { f(); } std::function<void()> f; }; } namespace fb2k { threadEntry::ptr threadEntry::make(std::function<void()> f) { auto ret = fb2k::service_new<threadEntryImpl>(); ret->f = f; return ret; } void cpuThreadPool::runMulti_(std::function<void()> f, size_t numRuns) { this->runMulti(threadEntry::make(f), numRuns, true); } void cpuThreadPool::runMultiHelper(std::function<void()> f, size_t numRuns) { if (numRuns == 0) return; #if FOOBAR2000_TARGET_VERSION >= 81 get()->runMulti_(f, numRuns); #else if (numRuns == 1) { f(); return; } size_t numThreads = numRuns - 1; struct rec_t { pfc::thread2 trd; std::exception_ptr ex; }; pfc::array_staticsize_t<rec_t> threads; threads.set_size_discard(numThreads); for (size_t walk = 0; walk < numThreads; ++walk) { threads[walk].trd.startHere([f, &threads, walk] { try { f(); } catch (...) { threads[walk].ex = std::current_exception(); } }); } std::exception_ptr exMain; try { f(); } catch (...) { exMain = std::current_exception(); } for (size_t walk = 0; walk < numThreads; ++walk) { threads[walk].trd.waitTillDone(); } if (exMain) std::rethrow_exception(exMain); for (size_t walk = 0; walk < numThreads; ++walk) { auto & ex = threads[walk].ex; if (ex) std::rethrow_exception(ex); } #endif } } #if FOOBAR2020 // timer.h functionality #include "timer.h" #include <memory> namespace fb2k { void callLater(double timeAfter, std::function< void() > func) { PFC_ASSERT( core_api::is_main_thread() ); auto releaseMe = std::make_shared<objRef>(); *releaseMe = registerTimer(timeAfter, [=] { if (releaseMe->is_valid()) { // ensure we get here once func(); releaseMe->release(); // warning: this should destroy objects that called us, hence func() call must go first } }); } objRef registerTimer(double interval, std::function<void()> func) { PFC_ASSERT( core_api::is_main_thread() ); return static_api_ptr_t<timerManager>()->addTimer(interval, makeCompletionNotify([func](unsigned) { func(); })); } } #endif // FOOBAR2020 // autoplaylist.h functionality #include "autoplaylist.h" bool autoplaylist_client::supports_async_() { autoplaylist_client_v3::ptr v3; bool rv = false; if (v3 &= this) { rv = v3->supports_async(); } return rv; } bool autoplaylist_client::supports_get_contents_() { autoplaylist_client_v3::ptr v3; bool rv = false; if (v3 &= this) { rv = v3->supports_get_contents(); } return rv; } void autoplaylist_client_v3::filter(metadb_handle_list_cref data, bool * out) { filter_v2(data, nullptr, out, fb2k::noAbort); } bool autoplaylist_client_v3::sort(metadb_handle_list_cref p_items,t_size * p_orderbuffer) { return sort_v2(p_items, p_orderbuffer, fb2k::noAbort); } #include "noInfo.h" namespace fb2k { noInfo_t noInfo; } // library_callbacks.h functionality #include "library_callbacks.h" bool library_callback::is_modified_from_hook() { auto api = library_manager_v5::tryGet(); if (api.is_valid()) return api->library_status(library_manager_v5::status_current_callback_from_hook, 0, nullptr, 0) != 0; else return false; } void library_callback_dynamic::register_callback() { library_manager_v3::get()->register_callback(this); } void library_callback_dynamic::unregister_callback() { library_manager_v3::get()->unregister_callback(this); } void library_callback_v2_dynamic::register_callback() { library_manager_v4::get()->register_callback_v2(this); } void library_callback_v2_dynamic::unregister_callback() { library_manager_v4::get()->unregister_callback_v2(this); } // configCache.h functionality #include "configCache.h" #include "configStore.h" bool fb2k::configBoolCache::get() { std::call_once(m_init, [this] { auto api = fb2k::configStore::get(); auto refresh = [this, api] { m_value = api->getConfigBool(m_var, m_def); }; api->addPermanentNotify(m_var, refresh); refresh(); }); return m_value; } int64_t fb2k::configIntCache::get() { std::call_once(m_init, [this] { auto api = fb2k::configStore::get(); auto refresh = [this, api] { m_value = api->getConfigInt(m_var, m_def); }; api->addPermanentNotify(m_var, refresh); refresh(); }); return m_value; } void fb2k::configBoolCache::set(bool v) { m_value = v; fb2k::configStore::get()->setConfigBool(m_var, v); } void fb2k::configIntCache::set(int64_t v) { m_value = v; fb2k::configStore::get()->setConfigBool(m_var, v); } // keyValueIO.h functionality #include "keyValueIO.h" int fb2k::keyValueIO::getInt( const char * name ) { auto str = get(name); if ( str.is_empty() ) return 0; return (int) pfc::atoi64_ex( str->c_str(), str->length() ); } void fb2k::keyValueIO::putInt( const char * name, int val ) { put( name, pfc::format_int(val) ); } // fileDialog.h functionality #include "fileDialog.h" #include "fsitem.h" namespace { using namespace fb2k; class fileDialogNotifyImpl : public fileDialogNotify { public: void dialogCancelled() {} void dialogOK2(arrayRef fsItems) { recv(fsItems); } std::function< void (arrayRef) > recv; }; } fb2k::fileDialogNotify::ptr fb2k::fileDialogNotify::create( std::function<void (arrayRef) > recv ) { service_ptr_t<fileDialogNotifyImpl> obj = new service_impl_t< fileDialogNotifyImpl >(); obj->recv = recv; return obj; } void fb2k::fileDialogSetup::run(fileDialogReply_t reply) { this->run(fb2k::fileDialogNotify::create(reply)); } void fb2k::fileDialogSetup::runSimple(fileDialogGetPath_t reply) { fb2k::fileDialogReply_t wrapper = [reply] (fb2k::arrayRef arg) { if ( arg.is_empty() ) {PFC_ASSERT(!"???"); return; } if ( arg->size() != 1 ) { PFC_ASSERT(!"???"); return; } auto obj = arg->itemAt(0); fsItemBase::ptr fsitem; if ( fsitem &= obj ) { reply( fsitem->canonicalPath() ); return; } fb2k::stringRef str; if ( str &= obj ) { reply(str); return; } PFC_ASSERT( !"???" ); }; this->run(wrapper); } #include "input_file_type.h" void fb2k::fileDialogSetup::setAudioFileTypes() { pfc::string8 temp; input_file_type::build_openfile_mask(temp); this->setFileTypes( temp ); } #include "search_tools.h" void search_filter_v2::test_multi_here(metadb_handle_list& ref, abort_callback& abort) { pfc::array_t<bool> mask; mask.resize(ref.get_size()); this->test_multi_ex(ref, mask.get_ptr(), abort); ref.filter_mask(mask.get_ptr()); } // core_api.h namespace fb2k { bool isDebugModeActive() { #if PFC_DEBUG return true; #else auto api = fb2k::configStore::tryGet(); if (api.is_empty()) return false; return api->getConfigBool("core.debugMode"); #endif } #if FB2K_SUPPORT_LOW_MEM_MODE static bool _isLowMemModeActive() { auto api = fb2k::configStore::tryGet(); if (api.is_empty()) return false; return api->getConfigBool("core.lowMemMode"); } bool isLowMemModeActive() { static bool cached = _isLowMemModeActive(); return cached; } #endif } // callback_merit.h namespace fb2k { callback_merit_t callback_merit_of(service_ptr obj) { { callback_with_merit::ptr q; if (q &= obj) return q->get_callback_merit(); } { metadb_io_callback_v2::ptr q; if (q &= obj) return q->get_callback_merit(); } return callback_merit_default; } } #ifdef _WIN32 #include "message_loop.h" message_filter_impl_base::message_filter_impl_base() { PFC_ASSERT( core_api::is_main_thread() ); message_loop::get()->add_message_filter(this); } message_filter_impl_base::message_filter_impl_base(t_uint32 lowest, t_uint32 highest) { PFC_ASSERT( core_api::is_main_thread() ); message_loop_v2::get()->add_message_filter_ex(this, lowest, highest); } message_filter_impl_base::~message_filter_impl_base() { PFC_ASSERT( core_api::is_main_thread() ); message_loop::get()->remove_message_filter(this); } bool message_filter_impl_accel::pretranslate_message(MSG * p_msg) { if (m_wnd != NULL) { if (GetActiveWindow() == m_wnd) { if (TranslateAccelerator(m_wnd,m_accel.get(),p_msg) != 0) { return true; } } } return false; } message_filter_impl_accel::message_filter_impl_accel(HINSTANCE p_instance,const TCHAR * p_accel) { m_accel.load(p_instance,p_accel); } bool message_filter_remap_f1::pretranslate_message(MSG * p_msg) { if (IsOurMsg(p_msg) && m_wnd != NULL && GetActiveWindow() == m_wnd) { ::PostMessage(m_wnd, WM_SYSCOMMAND, SC_CONTEXTHELP, -1); return true; } return false; } #endif
