voice_audio_multi/app/recipe/recipe.cpp
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

94 lines
2.7 KiB
C++

#include "recipe.h"
#include <algorithm>
#include <stdexcept>
#include <utility>
namespace minitts::app {
namespace {
std::vector<RecipeFactory> & recipe_factories() {
static std::vector<RecipeFactory> factories;
return factories;
}
} // namespace
RecipePluginRegistration::RecipePluginRegistration(RecipeFactory factory) {
if (!factory) {
throw std::runtime_error("cannot register an empty recipe factory");
}
recipe_factories().push_back(std::move(factory));
}
std::unordered_map<std::string, std::string> options_for_recipe_role(
const std::unordered_map<std::string, std::string> & options,
std::string_view role,
std::initializer_list<std::string_view> recipe_roles,
bool include_shared) {
std::unordered_map<std::string, std::string> selected;
const std::string prefix = std::string(role) + ".";
for (const auto & [key, value] : options) {
if (key.rfind(prefix, 0) == 0) {
continue;
}
bool belongs_to_another_role = false;
for (const auto candidate : recipe_roles) {
const std::string candidate_prefix = std::string(candidate) + ".";
if (key.rfind(candidate_prefix, 0) == 0) {
belongs_to_another_role = true;
break;
}
}
if (include_shared && !belongs_to_another_role) {
selected.emplace(key, value);
}
}
for (const auto & [key, value] : options) {
if (key.rfind(prefix, 0) == 0) {
selected.insert_or_assign(key.substr(prefix.size()), value);
}
}
return selected;
}
void RecipeRegistry::add(std::unique_ptr<IRecipe> recipe) {
if (!recipe) {
throw std::runtime_error("cannot register a null recipe");
}
const auto id = recipe->id();
if (id.empty()) {
throw std::runtime_error("recipe id must not be empty");
}
if (!recipes_.emplace(id, std::move(recipe)).second) {
throw std::runtime_error("duplicate recipe id: " + id);
}
}
const IRecipe & RecipeRegistry::require(std::string_view id) const {
const auto found = recipes_.find(std::string(id));
if (found == recipes_.end()) {
throw std::runtime_error("unknown recipe: " + std::string(id));
}
return *found->second;
}
std::vector<std::string> RecipeRegistry::ids() const {
std::vector<std::string> ids;
ids.reserve(recipes_.size());
for (const auto & [id, _] : recipes_) {
ids.push_back(id);
}
std::sort(ids.begin(), ids.end());
return ids;
}
RecipeRegistry make_recipe_registry() {
RecipeRegistry registry;
for (const auto & factory : recipe_factories()) {
registry.add(factory());
}
return registry;
}
} // namespace minitts::app