diff --git a/doc/bindings b/doc/bindings index f4b846cd..8ac4ffbb 100644 --- a/doc/bindings +++ b/doc/bindings @@ -22,17 +22,12 @@ ## action2 ## ... ## -## This creates chain of actions. When such chain is +## This creates a chain of actions. When such chain is ## executed, each action in chain is run until the end of -## chain is reached or one of actions failed to execute -## due to its requirements not being met. Note that -## execution of chain of actions ALWAYS succeeds, no -## matter if one of actions from the chain failed (even -## if it was the first one in order and thus nothing -## was really executed). Because of that, if you decide -## to bind both actions and chains to a single key, make -## sure that chain is defined in the end. Otherwise, all -## actions bound to the key after chain will never be run. +## chain is reached or one of its actions fails to execute +## due to its requirements not being met. If multiple actions +## and/or chains are bound to the same key, they will be +## consecutively run until one of them gets fully executed. ## ## 3) When ncmpcpp starts, bindings configuration file is ## parsed and then ncmpcpp provides "missing pieces" diff --git a/src/actions.cpp b/src/actions.cpp index 3601ddac..b9719d13 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -826,7 +826,8 @@ void ExecuteCommand::run() if (cmd) { Statusbar::msg(1, "Executing %s...", cmd_name.c_str()); - cmd->binding().execute(); + bool res = cmd->binding().execute(); + Statusbar::msg("Execution %s.", res ? "successful" : "unsuccessful"); } else Statusbar::msg("No command named \"%s\"", cmd_name.c_str()); diff --git a/src/bindings.cpp b/src/bindings.cpp index 36e2c451..42ac8662 100644 --- a/src/bindings.cpp +++ b/src/bindings.cpp @@ -233,7 +233,7 @@ bool BindingsConfiguration::read(const std::string &file) { if (!actions.empty()) { - m_commands.insert(std::make_pair(cmd_name, Command(actions, cmd_immediate))); + m_commands.insert(std::make_pair(cmd_name, Command(std::move(actions), cmd_immediate))); actions.clear(); return true; } diff --git a/src/bindings.h b/src/bindings.h index 00230037..8c2e6e1f 100644 --- a/src/bindings.h +++ b/src/bindings.h @@ -21,6 +21,8 @@ #ifndef NCMPCPP_BINDINGS_H #define NCMPCPP_BINDINGS_H +#include +#include #include #include #include "actions.h" @@ -74,57 +76,43 @@ struct Binding { typedef std::vector ActionChain; - Binding(Actions::Type at) : m_is_single(true), m_action(&Actions::get(at)) { } - Binding(const ActionChain &actions) { - assert(actions.size() > 0); - if (actions.size() == 1) { - m_is_single = true; - m_action = actions[0]; - } else { - m_is_single = false; - m_chain = new ActionChain(actions); - } + template + Binding(ArgT &&actions) + : m_actions(std::forward(actions)) { + assert(!m_actions.empty()); } + Binding(Actions::Type at) + : Binding(ActionChain({&Actions::get(at)})) { } bool execute() const { - bool result = false; - if (m_is_single) { - assert(m_action); - result = m_action->execute(); - } else { - for (auto it = m_chain->begin(); it != m_chain->end(); ++it) - if (!(*it)->execute()) - break; - result = true; - } - return result; + return std::all_of(m_actions.begin(), m_actions.end(), + boost::bind(&Actions::BaseAction::execute, _1) + ); } bool isSingle() const { - return m_is_single; - } - ActionChain *chain() const { - assert(!m_is_single); - return m_chain; + return m_actions.size() == 1; } + Actions::BaseAction *action() const { - assert(m_is_single); - return m_action; + assert(isSingle()); + return m_actions[0]; } - + + const ActionChain &actions() const { + return m_actions; + } + private: - bool m_is_single; - union { - Actions::BaseAction *m_action; - ActionChain *m_chain; - }; + ActionChain m_actions; }; /// Represents executable command struct Command { - Command(const Binding &binding_, bool immediate_) - : m_binding(binding_), m_immediate(immediate_) { } + template + Command(ArgT &&binding_, bool immediate_) + : m_binding(std::forward(binding_)), m_immediate(immediate_) { } const Binding &binding() const { return m_binding; } bool immediate() const { return m_immediate; } @@ -182,8 +170,9 @@ private: return k != Key::noOp && m_bindings.find(k) == m_bindings.end(); } - template void bind(Key k, const T &t) { - m_bindings[k].push_back(Binding(t)); + template + void bind(Key k, ArgT &&t) { + m_bindings[k].push_back(std::forward(t)); } BindingsMap m_bindings; diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 19cd2f18..049f6744 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -256,9 +256,7 @@ int main(int argc, char **argv) try { auto k = Bindings.get(input); - for (; k.first != k.second; ++k.first) - if (k.first->execute()) - break; + std::any_of(k.first, k.second, boost::bind(&Binding::execute, _1)); } catch (ConversionError &e) {