1 #pragma once
2 
3 #include "button_config.hpp"
4 #include "button_interface.hpp"
5 
6 #include <phosphor-logging/elog-errors.hpp>
7 
8 #include <unordered_map>
9 
10 using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
11     sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg)>;
12 
13 /**
14  * @brief This is abstract factory for the creating phosphor buttons objects
15  * based on the button  / formfactor type given.
16  */
17 
18 class ButtonFactory
19 {
20   public:
instance()21     static ButtonFactory& instance()
22     {
23         static ButtonFactory buttonFactoryObj;
24         return buttonFactoryObj;
25     }
26 
27     /**
28      * @brief this method creates a key and value pair element
29      * for the given button interface where key is the form factor
30      * name and the value is lambda method to return
31      * the instance of the button interface.
32      * This key value pair is stored in the Map buttonIfaceRegistry.
33      */
34 
35     template <typename T>
addToRegistry()36     void addToRegistry()
37     {
38         buttonIfaceRegistry[std::string(T::getFormFactorName())] =
39             [](sdbusplus::bus_t& bus, EventPtr& event,
40                ButtonConfig& buttonCfg) {
41                 return std::make_unique<T>(bus, T::getDbusObjectPath(), event,
42                                            buttonCfg);
43             };
44     }
45     /**
46      * @brief this method returns the button interface object
47      *    corresponding to the button formfactor name provided
48      */
49     std::unique_ptr<ButtonIface>
createInstance(const std::string & name,sdbusplus::bus_t & bus,EventPtr & event,ButtonConfig & buttonCfg)50         createInstance(const std::string& name, sdbusplus::bus_t& bus,
51                        EventPtr& event, ButtonConfig& buttonCfg)
52     {
53         // find matching name in the registry and call factory method.
54         auto objectIter = buttonIfaceRegistry.find(name);
55         if (objectIter != buttonIfaceRegistry.end())
56         {
57             return objectIter->second(bus, event, buttonCfg);
58         }
59         else
60         {
61             return nullptr;
62         }
63     }
64 
65   private:
66     // This map is the registry for keeping supported button interface types.
67     std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry;
68 };
69 
70 template <class T>
71 class ButtonIFRegister
72 {
73   public:
ButtonIFRegister()74     ButtonIFRegister()
75     {
76         // register the class factory function
77         ButtonFactory::instance().addToRegistry<T>();
78     }
79 };
80