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: instance()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> addToRegistry()36 void addToRegistry() 37 { 38 buttonIfaceRegistry[T::getFormFactorName()] = 39 [](sdbusplus::bus_t& bus, EventPtr& event, 40 ButtonConfig& buttonCfg) { 41 return std::make_unique<T>(bus, T::getDbusObjectPath().c_str(), 42 event, buttonCfg); 43 }; 44 } 45 46 template <typename T> addToRegistry(size_t index)47 void addToRegistry(size_t index) 48 { 49 auto indexStr = std::to_string(index); 50 buttonIfaceRegistry[T::getFormFactorName() + indexStr] = 51 [=](sdbusplus::bus_t& bus, EventPtr& event, 52 ButtonConfig& buttonCfg) { 53 return std::make_unique<T>( 54 bus, (T::getDbusObjectPath() + indexStr).c_str(), event, 55 buttonCfg); 56 }; 57 } 58 59 /** 60 * @brief this method returns the button interface object 61 * corresponding to the button formfactor name provided 62 */ 63 std::unique_ptr<ButtonIface> createInstance(const std::string & name,sdbusplus::bus_t & bus,EventPtr & event,ButtonConfig & buttonCfg)64 createInstance(const std::string& name, sdbusplus::bus_t& bus, 65 EventPtr& event, ButtonConfig& buttonCfg) 66 { 67 // find matching name in the registry and call factory method. 68 auto objectIter = buttonIfaceRegistry.find(name); 69 if (objectIter != buttonIfaceRegistry.end()) 70 { 71 return objectIter->second(bus, event, buttonCfg); 72 } 73 else 74 { 75 return nullptr; 76 } 77 } 78 79 private: 80 // This map is the registry for keeping supported button interface types. 81 std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry; 82 }; 83 84 template <class T> 85 class ButtonIFRegister 86 { 87 public: ButtonIFRegister()88 ButtonIFRegister() 89 { 90 // register the class factory function 91 ButtonFactory::instance().addToRegistry<T>(); 92 } 93 ButtonIFRegister(size_t count)94 explicit ButtonIFRegister(size_t count) 95 { 96 // register the class factory function 97 // The index, 'countIter', starts at 1 and increments, 98 // representing slot_1 through slot_N. 99 for (size_t countIter = 1; countIter <= count; countIter++) 100 { 101 ButtonFactory::instance().addToRegistry<T>(countIter); 102 } 103 } 104 }; 105