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