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 };