Mercurial > libanimone
view src/strategist.cc @ 32:93224b26a0ee default tip
player: efforts towards C-ization
author | Paper <paper@tflc.us> |
---|---|
date | Mon, 10 Feb 2025 19:17:29 -0500 |
parents | 668f4f31ddda |
children |
line wrap: on
line source
#include <regex> #include <unordered_map> #include "animone.h" #include "animone/a11y.h" #include "animone/fd.h" #include "animone/strategies.h" #include "animone/util.h" /* This file was changed lots from anisthesia. Most notably we don't use classes here * anymore, and we just pass the result vector to different function that append * to the result (which is better imo) */ static bool ApplyWindowTitleFormat(const std::string& format, std::string& title) { if (format.empty()) return false; const std::regex pattern(format); std::smatch match; std::regex_match(title, match, pattern); // Use the first non-empty match result, because the regular expression may // contain multiple sub-expressions. for (size_t i = 1; i < match.size(); ++i) { if (!match.str(i).empty()) { title = match.str(i); return true; } } // Results are empty, but the match was successful if (!match.empty()) { title.clear(); return true; } return true; } static animone::MediaInfoType InferMediaInformationType(const std::string& str) { const std::regex path_pattern(R"(^(?:[A-Za-z]:[/\\]|\\\\)[^<>:"/\\|?*]+)"); return (std::regex_search(str, path_pattern)) ? animone::MediaInfoType::File : animone::MediaInfoType::Unknown; } static bool AddMedia(animone::Result *result, const animone::MediaInfo media_information) { if (media_information.value.empty()) return false; animone::Media media; media.information = {media_information}; result->media.push_back(std::move(media)); return true; } /* ------------------------------------------------------------------------- */ /* strategies */ typedef bool (*strategy_spec_t)(animone::Result *results, size_t results_size); static bool ApplyWindowTitleStrategy(animone::Result *results, size_t results_size) { bool success = false; for (size_t i = 0; i < results_size; i++) { auto title = results[i].window.text; if (title.empty()) continue; ApplyWindowTitleFormat(results[i].player.window_title_format, title); success |= AddMedia(&results[i], {InferMediaInformationType(title), title}); } return success; } static bool ApplyOpenFilesStrategy(animone::Result *results, size_t results_size) { bool success = false; std::set<animone::internal::pid_t> pids; for (size_t i = 0; i < results_size; i++) pids.insert(results[i].process.pid); auto open_file_proc = [&](const animone::internal::OpenFile& file) -> bool { animone::Result *result = NULL; for (size_t i = 0; i < results_size; i++) { if (results[i].process.pid == file.pid) { result = &results[i]; break; } } if (!result) return false; success |= AddMedia(result, {animone::MediaInfoType::File, file.path}); return true; }; animone::internal::EnumerateOpenFiles(pids, open_file_proc); return success; } static bool ApplyAccessibilityStrategy(animone::Result *results, size_t results_size) { int success = 0; for (size_t i = 0; i < results_size; i++) { // TODO refactor our processing function specs to take in userdata auto web_browser_proc = [results, i](const animone::internal::WebBrowserInformation& info) -> void { auto value = info.value; switch (info.type) { case animone::internal::WebBrowserInformationType::Address: AddMedia(&results[i], {animone::MediaInfoType::Url, value}); break; case animone::internal::WebBrowserInformationType::Title: ApplyWindowTitleFormat(results[i].player.window_title_format, value); AddMedia(&results[i], {animone::MediaInfoType::Title, value}); break; case animone::internal::WebBrowserInformationType::Tab: AddMedia(&results[i], {animone::MediaInfoType::Tab, value}); break; } }; success |= animone::internal::GetWebBrowserInformation(results[i], web_browser_proc); } return success; } /* ------------------------------------------------------------------------- */ int animone_internal_ApplyStrategies(animone::Result *results, size_t results_size) { static const strategy_spec_t strategies[] = { ApplyWindowTitleStrategy, ApplyOpenFilesStrategy, ApplyAccessibilityStrategy }; int success = 0; for (size_t i = 0; i < (sizeof(strategies)/sizeof(*strategies)); i++) success |= strategies[i](results, results_size); return success; }