blob: 2b7c9b91fd1d8118fc32c6a157d94b6da7bc08f3 [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"
Naveen Mosesa1af3292021-12-15 11:47:01 +05305
6#include <phosphor-logging/elog-errors.hpp>
George Liu5b98f4d2022-06-20 13:31:14 +08007
Naveen Mosesa1af3292021-12-15 11:47:01 +05308#include <unordered_map>
9
10using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080011 sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg)>;
Naveen Mosesa1af3292021-12-15 11:47:01 +053012
13/**
14 * @brief This is abstract factory for the creating phosphor buttons objects
15 * based on the button / formfactor type given.
16 */
17
18class ButtonFactory
19{
Naveen Mosesa1af3292021-12-15 11:47:01 +053020 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 {
Rush Chen31ce3752024-11-08 14:57:27 +080038 buttonIfaceRegistry[T::getFormFactorName()] =
Patrick Williams9a529a62022-07-22 19:26:54 -050039 [](sdbusplus::bus_t& bus, EventPtr& event,
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080040 ButtonConfig& buttonCfg) {
Rush Chen31ce3752024-11-08 14:57:27 +080041 return std::make_unique<T>(bus, T::getDbusObjectPath().c_str(),
42 event, buttonCfg);
Patrick Williamsd36b6b12024-08-16 15:20:34 -040043 };
Naveen Mosesa1af3292021-12-15 11:47:01 +053044 }
Rush Chen31ce3752024-11-08 14:57:27 +080045
46 template <typename T>
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
Naveen Mosesa1af3292021-12-15 11:47:01 +053059 /**
60 * @brief this method returns the button interface object
61 * corresponding to the button formfactor name provided
62 */
Patrick Williamsd36b6b12024-08-16 15:20:34 -040063 std::unique_ptr<ButtonIface>
64 createInstance(const std::string& name, sdbusplus::bus_t& bus,
65 EventPtr& event, ButtonConfig& buttonCfg)
Naveen Mosesa1af3292021-12-15 11:47:01 +053066 {
Naveen Mosesa1af3292021-12-15 11:47:01 +053067 // find matching name in the registry and call factory method.
Naveen Moseseea8a4a2022-02-18 01:14:15 +053068 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 }
Naveen Mosesa1af3292021-12-15 11:47:01 +053077 }
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
84template <class T>
85class ButtonIFRegister
86{
87 public:
88 ButtonIFRegister()
89 {
90 // register the class factory function
91 ButtonFactory::instance().addToRegistry<T>();
92 }
Rush Chen31ce3752024-11-08 14:57:27 +080093
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 }
Patrick Williams0d038f52023-05-10 07:50:40 -0500104};