Templatify module factory

Saves us a lot of code duplication by generating module type-indexed map
and factory functions from the module class names.
This commit is contained in:
patrick96 2022-10-16 21:09:32 +02:00 committed by Patrick Ziegler
parent 56779a5902
commit 3561fd3ad1
5 changed files with 156 additions and 108 deletions

View File

@ -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"

View File

@ -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<module_interface>;
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

View File

@ -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

View File

@ -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<modules::module_interface>(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);

View File

@ -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<string, factory_fun>;
/**
* Creates a factory function for constructing a module.
*
* @tparam M name of the module class
*/
template <typename M>
static constexpr factory_fun get_factory() {
return [](const bar_settings& bar, string&& module_name) -> module_t {
return make_shared<M>(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 <typename M>
static factory_map::value_type map_entry() {
return std::make_pair(std::string(M::TYPE), get_factory<M>());
}
/**
* Factory function for each module type.
*/
static const factory_map factories = {
map_entry<counter_module>(),
map_entry<backlight_module>(),
map_entry<battery_module>(),
map_entry<bspwm_module>(),
map_entry<cpu_module>(),
map_entry<date_module>(),
map_entry<github_module>(),
map_entry<fs_module>(),
map_entry<memory_module>(),
map_entry<i3_module>(),
map_entry<mpd_module>(),
map_entry<alsa_module>(),
map_entry<pulseaudio_module>(),
map_entry<network_module>(),
#if DEBUG
map_entry<systray_module>(),
#endif
map_entry<temperature_module>(),
map_entry<xbacklight_module>(),
map_entry<xkeyboard_module>(),
map_entry<xwindow_module>(),
map_entry<xworkspaces_module>(),
map_entry<tray_module>(),
map_entry<text_module>(),
map_entry<script_module>(),
map_entry<menu_module>(),
map_entry<ipc_module>(),
};
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