From 3561fd3ad14208a4ee0c416a0bde246942ecf65d Mon Sep 17 00:00:00 2001
From: patrick96
Date: Sun, 16 Oct 2022 21:09:32 +0200
Subject: [PATCH] Templatify module factory
Saves us a lot of code duplication by generating module type-indexed map
and factory functions from the module class names.
---
include/modules/meta/all.hpp | 49 +++++++++++++
include/modules/meta/factory.hpp | 119 ++++---------------------------
src/CMakeLists.txt | 1 +
src/components/controller.cpp | 6 +-
src/modules/meta/factory.cpp | 89 +++++++++++++++++++++++
5 files changed, 156 insertions(+), 108 deletions(-)
create mode 100644 include/modules/meta/all.hpp
create mode 100644 src/modules/meta/factory.cpp
diff --git a/include/modules/meta/all.hpp b/include/modules/meta/all.hpp
new file mode 100644
index 00000000..c604bd4e
--- /dev/null
+++ b/include/modules/meta/all.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+/**
+ * Header file to include the headers for all modules.
+ */
+
+#include "modules/backlight.hpp"
+#include "modules/battery.hpp"
+#include "modules/bspwm.hpp"
+#include "modules/counter.hpp"
+#include "modules/cpu.hpp"
+#include "modules/date.hpp"
+#include "modules/fs.hpp"
+#include "modules/ipc.hpp"
+#include "modules/memory.hpp"
+#include "modules/menu.hpp"
+#include "modules/meta/base.hpp"
+#include "modules/script.hpp"
+#if DEBUG
+#include "modules/systray.hpp"
+#endif
+#include "modules/temperature.hpp"
+#include "modules/text.hpp"
+#include "modules/tray.hpp"
+#include "modules/xbacklight.hpp"
+#include "modules/xwindow.hpp"
+#include "modules/xworkspaces.hpp"
+#if ENABLE_I3
+#include "modules/i3.hpp"
+#endif
+#if ENABLE_MPD
+#include "modules/mpd.hpp"
+#endif
+#if ENABLE_NETWORK
+#include "modules/network.hpp"
+#endif
+#if ENABLE_ALSA
+#include "modules/alsa.hpp"
+#endif
+#if ENABLE_PULSEAUDIO
+#include "modules/pulseaudio.hpp"
+#endif
+#if ENABLE_CURL
+#include "modules/github.hpp"
+#endif
+#if ENABLE_XKEYBOARD
+#include "modules/xkeyboard.hpp"
+#endif
+#include "modules/unsupported.hpp"
diff --git a/include/modules/meta/factory.hpp b/include/modules/meta/factory.hpp
index 693320e9..0c3c96ba 100644
--- a/include/modules/meta/factory.hpp
+++ b/include/modules/meta/factory.hpp
@@ -1,115 +1,24 @@
#pragma once
#include "common.hpp"
-#include "modules/backlight.hpp"
-#include "modules/battery.hpp"
-#include "modules/bspwm.hpp"
-#include "modules/counter.hpp"
-#include "modules/cpu.hpp"
-#include "modules/date.hpp"
-#include "modules/fs.hpp"
-#include "modules/ipc.hpp"
-#include "modules/memory.hpp"
-#include "modules/menu.hpp"
+#include "components/logger.hpp"
+#include "components/types.hpp"
#include "modules/meta/base.hpp"
-#include "modules/script.hpp"
-#if DEBUG
-#include "modules/systray.hpp"
-#endif
-#include "modules/temperature.hpp"
-#include "modules/text.hpp"
-#include "modules/tray.hpp"
-#include "modules/xbacklight.hpp"
-#include "modules/xwindow.hpp"
-#include "modules/xworkspaces.hpp"
-#if ENABLE_I3
-#include "modules/i3.hpp"
-#endif
-#if ENABLE_MPD
-#include "modules/mpd.hpp"
-#endif
-#if ENABLE_NETWORK
-#include "modules/network.hpp"
-#endif
-#if ENABLE_ALSA
-#include "modules/alsa.hpp"
-#endif
-#if ENABLE_PULSEAUDIO
-#include "modules/pulseaudio.hpp"
-#endif
-#if ENABLE_CURL
-#include "modules/github.hpp"
-#endif
-#if ENABLE_XKEYBOARD
-#include "modules/xkeyboard.hpp"
-#endif
-#include "modules/unsupported.hpp"
POLYBAR_NS
-using namespace modules;
+namespace modules {
+ using module_t = shared_ptr;
-namespace {
- module_interface* make_module(string&& name, const bar_settings& bar, string module_name, const logger& m_log) {
- if (name == counter_module::TYPE) {
- return new counter_module(bar, move(module_name));
- } else if (name == backlight_module::TYPE) {
- return new backlight_module(bar, move(module_name));
- } else if (name == battery_module::TYPE) {
- return new battery_module(bar, move(module_name));
- } else if (name == bspwm_module::TYPE) {
- return new bspwm_module(bar, move(module_name));
- } else if (name == cpu_module::TYPE) {
- return new cpu_module(bar, move(module_name));
- } else if (name == date_module::TYPE) {
- return new date_module(bar, move(module_name));
- } else if (name == github_module::TYPE) {
- return new github_module(bar, move(module_name));
- } else if (name == fs_module::TYPE) {
- return new fs_module(bar, move(module_name));
- } else if (name == memory_module::TYPE) {
- return new memory_module(bar, move(module_name));
- } else if (name == i3_module::TYPE) {
- return new i3_module(bar, move(module_name));
- } else if (name == mpd_module::TYPE) {
- return new mpd_module(bar, move(module_name));
- } else if (name == "internal/volume") {
- m_log.warn("internal/volume is deprecated, use %s instead", string(alsa_module::TYPE));
- return new alsa_module(bar, move(module_name));
- } else if (name == alsa_module::TYPE) {
- return new alsa_module(bar, move(module_name));
- } else if (name == pulseaudio_module::TYPE) {
- return new pulseaudio_module(bar, move(module_name));
- } else if (name == network_module::TYPE) {
- return new network_module(bar, move(module_name));
-#if DEBUG
- } else if (name == systray_module::TYPE) {
- return new systray_module(bar, move(module_name));
-#endif
- } else if (name == temperature_module::TYPE) {
- return new temperature_module(bar, move(module_name));
- } else if (name == xbacklight_module::TYPE) {
- return new xbacklight_module(bar, move(module_name));
- } else if (name == xkeyboard_module::TYPE) {
- return new xkeyboard_module(bar, move(module_name));
- } else if (name == xwindow_module::TYPE) {
- return new xwindow_module(bar, move(module_name));
- } else if (name == xworkspaces_module::TYPE) {
- return new xworkspaces_module(bar, move(module_name));
- } else if (name == tray_module::TYPE) {
- return new tray_module(bar, move(module_name));
- } else if (name == text_module::TYPE) {
- return new text_module(bar, move(module_name));
- } else if (name == script_module::TYPE) {
- return new script_module(bar, move(module_name));
- } else if (name == menu_module::TYPE) {
- return new menu_module(bar, move(module_name));
- } else if (name == ipc_module::TYPE) {
- return new ipc_module(bar, move(module_name));
- } else {
- throw application_error("Unknown module: " + name);
- }
- }
-} // namespace
+ /**
+ * Creates a new module instance.
+ *
+ * @param type The type of the module (as given by each module's TYPE field)
+ * @param bar An instance of the @ref bar_settings
+ * @param module_name The user-specified module name
+ * @param log A @ref logger instance
+ */
+ module_t make_module(string&& type, const bar_settings& bar, string module_name, const logger& log);
+} // namespace modules
POLYBAR_NS_END
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0f36aeb8..02d37bac 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -94,6 +94,7 @@ set(POLY_SOURCES
${src_dir}/modules/memory.cpp
${src_dir}/modules/menu.cpp
${src_dir}/modules/meta/base.cpp
+ ${src_dir}/modules/meta/factory.cpp
${src_dir}/modules/script.cpp
${src_dir}/modules/systray.cpp
${src_dir}/modules/temperature.cpp
diff --git a/src/components/controller.cpp b/src/components/controller.cpp
index 31721191..7f81a902 100644
--- a/src/components/controller.cpp
+++ b/src/components/controller.cpp
@@ -11,6 +11,7 @@
#include "components/types.hpp"
#include "events/signal.hpp"
#include "events/signal_emitter.hpp"
+#include "modules/meta/all.hpp"
#include "modules/meta/base.hpp"
#include "modules/meta/event_handler.hpp"
#include "modules/meta/factory.hpp"
@@ -25,6 +26,7 @@
POLYBAR_NS
using namespace eventloop;
+using namespace modules;
/**
* Build controller instance
@@ -624,9 +626,7 @@ size_t controller::setup_modules(alignment align) {
}
m_log.notice("Loading module '%s' of type '%s'", module_name, type);
- auto ptr = make_module(move(type), m_bar->settings(), module_name, m_log);
- module_t module = shared_ptr(ptr);
- ptr = nullptr;
+ module_t module = modules::make_module(move(type), m_bar->settings(), module_name, m_log);
m_modules.push_back(module);
m_blocks[align].push_back(module);
diff --git a/src/modules/meta/factory.cpp b/src/modules/meta/factory.cpp
new file mode 100644
index 00000000..40503a55
--- /dev/null
+++ b/src/modules/meta/factory.cpp
@@ -0,0 +1,89 @@
+#include "modules/meta/factory.hpp"
+
+#include "modules/meta/all.hpp"
+
+POLYBAR_NS
+
+namespace modules {
+
+ /**
+ * Function pointer for creating a module.
+ */
+ using factory_fun = module_t (*)(const bar_settings&, string&&);
+ using factory_map = map;
+
+ /**
+ * Creates a factory function for constructing a module.
+ *
+ * @tparam M name of the module class
+ */
+ template
+ static constexpr factory_fun get_factory() {
+ return [](const bar_settings& bar, string&& module_name) -> module_t {
+ return make_shared(bar, move(module_name));
+ };
+ }
+
+ /**
+ * Creates an entry for the factories map.
+ *
+ * Each entry is a pair containing the module type and the factory function.
+ *
+ * @tparam M name of the module class
+ */
+ template
+ static factory_map::value_type map_entry() {
+ return std::make_pair(std::string(M::TYPE), get_factory());
+ }
+
+ /**
+ * Factory function for each module type.
+ */
+ static const factory_map factories = {
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+#if DEBUG
+ map_entry(),
+#endif
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ map_entry(),
+ };
+
+ module_t make_module(string&& type, const bar_settings& bar, string module_name, const logger& log) {
+ string actual_type = type;
+
+ if (type == "internal/volume") {
+ log.warn("internal/volume is deprecated, use %s instead", string(alsa_module::TYPE));
+ actual_type = alsa_module::TYPE;
+ }
+
+ auto it = factories.find(actual_type);
+ if (it != factories.end()) {
+ return it->second(bar, std::move(module_name));
+ } else {
+ throw application_error("Unknown module: " + type);
+ }
+ }
+} // namespace modules
+
+POLYBAR_NS_END