From add40d542d56c4a1232fbe7cbfd6dd96f2e7e864 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Thu, 20 Sep 2012 05:00:11 +0200 Subject: [PATCH] bindings: guarantee ordering of bindings of the same key --- src/actions.cpp | 4 ++-- src/bindings.h | 31 +++++++++++++++++++++++-------- src/help.cpp | 9 ++++++--- src/ncmpcpp.cpp | 2 +- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 16e5178e..62c1b128 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -277,9 +277,9 @@ void Action::Seek() Key input = Key::read(*wFooter); auto k = Bindings.get(input); - if (k.first == k.second || !k.first->second.isSingle()) // no single action? + if (k.first == k.second || !k.first->isSingle()) // no single action? break; - Action *a = k.first->second.action(); + Action *a = k.first->action(); if (dynamic_cast(a)) { if (songpos < Mpd.GetTotalTime()) diff --git a/src/bindings.h b/src/bindings.h index c62784bb..54f42302 100644 --- a/src/bindings.h +++ b/src/bindings.h @@ -137,12 +137,17 @@ private: /// Keybindings configuration class BindingsConfiguration { + struct KeyHash { + size_t operator()(const Key &k) const { + return (k.getChar() << 1) | (k.getType() == Key::Standard); + } + }; typedef std::unordered_map CommandsSet; - typedef std::multimap BindingsMap; + typedef std::unordered_map, KeyHash> BindingsMap; public: - typedef BindingsMap::iterator BindingIterator; - typedef BindingsMap::const_iterator ConstBindingIterator; + typedef BindingsMap::value_type::second_type::iterator BindingIterator; + typedef BindingsMap::value_type::second_type::const_iterator ConstBindingIterator; bool read(const std::string &file); void generateDefaults(); @@ -156,19 +161,29 @@ public: } std::pair get(const Key &k) { - return m_bindings.equal_range(k); + std::pair result; + auto it = m_bindings.find(k); + if (it != m_bindings.end()) { + result.first = it->second.begin(); + result.second = it->second.end(); + } else { + auto list_end = m_bindings.begin()->second.end(); + result.first = list_end; + result.second = list_end; + } + return result; } - ConstBindingIterator begin() const { return m_bindings.begin(); } - ConstBindingIterator end() const { return m_bindings.end(); } + BindingsMap::const_iterator begin() const { return m_bindings.begin(); } + BindingsMap::const_iterator end() const { return m_bindings.end(); } private: bool notBound(const Key &k) const { return k != Key::noOp && m_bindings.find(k) == m_bindings.end(); } - template void bind(Key k, T t) { - m_bindings.insert(std::make_pair(k, Binding(t))); + template void bind(Key k, const T &t) { + m_bindings[k].push_back(Binding(t)); } BindingsMap m_bindings; diff --git a/src/help.cpp b/src/help.cpp index 9685da71..1ea18d43 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -129,10 +129,13 @@ std::string Help::DisplayKeys(const ActionType at) std::string result; for (auto it = Bindings.begin(); it != Bindings.end(); ++it) { - if (it->second.isSingle() && it->second.action()->Type() == at) + for (auto j = it->second.begin(); j != it->second.end(); ++j) { - result += keyToString(it->first, &print_backspace); - result += " "; + if (j->isSingle() && j->action()->Type() == at) + { + result += keyToString(it->first, &print_backspace); + result += " "; + } } } result.resize(16, ' '); diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 92c5e1f4..eb43df69 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -248,7 +248,7 @@ int main(int argc, char **argv) auto k = Bindings.get(input); for (; k.first != k.second; ++k.first) - if (k.first->second.execute()) + if (k.first->execute()) break; if (myScreen == myPlaylist)