1 #pragma once
2 
3 #include "config.hpp"
4 #include "power_button_profile.hpp"
5 
6 #include <memory>
7 #include <unordered_map>
8 
9 namespace phosphor::button
10 {
11 
12 using powerButtonProfileCreator =
13     std::function<std::unique_ptr<PowerButtonProfile>(sdbusplus::bus_t& bus)>;
14 
15 /**
16  * @class PowerButtonProfileFactory
17  *
18  * Creates the custom power button profile class if one is set with
19  * the 'power-button-profile' meson option.
20  *
21  * The createProfile() method will return a nullptr if no custom
22  * profile is enabled.
23  */
24 class PowerButtonProfileFactory
25 {
26   public:
instance()27     static PowerButtonProfileFactory& instance()
28     {
29         static PowerButtonProfileFactory factory;
30         return factory;
31     }
32 
33     template <typename T>
addToRegistry()34     void addToRegistry()
35     {
36         profileRegistry[std::string(T::getName())] = [](sdbusplus::bus_t& bus) {
37             return std::make_unique<T>(bus);
38         };
39     }
40 
createProfile(sdbusplus::bus_t & bus)41     std::unique_ptr<PowerButtonProfile> createProfile(sdbusplus::bus_t& bus)
42     {
43         // Find the creator method named after the
44         // 'power-button-profile' option value.
45         auto objectIter = profileRegistry.find(POWER_BUTTON_PROFILE);
46         if (objectIter != profileRegistry.end())
47         {
48             return objectIter->second(bus);
49         }
50         else
51         {
52             return nullptr;
53         }
54     }
55 
56   private:
57     PowerButtonProfileFactory() = default;
58 
59     std::unordered_map<std::string, powerButtonProfileCreator> profileRegistry;
60 };
61 
62 /**
63  * @brief Registers a power button profile with the factory.
64  *
65  * Declare a static instance of this at the top of the profile
66  * .cpp file like:
67  *    static PowerButtonProfileRegister<MyClass> register;
68  */
69 template <class T>
70 class PowerButtonProfileRegister
71 {
72   public:
PowerButtonProfileRegister()73     PowerButtonProfileRegister()
74     {
75         PowerButtonProfileFactory::instance().addToRegistry<T>();
76     }
77 };
78 } // namespace phosphor::button
79