Add abstract factory to create button iface objects

A abstract factory class is implemented  to return
the instance of button interface class based on the
button iface formfactor name provided as
parameter to the abstract factory createInstance
 method.

Signed-off-by: Naveen Moses <naveen.mosess@hcl.com>
Change-Id: Ia791a2b6f52d09dd87da0e50a709fc72ac9d1bd7
diff --git a/inc/button_factory.hpp b/inc/button_factory.hpp
new file mode 100644
index 0000000..81c8e47
--- /dev/null
+++ b/inc/button_factory.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "button_interface.hpp"
+#include "gpio.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <unordered_map>
+
+using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
+    sdbusplus::bus::bus& bus, EventPtr& event, buttonConfig& buttonCfg)>;
+
+/**
+ * @brief This is abstract factory for the creating phosphor buttons objects
+ * based on the button  / formfactor type given.
+ */
+
+class ButtonFactory
+{
+
+  public:
+    static ButtonFactory& instance()
+    {
+        static ButtonFactory buttonFactoryObj;
+        return buttonFactoryObj;
+    }
+
+    /**
+     * @brief this method creates a key and value pair element
+     * for the given button interface where key is the form factor
+     * name and the value is lambda method to return
+     * the instance of the button interface.
+     * This key value pair is stored in the Map buttonIfaceRegistry.
+     */
+
+    template <typename T>
+    void addToRegistry()
+    {
+
+        buttonIfaceRegistry[std::string(T::getFormFactorName())] =
+            [](sdbusplus::bus::bus& bus, EventPtr& event,
+               buttonConfig& buttonCfg) {
+                return std::make_unique<T>(bus, T::getDbusObjectPath(), event,
+                                           buttonCfg);
+            };
+    }
+    /**
+     * @brief this method returns the button interface object
+     *    corresponding to the button formfactor name provided
+     */
+    std::unique_ptr<ButtonIface> createInstance(std::string name,
+                                                sdbusplus::bus::bus& bus,
+                                                EventPtr& event,
+                                                buttonConfig& buttonCfg)
+    {
+
+        // find matching name in the registry and call factory method.
+
+        return buttonIfaceRegistry.at(name)(bus, event, buttonCfg);
+    }
+
+  private:
+    // This map is the registry for keeping supported button interface types.
+    std::unordered_map<std::string, buttonIfCreatorMethod> buttonIfaceRegistry;
+};
+
+template <class T>
+class ButtonIFRegister
+{
+  public:
+    ButtonIFRegister()
+    {
+        // register the class factory function
+        ButtonFactory::instance().addToRegistry<T>();
+    }
+};
\ No newline at end of file