Added tempKeys, & lua hooks for tempKeys/permKeys#472
Added tempKeys, & lua hooks for tempKeys/permKeys#472vadi2 merged 33 commits intoMudlet:developmentfrom
Conversation
|
Awesome, thanks! Will review this in the next couple of days. We've improved on some code guidelines since the alias code was written, but they haven't been applied to Alias yet so no complaints from me in that regard! |
src/KeyUnit.cpp
Outdated
|
|
||
| bool KeyUnit::killKey( QString & name ) { | ||
| typedef list<TKey *>::const_iterator I; | ||
| for( I it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it++) |
There was a problem hiding this comment.
Yeah, since we've adopted C++11 you can now use the auto keyword to avoid the typedefs... 😀
| else return QString("undefined key"); | ||
| } | ||
|
|
||
| void KeyUnit::initStats() |
There was a problem hiding this comment.
You've obviously seen similar code in a different Mudlet "item" class and taken the initiative to replicate the stats reporting stuff. Kudos for doing it, though we may want to rethink this if we get around to doing something like this for all of "Buttons/Menus/Toolbars; Keys, Aliases, Timers, Triggers..." err "Scripts" and "Variables"... 😮
src/TLuaInterpreter.cpp
Outdated
| { | ||
| luaSendText = lua_tostring( L, 1 ); | ||
| } | ||
| Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; |
There was a problem hiding this comment.
We have some different boiler-plate now that checks for a null pHost and returns an (error) string before produced a lua_error( L ). {Until very recently yours truely 😊 was going for a lua nil+error message response but that is not the pattern I should have used.}
src/TLuaInterpreter.cpp
Outdated
| } | ||
| else | ||
| { | ||
| luaSendText = lua_tostring( L, 1 ); |
There was a problem hiding this comment.
In the medium term, we will replace these std::string capturing lines with QString ones and replacing the cargo-cult "luaSendText" with more meaningful local names. In this case I'd suggest using a QString:
itemName = QString::fromUtf8( lua_tostring( L, 1 ) );
src/TLuaInterpreter.cpp
Outdated
| string luaSendText=""; | ||
| if( ! lua_isstring( L, 1 ) ) | ||
| { | ||
| lua_pushstring( L, "killKey: wrong argument type" ); |
There was a problem hiding this comment.
To support the I18n work for Mudlet 4.0 you will see later code in this class containing more informative (and translatable should we go that way) error code such as:
lua_pushstring( L, tr( "killKey: bad argument #1 type (key name as string expected, got %1!)" )
.arg( luaL_typename( L, 1 ) )
.toUtf8().constData() );
There was a problem hiding this comment.
While looking into this, I also found on line 3201 the following variant. (I typed it in, as vmware stopped sharing my clipboard. this might not be exactly the line, but more or less)
lua_pushfstring( L, tr( "startLogging: bad argument #1 (turn logging on/off, as boolean expected, got %s)", luaL_typename(L,1) ).toUtf8().constData() );
This syntax seems more clear to me, but I assume there's a good reason to use the .arg() call instead? If so, I can fix that line while I'm at it.
There was a problem hiding this comment.
I don't see why can't we use lua_pushfstring() - @SlySven ? I'd prefer it over having to wrap things in .arg().
There was a problem hiding this comment.
alright, I've committed one with the .arg syntax, since that's what was suggested when I'd started. I can switch that over pretty easily though, if you'd like.
There was a problem hiding this comment.
I am not sure that lua_pushfstring(...) will work here, tr("string") needs .args() to supply the replacement parameters %1..%99 - the only other valid replacement string is (I have recently discovered) a %n which uses the numeric value as a third argument to tr("string","context",integer) to select the right plural/alternative text form to use in conjunction with the actual number positioned where the %n is, some languages have up to three!
E.g. English has “0 rooms”, “1 room”, “2 rooms”
But French has «0 pièce», «1 pièce», «2 pièces»
And leaving raw strings around (Qt assumes Utf8 not ASCII source files but I am not sure about other parts of the process) will flag as issues when we start looking for the bits that have to be translated as opposed to internal stuff that does not - though to be honest we have not had the discussion of how we will get all multi-lingual for Mudlet 4.0 {though I have some strong feelings about part of it - but we will need to colour some of the details in!}
There was a problem hiding this comment.
For sure. I'll start a thread on the forums so we can invite others to the discussion.
src/TLuaInterpreter.cpp
Outdated
| luaSendText = lua_tostring( L, 1 ); | ||
| } | ||
| Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; | ||
| QString text(luaSendText.c_str()); |
There was a problem hiding this comment.
As I've suggested a modification to capture the (unicode) QString directly this line can go and the following would become:
lua_pushboolean( L, pHost->getKeyUnit()->killKey( itemName ) );
Hope these suggestions are of use...
| TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); | ||
| QString _luaFunction = luaFunction.c_str(); | ||
| QString _luaRegex = luaRegex.c_str(); | ||
| int timerID = pLuaInterpreter->startTempAlias( _luaRegex, _luaFunction ); |
There was a problem hiding this comment.
Huh, was that there...! Well spotted.
src/TLuaInterpreter.cpp
Outdated
| else if( type == "keybind") | ||
| { | ||
| QMap<QString, TKey *>::const_iterator it1 = pHost->getKeyUnit()->mLookupTable.find( name ); | ||
| while( it1 != pHost->getKeyUnit()->mLookupTable.end() && it1.key() == name ) |
There was a problem hiding this comment.
🤔 If, as I suspect, pHost->getKeyUnit()->mLookupTable is a QMap<QString, TKey *> can not the iteration loop be collapsed to:
cnt += pHost->getKeyUnit()->mLookupTable.count( name );
There is an (int)QMap::count(const Key &key) const method after all...
Actually that pHost->getKeyUnit()->mLookupTable may be a QMultiMap<QString, TKey *> as a QMap does not normally support multiple entries with the same key (unless QMap::insertMulti( const Key &key, const T &value ) was used to populate items with the same key. The QMap::const_iterator can handle either type...
There was a problem hiding this comment.
As it turns out, exists() doesn't work for keybinds right now. I thought I'd sorted that out, but just tested it, and it fails. So your suggestions may solve the problem I'm running into also.
There was a problem hiding this comment.
They did end up being QMultiMaps, but count() still worked as expected.
It seems that KeyUnit is not using mLookupTable in the same way that AliasUnit does, and since exists() relies on mLookupTable, that's the reason I can't get exists() to work with keybinds.
Couple things yet to try, but I should find out why AU and KU are tracking their children in different ways first, because I don't want to accidentally break something.
src/TLuaInterpreter.cpp
Outdated
| luaKeyCode = lua_tointeger( L, 3 ); | ||
| } | ||
|
|
||
| int luaModifier; |
There was a problem hiding this comment.
We may need to document the integer values for this on the Wiki - they are Qt defined constants:
enum Qt::KeyboardModifier
flags Qt::KeyboardModifiers
This enum describes the modifier keys.
Constant Value Description
Qt::NoModifier 0x00000000 No modifier key is pressed.
Qt::ShiftModifier 0x02000000 A Shift key on the keyboard is pressed.
Qt::ControlModifier 0x04000000 A Ctrl key on the keyboard is pressed.
Qt::AltModifier 0x08000000 An Alt key on the keyboard is pressed.
Qt::MetaModifier 0x10000000 A Meta key on the keyboard is pressed.
Qt::KeypadModifier 0x20000000 A keypad button is pressed.
Qt::GroupSwitchModifier 0x40000000 X11 only. A Mode_switch key on the keyboard is pressed.
Note that on MacOs that Ctrl is the "Command" or "⌘" key...
src/XMLexport.cpp
Outdated
| @@ -555,8 +555,10 @@ bool XMLexport::writeHost( Host * pHost ) | |||
| if( ! (*it) || (*it)->mModuleMember) { | |||
There was a problem hiding this comment.
Can include the temp key check here instead as:
if( ! (*it) || (*it)->isTempKey() || (*it)->mModuleMember) {
SlySven
left a comment
There was a problem hiding this comment.
Nothing critically against this PR just some suggested improvements...
|
Thanks for the suggestions, I'll see what I can do about cleaning things up. C++ is not my best language, so I was heavily pulling from code I recognized to be similar, and fell into some pitfalls as a result. Some of the style issues (the auto thing in particular) came because I was basing my code off of the 3.0.0 tag, and then later moved my changes to the development branch. In any case, I'll attack some of these later today, and see if I can commit something a bit cleaner. Edit: I was actually curious about style guidelines, as I saw many inconsistencies among similar code sprinkled about. If there is an official style guideline file, I'd be happy to start working on getting some more of the code into compliance with it. |
|
We need to write an official one up and also sort out our .clang-format. It's a bit word of mouth right now - sorry. It's on the TODO list we're getting through! |
|
Tagging #628 |
…nto development
|
@SecareLupus tag the PR with 'Ready' when you'd like it reviewed. Thanks for working on this! |
|
I don't think I can actually tag this pull request. Not sure how to, at least. |
|
I couldn't see an easy way to iterate over the names and values of an enum in c++, only the values, so I couldn't find a way to populate the keys in the lua list. Also, wouldn't the lua execution have the same speed regardless of whether we're reading from a file or building the string from scratch? The only difference in execution time should be the sourcing of the string we're executing in the lua interpereter. With this in mind, wouldn't it be faster to read hard-coded values from a lua script file than to iterated over the keys and values of a list, building a string from them? Between not seeing how to build the string, and my assumption that it would be more programmatically costly to do so, I thought this was the most elegant way to handle the issue. Unrelatedly, I'm not sure what
is in reference to. |
|
Github screwed up the rendering... it was a comment on |
|
Try http://blog.qt.io/blog/2008/10/09/coding-tip-pretty-printing-enum-values/, does that let you get the name as well as the value? |
|
Resolved some more conflicts that happened again, though it was due to a pretty awesome commit a975a93 which allows coroutines in Mudlet so it's forgivable. |
|
That link is using QMetaEnum to access the info. The QMetaEnum object is being passed from a QMetaObject. I'm not sure how to generate a QMetaQbject to do that though, and if we're spending all these cycles iterating through an emum and building a string to pass to the lua interpreter, what's the benefit to building that string on the fly, vs having it prebuilt and in a .lua file? I suppose if Qt::Key changes, it wouldn't need to be updated, but mudlet doesn't really support every item in the |
|
|
|
I've simplified the loading since we'll be using this method instead, when I gave the advice I was thinking of the autogenerated string. By the way I think the new C++11 keyword |
SlySven
left a comment
There was a problem hiding this comment.
Some clean-up work (with clang-format), some revising for non-translatable lua error messages and elimination of redundant intermediate QString variables in TLuaInterpreter to do I think...
src/KeyUnit.cpp
Outdated
| return found; | ||
| } | ||
|
|
||
| bool KeyUnit::killKey( QString & name ) { |
There was a problem hiding this comment.
📝 We now aim to have function opening braces on the next line but it may not yet be the case for all our source code - no need to worry about it though
- it will get cleaned up at some stage in the near future.
| @@ -227,10 +266,16 @@ void KeyUnit::addKey(TKey* pT) | |||
|
|
|||
| void KeyUnit::removeKey(TKey* pT) | |||
There was a problem hiding this comment.
💭 This is functionally very similar to (void) KeyUnit::removeKeyRootNode(TKey*) so that could just call this one and then do the one extra line of code - but that does not matter for this PR, ![]()
src/KeyUnit.cpp
Outdated
| msg << "Keys current total: " << QString::number(statsKeyTotal) << "\n" | ||
| << "tempKeys current total: " << QString::number(statsTempKeys) << "\n" | ||
| << "active Keys: " << QString::number(statsActiveKeys) << "\n"; | ||
| /*<< "active Aliass max this session: " << QString::number(statsActiveAliassMax) << "\n" |
There was a problem hiding this comment.
If there is not an equivalent TKey related statistic then these comments should not be left here - and if there are then they ought to be edited to be appropriate IMHO - even if left commented out for the moment.
src/TLuaInterpreter.cpp
Outdated
| int TLuaInterpreter::enableKey( lua_State *L ) | ||
| { | ||
| string luaSendText=""; | ||
| string luaNameID = ""; |
There was a problem hiding this comment.
I believe this should be a QString by now as we pass it as one of those to host.getKeyUnit()->enableKey(...) further down anyhow.
Also there is no need to have a "lua" prefix for the variable name (which has been derived from the generic luaText that has been mindlessly copied and pasted between a whole load of functions) - keyName is what I would have used - but that is just my feeling on the subject! 🙊
src/TLuaInterpreter.cpp
Outdated
| if( ! lua_isstring( L, 1 ) ) | ||
| { | ||
| lua_pushstring( L, "enableKey: wrong argument type" ); | ||
| lua_pushstring( L, tr( "enableKey: bad argument #1 type (key name as string expected, got %1!)" ) |
There was a problem hiding this comment.
This may be one source of the current re-basing conflicts and we are no longer planning to translate error messages so these THREE new lines should instead be:
lua_pushfstring(L, "enableKey: bad argument #1 type (key name as string expected, got %s!)",
luaL_typename(L, 1));
and the following pair of lines are also refactored to avoid a moan from Coverity (or Codacy, can't remember which!) about an unreachable line (the return 1; one - which is never executed as lua_error(L) never returns - as it does a system longjmp() instead):
return lua_error(L);
src/TLuaInterpreter.cpp
Outdated
| } | ||
| Host& host = getHostFromLua(L); | ||
| QString text(luaSendText.c_str()); | ||
| QString text(luaNameID.c_str()); |
There was a problem hiding this comment.
This line is now redundant as we already have it as a QString, and the following line uses keyName instead of text! 🤓
This sort of thing also should be done in the remaining changed TLuaInterpreter functions...
src/XMLexport.cpp
Outdated
| } | ||
| if ((*it)->mModuleMember) { | ||
| if (!writeKey(*it)) { | ||
| if( ! (*it)->isTempKey() && (*it)->mModuleMember ) { |
There was a problem hiding this comment.
If you have clang-format available and you are using a recent Qt Creator as your IDE you ought to use that "beautifier" on the functions you have edited - that should make the layout more closely match the layout we are trying to adopt throughout our C++ code now - and make the number of lines of things that have changed smaller... 🤓
src/mudlet-lua/lua/KeyCodes.lua
Outdated
| ["Meta"] = 0x10000000, | ||
| ["Keypad"] = 0x20000000, | ||
| ["GroupSwitch"] = 0x40000000, | ||
| } No newline at end of file |
There was a problem hiding this comment.
Needs a new-line at the end of the file I think!
Also, if you are adding to the set of files that we need to distribute like this (and its contents could instead be included inside one of the existing ones IMVHO) then please also add this file to the relevant list {the LUA.files one} in the main qmake project file (i.e. /src/src.pro) as well otherwise it may get missed by one of the installers...
src/dlgPackageExporter.cpp
Outdated
| QTreeWidgetItem* top = items.first(); | ||
| for (it = tList.begin(); it != tList.end(); it++) { | ||
| TKey* pChild = *it; | ||
| list<TKey *>::const_iterator it; |
There was a problem hiding this comment.
The first six of these nine lines of change seem entirely down to white space differences where the new one does not seem to match our code style - they ought to be restored either by hand or using the Clang-format beautifier on this chunk of code IMHO!
|
Ah man, don't wait until the last minute to give all of that! @SecareLupus I'll do the requested changes in the interests of time so we get this in 😁 |
|
OK - I've applied all the changes. They're pretty minor so I assume no other feedback was necessary, will merge this tomorrow unless there are any other unmentioned concerns! |
SlySven
left a comment
There was a problem hiding this comment.
...will merge this tomorrow unless there are any other unmentioned concerns!
Well the things about using a QString marked as a candidate for translation as an error message AND use of an unnecessary std::string for something that gets changed to a QString before being passed to the C++ code in TLuaInterpreter::enableKey() also applies equally to the disableKey() one case - and there are similar things with the other TLuaInterpreter functions that get doctored/added here I am afraid... 😞
@vadi2 I'll give it my approval as I can see you will want to clear those things up and get it in.. 😄
|
@SecareLupus it's in! You've taken on a pretty hefty chunk and got it done, that's awesome for the first go!! This'll make it into Mudlet 3.2 in the next couple of days and then you could use it in your scripts 😃 if you'd like to make any more improvements, feel free to come again! There's a ton of things to improve here. |
I think a file slipped in where I was just cleaning up some indentations, as well. The new API mirrors the existing API for Alias(s), etc.