From 86301b8a6f5bf355d197dd6bdd3d4dad309153aa Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 28 Jul 2011 21:51:27 +0200 Subject: Refactor keys code a bit I uncoupled the binding lookup from actual adding. This will make it easier to add functions for removing bindings. --- src/Keys.cc | 67 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/Keys.cc b/src/Keys.cc index 3f7c953..68ad6fa 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -137,17 +137,23 @@ const char default_keymode[] = "default_keymode"; } // end of anonymous namespace // helper class 'keytree' -class Keys::t_key { +class Keys::t_key: private FbTk::NotCopyable { public: // typedefs typedef std::list keylist_t; + typedef std::pair FindPair; static void initKeys(FbTk::Lua &l); - static int addBindingWrapper(lua::state *l); + static int addBinding(lua::state *l); static int newKeyMode(lua::state *l); - // constructor / destructor + bool equalExact(const RefKey &x) { + return type == x->type && key == x->key && context == x->context + && isdouble == x->isdouble && mod == x->mod; + } + + // constructor t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, int context = 0, bool isdouble = false); @@ -166,18 +172,11 @@ public: return RefKey(); } - RefKey find_or_insert(int type_, unsigned int mod_, unsigned int key_, - int context_, bool isdouble_) { - - RefKey t = find(type_, mod_, key_, context_, isdouble_); - if(! t) { - t.reset(new t_key(type_, mod_, key_, context_, isdouble_)); - keylist.push_back(t); - } - return t; - } - - void addBinding(vector val, const FbTk::RefCount > &cmd ); + /** + * Returns the t_key object corresponding to the binding val and it's parent. + * The parent comes in handy when we want to remove the binding. + */ + FindPair findBinding(vector val, bool insert); // member variables @@ -193,14 +192,14 @@ public: static FbTk::Lua::RegisterInitFunction registerInitKeys; }; -int Keys::t_key::addBindingWrapper(lua::state *l) +int Keys::t_key::addBinding(lua::state *l) { l->checkstack(2); try { l->checkargno(3); - const RefKey &k = *l->checkudata(1, keymode_metatable); + RefKey k = *l->checkudata(1, keymode_metatable); if(! l->isstring(2)) { throw KeyError(_FB_CONSOLETEXT(Keys, Bad2ndArg, "2nd argument is not a string.", @@ -221,7 +220,11 @@ int Keys::t_key::addBindingWrapper(lua::state *l) cmd.reset(new FbCommands::LuaCmd(*l)); } - k->addBinding(val, cmd); + FindPair p = k->findBinding(val, true); + + k = *p.first; + k->m_command = cmd; + k->keylist.clear(); } catch(std::runtime_error &e) { cerr << "addBinding: " << e.what() << endl; @@ -248,7 +251,7 @@ void Keys::t_key::initKeys(FbTk::Lua &l) { l.rawsetfield(-2, "__gc"); l.newtable(); { - l.pushfunction(&addBindingWrapper); + l.pushfunction(&addBinding); l.rawsetfield(-2, "addBinding"); l.pushfunction(&setKeyModeWrapper); @@ -270,13 +273,12 @@ Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, type(type_), mod(mod_), key(key_), - context(context_), + context(context_ ? context_ : GLOBAL), isdouble(isdouble_), m_command(0) { - context = context_ ? context_ : GLOBAL; } -void Keys::t_key::addBinding(vector val, const FbTk::RefCount > &cmd ) { +Keys::t_key::FindPair Keys::t_key::findBinding(vector val, bool insert ) { unsigned int key = 0, mod = 0; int type = 0, context = 0; @@ -372,24 +374,23 @@ void Keys::t_key::addBinding(vector val, const FbTk::RefCountm_command) - throw KeyError("Key combination already used:" + processed); + RefKey new_key = RefKey(new t_key(type, mod, key, context, isdouble)); + keylist_t::iterator new_it = std::find_if(keylist.begin(), keylist.end(), + FbTk::MemFun(*new_key, &t_key::equalExact)); - if(val.empty()) { - if(! new_key->keylist.empty()) - throw KeyError("Key combination already used as a keychain:" + processed); + if(new_it == keylist.end() && insert) + new_it = keylist.insert(new_it, new_key); - new_key->m_command = cmd; - } else - new_key->addBinding(val, cmd); + if(new_it == keylist.end() || val.empty()) + return FindPair(new_it, *this); + else + return (*new_it)->findBinding(val, insert); } -- cgit v0.11.2