1 #pragma once
2 
3 #include "button_interface.hpp"
4 #include "gpio.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::bus& 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:
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>
36     void addToRegistry()
37     {
38         buttonIfaceRegistry[std::string(T::getFormFactorName())] =
39             [](sdbusplus::bus::bus& 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(std::string name,
50                                                 sdbusplus::bus::bus& bus,
51                                                 EventPtr& event,
52                                                 buttonConfig& buttonCfg)
53     {
54         // find matching name in the registry and call factory method.
55         auto objectIter = buttonIfaceRegistry.find(name);
56         if (objectIter != buttonIfaceRegistry.end())
57         {
58             return objectIter->second(bus, event, buttonCfg);
59         }
60         else
61         {
62             return nullptr;
63         }
64     }
65 
66   private:
67     // This map is the registry for keeping supported button interface types.
68     std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry;
69 };
70 
71 template <class T>
72 class ButtonIFRegister
73 {
74   public:
75     ButtonIFRegister()
76     {
77         // register the class factory function
78         ButtonFactory::instance().addToRegistry<T>();
79     }
80 };