1 #pragma once 2 3 #include "config.hpp" 4 #include "power_button_profile.hpp" 5 6 #include <memory> 7 #include <unordered_map> 8 9 namespace phosphor::button 10 { 11 12 using powerButtonProfileCreator = 13 std::function<std::unique_ptr<PowerButtonProfile>(sdbusplus::bus_t& bus)>; 14 15 /** 16 * @class PowerButtonProfileFactory 17 * 18 * Creates the custom power button profile class if one is set with 19 * the 'power-button-profile' meson option. 20 * 21 * The createProfile() method will return a nullptr if no custom 22 * profile is enabled. 23 */ 24 class PowerButtonProfileFactory 25 { 26 public: instance()27 static PowerButtonProfileFactory& instance() 28 { 29 static PowerButtonProfileFactory factory; 30 return factory; 31 } 32 33 template <typename T> addToRegistry()34 void addToRegistry() 35 { 36 profileRegistry[std::string(T::getName())] = [](sdbusplus::bus_t& bus) { 37 return std::make_unique<T>(bus); 38 }; 39 } 40 createProfile(sdbusplus::bus_t & bus)41 std::unique_ptr<PowerButtonProfile> createProfile(sdbusplus::bus_t& bus) 42 { 43 // Find the creator method named after the 44 // 'power-button-profile' option value. 45 auto objectIter = profileRegistry.find(POWER_BUTTON_PROFILE); 46 if (objectIter != profileRegistry.end()) 47 { 48 return objectIter->second(bus); 49 } 50 else 51 { 52 return nullptr; 53 } 54 } 55 56 private: 57 PowerButtonProfileFactory() = default; 58 59 std::unordered_map<std::string, powerButtonProfileCreator> profileRegistry; 60 }; 61 62 /** 63 * @brief Registers a power button profile with the factory. 64 * 65 * Declare a static instance of this at the top of the profile 66 * .cpp file like: 67 * static PowerButtonProfileRegister<MyClass> register; 68 */ 69 template <class T> 70 class PowerButtonProfileRegister 71 { 72 public: PowerButtonProfileRegister()73 PowerButtonProfileRegister() 74 { 75 PowerButtonProfileFactory::instance().addToRegistry<T>(); 76 } 77 }; 78 } // namespace phosphor::button 79