blob: 62b0c723ee34cc8c618d49db9633cbcddc6a0f58 [file] [log] [blame]
Naveen Mosesa1af3292021-12-15 11:47:01 +05301#pragma once
2
Delphine CC Chiuccd7db02023-02-09 14:48:53 +08003#include "button_config.hpp"
Naveen Mosesa1af3292021-12-15 11:47:01 +05304#include "button_interface.hpp"
Matt Spinlerea47dd42025-08-20 13:07:20 -05005#include "config.hpp"
Naveen Mosesa1af3292021-12-15 11:47:01 +05306
7#include <phosphor-logging/elog-errors.hpp>
George Liu5b98f4d2022-06-20 13:31:14 +08008
Naveen Mosesa1af3292021-12-15 11:47:01 +05309#include <unordered_map>
10
11using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080012 sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg)>;
Naveen Mosesa1af3292021-12-15 11:47:01 +053013
14/**
15 * @brief This is abstract factory for the creating phosphor buttons objects
16 * based on the button / formfactor type given.
17 */
18
19class ButtonFactory
20{
Naveen Mosesa1af3292021-12-15 11:47:01 +053021 public:
22 static ButtonFactory& instance()
23 {
24 static ButtonFactory buttonFactoryObj;
25 return buttonFactoryObj;
26 }
27
28 /**
29 * @brief this method creates a key and value pair element
30 * for the given button interface where key is the form factor
31 * name and the value is lambda method to return
32 * the instance of the button interface.
33 * This key value pair is stored in the Map buttonIfaceRegistry.
34 */
35
36 template <typename T>
37 void addToRegistry()
38 {
Rush Chen31ce3752024-11-08 14:57:27 +080039 buttonIfaceRegistry[T::getFormFactorName()] =
Patrick Williams9a529a62022-07-22 19:26:54 -050040 [](sdbusplus::bus_t& bus, EventPtr& event,
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080041 ButtonConfig& buttonCfg) {
Rush Chen31ce3752024-11-08 14:57:27 +080042 return std::make_unique<T>(bus, T::getDbusObjectPath().c_str(),
43 event, buttonCfg);
Patrick Williamsd36b6b12024-08-16 15:20:34 -040044 };
Naveen Mosesa1af3292021-12-15 11:47:01 +053045 }
Rush Chen31ce3752024-11-08 14:57:27 +080046
47 template <typename T>
48 void addToRegistry(size_t index)
49 {
50 auto indexStr = std::to_string(index);
51 buttonIfaceRegistry[T::getFormFactorName() + indexStr] =
52 [=](sdbusplus::bus_t& bus, EventPtr& event,
53 ButtonConfig& buttonCfg) {
54 return std::make_unique<T>(
55 bus, (T::getDbusObjectPath() + indexStr).c_str(), event,
56 buttonCfg);
57 };
58 }
59
Naveen Mosesa1af3292021-12-15 11:47:01 +053060 /**
61 * @brief this method returns the button interface object
62 * corresponding to the button formfactor name provided
63 */
Patrick Williamsefe50922025-02-01 08:22:17 -050064 std::unique_ptr<ButtonIface> createInstance(
65 const std::string& name, sdbusplus::bus_t& bus, EventPtr& event,
66 ButtonConfig& buttonCfg)
Naveen Mosesa1af3292021-12-15 11:47:01 +053067 {
Naveen Mosesa1af3292021-12-15 11:47:01 +053068 // find matching name in the registry and call factory method.
Naveen Moseseea8a4a2022-02-18 01:14:15 +053069 auto objectIter = buttonIfaceRegistry.find(name);
70 if (objectIter != buttonIfaceRegistry.end())
71 {
72 return objectIter->second(bus, event, buttonCfg);
73 }
74 else
75 {
76 return nullptr;
77 }
Naveen Mosesa1af3292021-12-15 11:47:01 +053078 }
79
80 private:
81 // This map is the registry for keeping supported button interface types.
82 std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry;
83};
84
85template <class T>
86class ButtonIFRegister
87{
88 public:
89 ButtonIFRegister()
90 {
91 // register the class factory function
92 ButtonFactory::instance().addToRegistry<T>();
93 }
Rush Chen31ce3752024-11-08 14:57:27 +080094
95 explicit ButtonIFRegister(size_t count)
96 {
Matt Spinlerea47dd42025-08-20 13:07:20 -050097 // The JSON power button definitions only have an instance in
98 // their name if there is more than 1 chassis.
99 if (instances.size() > 1)
Rush Chen31ce3752024-11-08 14:57:27 +0800100 {
Matt Spinlerea47dd42025-08-20 13:07:20 -0500101 // register the class factory function
102 // The index, 'countIter', starts at 1 and increments,
103 // representing slot_1 through slot_N.
104 for (size_t countIter = 1; countIter <= count; countIter++)
105 {
106 ButtonFactory::instance().addToRegistry<T>(countIter);
107 }
108 }
109 else
110 {
111 ButtonFactory::instance().addToRegistry<T>();
Rush Chen31ce3752024-11-08 14:57:27 +0800112 }
113 }
Patrick Williams0d038f52023-05-10 07:50:40 -0500114};