bindings: allow for binding multiple chains to one key

This commit is contained in:
Andrzej Rybczak
2014-08-27 01:15:28 +02:00
parent afd5c22acf
commit a7f3992c97
5 changed files with 36 additions and 53 deletions

View File

@@ -21,6 +21,8 @@
#ifndef NCMPCPP_BINDINGS_H
#define NCMPCPP_BINDINGS_H
#include <algorithm>
#include <boost/bind.hpp>
#include <cassert>
#include <unordered_map>
#include "actions.h"
@@ -74,57 +76,43 @@ struct Binding
{
typedef std::vector<Actions::BaseAction *> 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 <typename ArgT>
Binding(ArgT &&actions)
: m_actions(std::forward<ArgT>(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 <typename ArgT>
Command(ArgT &&binding_, bool immediate_)
: m_binding(std::forward<ArgT>(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 <typename T> void bind(Key k, const T &t) {
m_bindings[k].push_back(Binding(t));
template <typename ArgT>
void bind(Key k, ArgT &&t) {
m_bindings[k].push_back(std::forward<ArgT>(t));
}
BindingsMap m_bindings;