Line data Source code
1 : #pragma once
2 :
3 : #include <functional>
4 : #include <stdexcept>
5 : #include <string>
6 : #include <unordered_map>
7 :
8 : #include "audio/effects/core/effect.h"
9 :
10 : namespace Amplitron {
11 :
12 : /**
13 : * Registry-based effect factory.
14 : * Replaces the if-chain in PresetManager::create_effect().
15 : * All effect types self-register via EffectRegistrar.
16 : */
17 : class EffectFactory {
18 : public:
19 : using Creator = std::function<std::shared_ptr<Effect>()>;
20 :
21 666 : static EffectFactory& instance() {
22 669 : static EffectFactory factory;
23 666 : return factory;
24 : }
25 :
26 111 : void register_effect(const std::string& type_name, Creator creator) {
27 111 : if (creators_.count(type_name) > 0) {
28 4 : throw std::runtime_error("Duplicate effect registration: " + type_name);
29 : }
30 108 : creators_.emplace(type_name, std::move(creator));
31 109 : }
32 :
33 549 : std::shared_ptr<Effect> create(const std::string& type_name) const {
34 549 : auto it = creators_.find(type_name);
35 549 : if (it != creators_.end()) {
36 465 : return it->second();
37 : }
38 84 : return nullptr;
39 183 : }
40 :
41 6 : std::vector<std::string> registered_types() const {
42 6 : std::vector<std::string> types;
43 6 : types.reserve(creators_.size());
44 114 : for (auto& [name, _] : creators_) {
45 108 : types.push_back(name);
46 : }
47 6 : return types;
48 2 : }
49 :
50 57 : std::shared_ptr<Effect> create_from_type(const std::string& type_name) const {
51 57 : return create(type_name);
52 : }
53 :
54 6 : std::vector<std::string> get_all_type_names() const { return registered_types(); }
55 :
56 : private:
57 8 : EffectFactory() = default;
58 : std::unordered_map<std::string, Creator> creators_;
59 : };
60 :
61 : /**
62 : * RAII helper that registers an effect type at static-init time.
63 : * Usage (in .cpp file):
64 : * static EffectRegistrar<MyEffect> reg("My Effect");
65 : */
66 : template <typename T>
67 : struct EffectRegistrar {
68 144 : explicit EffectRegistrar(const std::string& type_name) {
69 144 : EffectFactory::instance().register_effect(type_name,
70 537 : []() { return std::make_shared<T>(); });
71 144 : }
72 : };
73 :
74 : } // namespace Amplitron
|