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