1 #pragma once
2 
3 #include "button_interface.hpp"
4 #include "gpio.hpp"
5 
6 #include <phosphor-logging/elog-errors.hpp>
7 #include <unordered_map>
8 
9 using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
10     sdbusplus::bus::bus& bus, EventPtr& event, buttonConfig& buttonCfg)>;
11 
12 /**
13  * @brief This is abstract factory for the creating phosphor buttons objects
14  * based on the button  / formfactor type given.
15  */
16 
17 class ButtonFactory
18 {
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 
39         buttonIfaceRegistry[std::string(T::getFormFactorName())] =
40             [](sdbusplus::bus::bus& bus, EventPtr& event,
41                buttonConfig& buttonCfg) {
42                 return std::make_unique<T>(bus, T::getDbusObjectPath(), event,
43                                            buttonCfg);
44             };
45     }
46     /**
47      * @brief this method returns the button interface object
48      *    corresponding to the button formfactor name provided
49      */
50     std::unique_ptr<ButtonIface> createInstance(std::string name,
51                                                 sdbusplus::bus::bus& bus,
52                                                 EventPtr& event,
53                                                 buttonConfig& buttonCfg)
54     {
55 
56         // find matching name in the registry and call factory method.
57         auto objectIter = buttonIfaceRegistry.find(name);
58         if (objectIter != buttonIfaceRegistry.end())
59         {
60             return objectIter->second(bus, event, buttonCfg);
61         }
62         else
63         {
64             return nullptr;
65         }
66     }
67 
68   private:
69     // This map is the registry for keeping supported button interface types.
70     std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry;
71 };
72 
73 template <class T>
74 class ButtonIFRegister
75 {
76   public:
77     ButtonIFRegister()
78     {
79         // register the class factory function
80         ButtonFactory::instance().addToRegistry<T>();
81     }
82 };