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: 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_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> 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: 74 ButtonIFRegister() 75 { 76 // register the class factory function 77 ButtonFactory::instance().addToRegistry<T>(); 78 } 79 }; 80