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