diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py index d4b42b8c..12a1e8aa 100644 --- a/.ycm_extra_conf.py +++ b/.ycm_extra_conf.py @@ -32,7 +32,6 @@ flags = [ '-std=c++14', '-Wall', '-Wextra', -'-Wpedantic', ] compilation_database_folder = '' diff --git a/include/bar.hpp b/include/bar.hpp index 3de4c9f9..01903c58 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -11,6 +11,8 @@ DefineBaseException(ConfigurationError); +class Registry; + struct CompiledWithoutModuleSupport : public ConfigurationError { explicit CompiledWithoutModuleSupport(std::string module_name) @@ -20,7 +22,7 @@ struct CompiledWithoutModuleSupport : public ConfigurationError struct Font { std::string id; - int offset; + int offset = 0; Font(std::string id, int offset) : id(id), offset(offset){} @@ -46,8 +48,8 @@ struct Options std::string foreground = "#000000"; std::string linecolor = "#000000"; - int width; - int height; + int width = 0; + int height = 0; int offset_x = 0; int offset_y = 0; @@ -88,11 +90,12 @@ class Bar Bar(); std::unique_ptr opts; + std::shared_ptr registry; + + void load(std::shared_ptr registry); std::string get_output(); std::string get_exec_line(); - - void load(); }; std::shared_ptr &get_bar(); diff --git a/include/eventloop.hpp b/include/eventloop.hpp index 1d78d8bc..372d7605 100644 --- a/include/eventloop.hpp +++ b/include/eventloop.hpp @@ -20,7 +20,7 @@ class EventLoop std::shared_ptr registry; std::shared_ptr logger; - concurrency::Atomic state; + concurrency::Atomic state { 0 }; std::thread t_write; std::thread t_read; @@ -50,6 +50,4 @@ class EventLoop void wait(); void cleanup(int timeout_ms = 5000); - - void add_stdin_subscriber(std::string module_name); }; diff --git a/include/interfaces/mpd.hpp b/include/interfaces/mpd.hpp index 20bd2909..2df36c59 100644 --- a/include/interfaces/mpd.hpp +++ b/include/interfaces/mpd.hpp @@ -119,17 +119,15 @@ namespace mpd std::unique_ptr connection; std::string host; std::string password; - int port; + int port = 6600; int timeout = 15; bool mpd_command_list_active = false; bool mpd_idle = false; - int mpd_fd; + int mpd_fd = -1; - void check_connection(); void check_prerequisites(); void check_prerequisites_commands_list(); - void check_errors(); public: Connection(std::string host, int port, std::string password) @@ -167,7 +165,9 @@ namespace mpd struct MpdStatus { - bool random, repeat, single; + bool random = false, + repeat = false, + single = false; std::string artist; std::string album; diff --git a/include/modules/backlight.hpp b/include/modules/backlight.hpp index a179e8c6..55b0ed0f 100644 --- a/include/modules/backlight.hpp +++ b/include/modules/backlight.hpp @@ -29,8 +29,7 @@ namespace modules bool on_event(InotifyEvent *event); bool build(Builder *builder, std::string tag); - void idle() const - { + void idle() const { std::this_thread::sleep_for(25ms); } }; diff --git a/include/modules/base.hpp b/include/modules/base.hpp index 062dab17..efd82300 100644 --- a/include/modules/base.hpp +++ b/include/modules/base.hpp @@ -38,6 +38,8 @@ DefineBaseException(ModuleError); DefineChildException(UndefinedFormat, ModuleError); DefineChildException(UndefinedFormatTag, ModuleError); +class Registry; + class ModuleFormatter { public: @@ -66,7 +68,7 @@ class ModuleFormatter namespace modules { - void broadcast_module_update(std::string module_name); + void broadcast_module_update(std::shared_ptr registry, std::string module_name); std::string get_tag_name(std::string tag); struct ModuleInterface @@ -82,7 +84,11 @@ namespace modules virtual std::string operator()() = 0; + virtual void attach_registry(std::shared_ptr registry) = 0; + virtual bool handle_command(std::string cmd) = 0; + + virtual bool register_for_events() const = 0; }; template @@ -100,6 +106,7 @@ namespace modules std::condition_variable sleep_handler; std::string name_; + std::shared_ptr registry; std::shared_ptr logger; std::unique_ptr builder; std::unique_ptr broadcast_throttler; @@ -162,10 +169,18 @@ namespace modules return this->cache(); } + void attach_registry(std::shared_ptr registry) { + this->registry = registry; + } + bool handle_command(std::string cmd) { return CastModule(ModuleImpl)->handle_command(cmd); } + bool register_for_events() const { + return false; + } + protected: bool enabled() { return this->enabled_flag(); @@ -182,7 +197,7 @@ namespace modules log_trace2(this->logger, "Throttled broadcast for: "+ this->name_); return; } - broadcast_module_update(ConstCastModule(ModuleImpl).name()); + broadcast_module_update(this->registry, ConstCastModule(ModuleImpl).name()); } void sleep(std::chrono::duration sleep_duration) diff --git a/include/modules/bspwm.hpp b/include/modules/bspwm.hpp index b43c5cd9..e97e2003 100644 --- a/include/modules/bspwm.hpp +++ b/include/modules/bspwm.hpp @@ -78,6 +78,10 @@ namespace modules bool has_event(); bool update(); bool build(Builder *builder, std::string tag); + bool handle_command(std::string cmd); + bool register_for_events() const { + return true; + } }; } diff --git a/include/modules/date.hpp b/include/modules/date.hpp index 5b437011..df4b780c 100644 --- a/include/modules/date.hpp +++ b/include/modules/date.hpp @@ -26,5 +26,9 @@ namespace modules std::string get_output(); bool handle_command(std::string cmd); + + bool register_for_events() const { + return true; + } }; } diff --git a/include/modules/i3.hpp b/include/modules/i3.hpp index 8429f6f7..58aa4a7c 100644 --- a/include/modules/i3.hpp +++ b/include/modules/i3.hpp @@ -73,5 +73,8 @@ namespace modules bool build(Builder *builder, std::string tag); bool handle_command(std::string cmd); + bool register_for_events() const { + return true; + } }; } diff --git a/include/modules/menu.hpp b/include/modules/menu.hpp index 2313fa01..0628c8c0 100644 --- a/include/modules/menu.hpp +++ b/include/modules/menu.hpp @@ -40,5 +40,9 @@ namespace modules bool build(Builder *builder, std::string tag); bool handle_command(std::string cmd); + + bool register_for_events() const { + return true; + } }; } diff --git a/include/modules/mpd.hpp b/include/modules/mpd.hpp index 2107bdb9..74253bcc 100644 --- a/include/modules/mpd.hpp +++ b/include/modules/mpd.hpp @@ -80,5 +80,9 @@ namespace modules bool build(Builder *builder, std::string tag); bool handle_command(std::string cmd); + + bool register_for_events() const { + return true; + } }; } diff --git a/include/modules/volume.hpp b/include/modules/volume.hpp index f4906007..f829d4b3 100644 --- a/include/modules/volume.hpp +++ b/include/modules/volume.hpp @@ -50,9 +50,12 @@ namespace modules bool update(); std::string get_format(); + std::string get_output(); bool build(Builder *builder, std::string tag); - std::string get_output(); bool handle_command(std::string cmd); + bool register_for_events() const { + return true; + } }; } diff --git a/include/registry.hpp b/include/registry.hpp index ad72be0f..e59e6fcf 100644 --- a/include/registry.hpp +++ b/include/registry.hpp @@ -37,12 +37,10 @@ class Registry bool ready(); void insert(std::unique_ptr &&module); - void load(); + void load(std::function add_stdin_subscriber); void unload(); bool wait(); void notify(std::string module_name); std::string get(std::string module_name); std::unique_ptr& find(std::string module_name); }; - -std::shared_ptr &get_registry(); diff --git a/include/version.hpp b/include/version.hpp index c46cffe1..84ca4333 100644 --- a/include/version.hpp +++ b/include/version.hpp @@ -1,3 +1,3 @@ #pragma once -#define GIT_TAG "1.4.1" +#define GIT_TAG "1.4.1-3-g6329b56-dev" diff --git a/src/bar.cpp b/src/bar.cpp index fc04e7a3..e8943e93 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -130,8 +130,10 @@ Bar::Bar() : config_path(config::get_bar_path()), opts(std::make_unique /** * Loads all modules configured for the current bar */ -void Bar::load() +void Bar::load(std::shared_ptr registry) { + this->registry = registry; + auto add_modules = [&](std::string modlist, std::vector &vec){ std::vector modules; string::split_into(modlist, ' ', modules); @@ -173,8 +175,10 @@ void Bar::load() else if (type == "custom/menu") module = std::make_unique(mod); else throw ConfigurationError("Unknown module: "+ mod); + module->attach_registry(this->registry); + vec.emplace_back(module->name()); - get_registry()->insert(std::move(module)); + this->registry->insert(std::move(module)); } }; @@ -201,7 +205,7 @@ std::string Bar::get_output() builder->append_module_output(align, pad_left, false, false); for (auto &mod_name : mods) { - auto mod_output = get_registry()->get(mod_name); + auto mod_output = this->registry->get(mod_name); builder->append_module_output(align, mod_output, !(align == Builder::ALIGN_LEFT && mod_name == mods.front()), !(align == Builder::ALIGN_RIGHT && mod_name == mods.back())); diff --git a/src/eventloop.cpp b/src/eventloop.cpp index e259db39..6a31bf30 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -12,7 +12,7 @@ EventLoop::EventLoop(std::string input_pipe) : bar(get_bar()), - registry(get_registry()), + registry(std::make_shared()), logger(get_logger()), state(STATE_STOPPED), pipe_filename(input_pipe) @@ -39,8 +39,12 @@ void EventLoop::start() this->logger->debug("Starting event loop..."); - this->bar->load(); - this->registry->load(); + this->bar->load(registry); + + this->registry->load([&](std::string module_name){ + this->logger->debug("Adding stdin subscriber: "+ module_name); + this->stdin_subs.emplace_back(module_name); + }); this->state = STATE_STARTED; @@ -98,12 +102,6 @@ void EventLoop::wait() this->logger->info("Termination signal received... Shutting down"); } -void EventLoop::add_stdin_subscriber(std::string module_name) -{ - // this->stdin_subs.insert(std::make_pair("TAG", module_name)); - this->stdin_subs.emplace_back(module_name); -} - void EventLoop::loop_write() { std::deque ticks; diff --git a/src/interfaces/alsa.cpp b/src/interfaces/alsa.cpp index d0054a81..da5ea899 100644 --- a/src/interfaces/alsa.cpp +++ b/src/interfaces/alsa.cpp @@ -12,7 +12,7 @@ namespace alsa ControlInterface::ControlInterface(int numid) { - int err; + int err = 0; snd_ctl_elem_info_alloca(&this->info); snd_ctl_elem_value_alloca(&this->value); @@ -54,7 +54,7 @@ namespace alsa { std::lock_guard lck(this->lock); - int err; + int err = 0; if ((err = snd_ctl_wait(this->ctl, timeout)) < 0) throw ControlInterfaceError(err, "Failed to wait for events: "+ StrSndErr(err)); @@ -76,7 +76,7 @@ namespace alsa { std::lock_guard lck(this->lock); - int err; + int err = 0; if ((err = snd_hctl_elem_read(this->elem, this->value)) < 0) throw ControlInterfaceError(err, "Could not read control value: "+ StrSndErr(err)); diff --git a/src/interfaces/mpd.cpp b/src/interfaces/mpd.cpp index 0b873156..e145ca4c 100644 --- a/src/interfaces/mpd.cpp +++ b/src/interfaces/mpd.cpp @@ -8,6 +8,29 @@ #include "interfaces/mpd.hpp" #include "utils/math.hpp" +inline void check_connection(mpd_connection *conn) +{ + if (conn == nullptr) + throw mpd::ClientError("Not connected to MPD server", MPD_ERROR_STATE, false); +} + +inline void check_errors(mpd_connection *conn) +{ + mpd_error code = mpd_connection_get_error(conn); + + if (code == MPD_ERROR_SUCCESS) + return; + + std::string msg = mpd_connection_get_error_message(conn); + + if (code == MPD_ERROR_SERVER) + throw mpd::ServerError(msg, + mpd_connection_get_server_error(conn), + mpd_connection_clear_error(conn)); + else + throw mpd::ClientError(msg, code, mpd_connection_clear_error(conn)); +} + namespace mpd { // Base @@ -18,17 +41,17 @@ namespace mpd try { this->connection.reset(mpd_connection_new(this->host.c_str(), this->port, this->timeout * 1000)); - this->check_errors(); + check_errors(this->connection.get()); if (!this->password.empty()) { this->noidle(); assert(!this->mpd_command_list_active); mpd_run_password(this->connection.get(), this->password.c_str()); - this->check_errors(); + check_errors(this->connection.get()); } this->mpd_fd = mpd_connection_get_fd(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } catch(ClientError &e) { this->disconnect(); throw e; @@ -67,64 +90,40 @@ namespace mpd void Connection::idle() { - this->check_connection(); + check_connection(this->connection.get()); if (!this->mpd_idle) { mpd_send_idle(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } this->mpd_idle = true; } int Connection::noidle() { - this->check_connection(); + check_connection(this->connection.get()); int flags = 0; if (this->mpd_idle && mpd_send_noidle(this->connection.get())) { this->mpd_idle = false; flags = mpd_recv_idle(this->connection.get(), true); mpd_response_finish(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } return flags; } - void Connection::check_connection() + inline void Connection::check_prerequisites() { - if (!this->connection) - throw ClientError("Not connected to MPD server", MPD_ERROR_STATE, false); - } - - void Connection::check_prerequisites() - { - this->check_connection(); + check_connection(this->connection.get()); this->noidle(); } - void Connection::check_prerequisites_commands_list() + inline void Connection::check_prerequisites_commands_list() { this->noidle(); assert(!this->mpd_command_list_active); this->check_prerequisites(); } - void Connection::check_errors() - { - auto connection = this->connection.get(); - mpd_error code = mpd_connection_get_error(connection); - - if (code == MPD_ERROR_SUCCESS) - return; - - std::string msg = mpd_connection_get_error_message(connection); - - if (code == MPD_ERROR_SERVER) - throw ServerError(msg, - mpd_connection_get_server_error(connection), - mpd_connection_clear_error(connection)); - else - throw ClientError(msg, code, mpd_connection_clear_error(connection)); - } - // Commands @@ -133,7 +132,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_play(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -144,7 +143,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_pause(this->connection.get(), state); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -155,7 +154,7 @@ namespace mpd // try { // this->check_prerequisites_commands_list(); // mpd_run_toggle_pause(this->connection.get()); - // this->check_errors(); + // check_errors(this->connection.get()); // } catch (Exception &e) { // log_error(e.what()); // } @@ -166,7 +165,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_stop(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -177,7 +176,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_previous(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -188,7 +187,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_next(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -207,7 +206,7 @@ namespace mpd int pos = float(status->total_time) * percentage / 100.0f + 0.5f; this->check_prerequisites_commands_list(); mpd_run_seek_id(this->connection.get(), status->song_id, pos); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -218,7 +217,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_repeat(this->connection.get(), mode); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -229,7 +228,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_random(this->connection.get(), mode); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -240,7 +239,7 @@ namespace mpd try { this->check_prerequisites_commands_list(); mpd_run_single(this->connection.get(), mode); - this->check_errors(); + check_errors(this->connection.get()); } catch (Exception &e) { log_error(e.what()); } @@ -253,7 +252,7 @@ namespace mpd { this->check_prerequisites(); mpd_status *mpd_status = mpd_run_status(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); auto status = std::make_unique(mpd_status); if (update) status->update(-1, this); @@ -362,7 +361,7 @@ namespace mpd mpd_send_current_song(this->connection.get()); mpd_song *song = mpd_recv_song(this->connection.get()); mpd_response_finish(this->connection.get()); - this->check_errors(); + check_errors(this->connection.get()); if (song == nullptr) return std::make_unique(); diff --git a/src/lemonbuddy.cpp b/src/lemonbuddy.cpp index 9444c834..688318d3 100644 --- a/src/lemonbuddy.cpp +++ b/src/lemonbuddy.cpp @@ -25,8 +25,6 @@ * TODO: Simplify overall flow */ -std::unique_ptr eventloop; - std::mutex pid_mtx; std::vector pids; @@ -38,9 +36,6 @@ void unregister_pid(pid_t pid) { std::lock_guard lck(pid_mtx); pids.erase(std::remove(pids.begin(), pids.end(), pid), pids.end()); } -void register_command_handler(std::string module_name) { - eventloop->add_stdin_subscriber(module_name); -} /** * Main entry point woop! @@ -48,7 +43,9 @@ void register_command_handler(std::string module_name) { int main(int argc, char **argv) { int retval = EXIT_SUCCESS; - auto logger = get_logger(); + + std::unique_ptr eventloop; + std::shared_ptr logger = get_logger(); try { auto usage = "Usage: "+ std::string(argv[0]) + " bar_name [OPTION...]"; @@ -80,9 +77,11 @@ int main(int argc, char **argv) << (ENABLE_MPD ? "+" : "-") << "mpd " << (ENABLE_NETWORK ? "+" : "-") << "network " << "\n\n"; + if (ENABLE_ALSA) std::cout << "ALSA_SOUNDCARD " << ALSA_SOUNDCARD << std::endl; + std::cout << "CONNECTION_TEST_IP " << CONNECTION_TEST_IP << "\n" << "PATH_BACKLIGHT_VAL " << PATH_BACKLIGHT_VAL << "\n" @@ -92,12 +91,11 @@ int main(int argc, char **argv) << "PATH_CPU_INFO " << PATH_CPU_INFO << "\n" << "PATH_MEMORY_INFO " << PATH_MEMORY_INFO << "\n"; } - return EXIT_SUCCESS; } if (cli::has_option("help") || argv[1][0] == '-') - cli::usage(usage); + cli::usage(usage, false); /** * Set logging verbosity diff --git a/src/modules/base.cpp b/src/modules/base.cpp index a045fa3f..4e66e299 100644 --- a/src/modules/base.cpp +++ b/src/modules/base.cpp @@ -85,10 +85,10 @@ bool ModuleFormatter::has(std::string tag) namespace modules { - void broadcast_module_update(std::string module_name) + void broadcast_module_update(std::shared_ptr registry, std::string module_name) { log_trace("Broadcasting module update for => "+ module_name); - get_registry()->notify(module_name); + registry->notify(module_name); } std::string get_tag_name(std::string tag) { diff --git a/src/modules/bspwm.cpp b/src/modules/bspwm.cpp index ecfce3a0..8012325a 100644 --- a/src/modules/bspwm.cpp +++ b/src/modules/bspwm.cpp @@ -80,8 +80,6 @@ BspwmModule::BspwmModule(std::string name_, std::string monitor) auto vec = string::split(workspace, ';'); if (vec.size() == 2) this->icons->add(vec[0], std::make_unique(vec[1])); } - - register_command_handler(name()); } BspwmModule::~BspwmModule() diff --git a/src/modules/date.cpp b/src/modules/date.cpp index 4d4d99ff..87c6934d 100644 --- a/src/modules/date.cpp +++ b/src/modules/date.cpp @@ -16,9 +16,6 @@ DateModule::DateModule(std::string name_) this->date = config::get(name(), "date"); this->date_detailed = config::get(name(), "date_detailed", ""); - - if (!this->date_detailed.empty()) - register_command_handler(name()); } bool DateModule::update() diff --git a/src/modules/i3.cpp b/src/modules/i3.cpp index 5db07fc2..58e255f9 100644 --- a/src/modules/i3.cpp +++ b/src/modules/i3.cpp @@ -55,8 +55,6 @@ i3Module::i3Module(std::string name_, std::string monitor) auto vec = string::split(workspace, ';'); if (vec.size() == 2) this->icons->add(vec[0], std::make_unique(vec[1])); } - - register_command_handler(name()); } i3Module::~i3Module() diff --git a/src/modules/menu.cpp b/src/modules/menu.cpp index 00433440..304d9b4b 100644 --- a/src/modules/menu.cpp +++ b/src/modules/menu.cpp @@ -48,8 +48,6 @@ MenuModule::MenuModule(std::string name_) : StaticModule(name_) level_n++; } } - - register_command_handler(name()); } std::string MenuModule::get_output() diff --git a/src/modules/mpd.cpp b/src/modules/mpd.cpp index f1af9cfe..0e1c3fbe 100644 --- a/src/modules/mpd.cpp +++ b/src/modules/mpd.cpp @@ -67,10 +67,6 @@ MpdModule::MpdModule(std::string name_) this->bar_progress = drawtypes::get_config_bar(name(), get_tag_name(TAG_BAR_PROGRESS)); } // }}} - - // Sign up for stdin events {{{ - register_command_handler(name()); - // }}} } MpdModule::~MpdModule() diff --git a/src/modules/volume.cpp b/src/modules/volume.cpp index f265df1a..f598e4d3 100644 --- a/src/modules/volume.cpp +++ b/src/modules/volume.cpp @@ -82,10 +82,6 @@ VolumeModule::VolumeModule(std::string name_) : EventModule(name_) this->label_muted_tokenized = this->label_muted->clone(); } // }}} - - // Sign up for stdin events {{{ - register_command_handler(name()); - // }}} } VolumeModule::~VolumeModule() diff --git a/src/registry.cpp b/src/registry.cpp index c9c8a1ab..8e9e3f43 100644 --- a/src/registry.cpp +++ b/src/registry.cpp @@ -2,14 +2,6 @@ #include "services/logger.hpp" #include "utils/string.hpp" -std::shared_ptr registry; -std::shared_ptr &get_registry() -{ - if (registry == nullptr) - registry = std::make_shared(); - return registry; -} - Registry::Registry() : logger(get_logger()) { this->logger->debug("Entering STAGE 1"); @@ -33,7 +25,7 @@ void Registry::insert(std::unique_ptr &&module) this->modules.emplace_back(std::make_unique(std::move(module))); } -void Registry::load() +void Registry::load(std::function add_stdin_subscriber) { if (this->stage() != STAGE_1) return; @@ -46,6 +38,8 @@ void Registry::load() for (auto &&entry : this->modules) { std::lock_guard lck(this->wait_lock); + if (entry->module->register_for_events()) + add_stdin_subscriber(entry->module->name()); entry->module->start(); } }