Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webengine JavaScript refactor #403

Merged
merged 65 commits into from
Apr 1, 2017

Conversation

Teklad
Copy link
Collaborator

@Teklad Teklad commented Mar 20, 2017

So.... this PR looks a lot fatter than it really is... it partially implements the json language file bit we were talking about.

At some point or another... I accidentally fixed that notorious preview gutter bug while I was working on this as well.

There's still some work to be done... but the overall performance of this is very good! This also happens to get rid of the QJSEngine requirement from the initial QWebEngine PR.

I'll most likely start cleaning up the javascript in this PR as well. Its a mess right now and could really use some TLC. Feel free to review the code when you guys get a chance. It's still a work in progress though, lol.

@@ -256,16 +254,13 @@ private slots:
int saveAs(EditorTabWidget *tabWidget, int tab, bool copy);
QUrl getSaveDialogDefaultFileName(EditorTabWidget *tabWidget, int tab);
void setupLanguagesMenu();
void transformSelectedText(std::function<QString (const QString &)> func);
void transformSelectedText(QString (*func)(const QString&));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why that change? Isn't a std::function all around more convenient and more compatible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't make sense to have the overhead for something that doesn't need any captures to begin with.

@JuBan1
Copy link
Collaborator

JuBan1 commented Mar 20, 2017

Is this PR supposed to also have all the changes from #402 in it?

@JuBan1
Copy link
Collaborator

JuBan1 commented Mar 20, 2017

Here's a question for my understanding (because I only take a glance at some of the changes at it's hard to keep up):

Right now we've two ways of getting data: the async calls you're implementing right now and using signals to set Editor's members like m_contentInfo. Why can't we only use signaling to handle all getter functions? What's special about getSelections & friends that it can't be done via signals and members?

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017

That works great for data that's accessed rather passively... but not so much for on-demand requests. As an example, if we got 10 functions that use getSelectionsText... that's either 10 signals + lambdas. or one signal... a bunch of functors and a message transport handler.

... Though the idea of just sending a "request" and intercepting the reply does sound nice, lol.... it's basically what we're doing with the async setup.... just.. uglier?

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017

The biggest blocker for that change is "getValue"... for the record... the way its tied into sessions, mainwindow, docengine, etc... makes it a pain in the behind to get working right.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017

I could change all the get[GetFunctionName] thingies to request... and provide a small flexible API for handling callbacks there in one place. It's probably doable now that I think about it. So I'm probably gonna try... because segmented API annoys the crap out of me.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017

I can't really think of a way to implement that for the others without blocking the current running thread, lol... Asynchronous programming is really tedious.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017

Here's an example of what the code would look like with signals/slots... assuming you did an in-place lambda.

void frmSearchReplace::on_searchStringEdited(const QString &/*text*/)
{
    NqqSettings& s = NqqSettings::getInstance();

    if (s.Search.getSearchAsIType()) {
        if (ui->actionFind->isChecked()) {
            Editor *editor = currentEditor();
            auto conn = std::make_shared<QMetaObject::Connection>();
            *conn = connect(editor, &Editor::selectionReply, [this, conn, editor] (QList<Editor::Selection> selections) {
                if (selections.length() > 0) {
                    editor->setCursorPosition(
                        std::min(selections[0].from, selections[0].to));
                }
                findFromUI(true);
                QObject::disconnect(*conn);
            });
            editor->requestSelections();
        }
    }
}

@JuBan1
Copy link
Collaborator

JuBan1 commented Mar 20, 2017

That works great for data that's accessed rather passively... but not so much for on-demand requests. As an example, if we got 10 functions that use getSelectionsText... that's either 10 signals + lambdas. or one signal... a bunch of functors and a message transport handler.

I think you misunderstood. What I mean is that, right now, Editor already catches a whole bunch of signals from JavaScript. Like J_EVT_CLEAN_CHANGED causes m_contentInfo.clean to be set. Then we can super easily access it via Editor::isClean().

Why is it we don't do that for stuff like getSelections()? Just have Editor catch a signal if selection changes (we kind of already do that with J_EVT_CURSOR_ACTIVITY) and store it. Then we'd need to lambdas or any other magic inside the getter function.

Sorry if that's just me being daft :P

Here's an example of what the code would look like with signals/slots...

Kill it with fire!

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017 via email

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017 via email

@JuBan1
Copy link
Collaborator

JuBan1 commented Mar 20, 2017

I think it's good- if it works :p The less we have to worry about async operations in all of the code using Editor the better.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 20, 2017 via email

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

So the proxy is probably going to go back to just sending messages/signals... as it stands it doesn't really need to store any values, because that's being handled by Editor as the data passes through.

So long as I tread carefully I should be able to implement a very clean interface for all of this and reduce the need to rely on javascript callbacks in general.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

EVIL! Unwinding that javascript spaghetti took forever! There might be a couple of functions in the wrong class... but aside from that, I think its a bit cleaner.... or at least more reliable.

This changeset really got out of hand, lol...

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

@JuBan1, I'm going to go out on a limb and assume @danieleds is having a few of his busy weekdays. Care to go over the Javascript portion and see if there's any code I could move around and/or more correct class name/filename for certain things?


// Since the original tab is replaced by a space we only need numSpaces-1
// new spaces.
tabToSpaceCounter += numSpaces-1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this. missing?

C_CMD_TAB_TO_SPACE(data)
{
editLines(function (x) {
tabToSpaceCounter = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still work since tabToSpaceCounter is now in App.helpers?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is no longer relevant since I moved helpers to a plain functions file. It all works as-is


return x.replace(/ +/g, function(match, offset) {
return App.helpers.spaceToTab(match, offset, tabSz)
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I like the idea of moving code logic into another class, I think this is a bad place to do it. There are really tricky interactions here where the algorithm won't work if a user forgets to call App.helpers.spaceToTabCounter = 0 or similar.

Previously all code was right next to each other so the interactions were easy to see and follow but now that code is more encapsulated it becomes very hard to follow code execution.

Can we move all the code to App.helpers so we only cal something along the lines of editLines(App.helpers.spaceToTab) or similar?

Same goes for the other XtoY functions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we forget about "Helpers" all together and make it a plain functions file since they're all utility functions... this would fix all three problems I think.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main point was that tightly coupled code should either be near each other or should be very clear to reduce code spaghetti. So if you think that solves it, give it a try.

else
cm.execCommand("insertSoftTab");
},
"Shift-Tab": function (cm) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, button presses are pretty much events too. Might be a nice idea to move these two functions into EditorEventHook.js as well?

@JuBan1
Copy link
Collaborator

JuBan1 commented Mar 21, 2017

Take my input with a grain of salt. My JavaScript is not great :)

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

I'm trying to think of the best way to go about those helper functions in particular... Having them in a class does break code logic a bit. I could write a shortcut "functions" file that calls the appropriate App.helpers.Function... but in all reality I think that's just nesting, lol.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

I seriously need to learn how to base a branch on a branch using git... merge conflicts are evil, lol.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 21, 2017

a.k.a. I didn't mean to include #402's changeset into this.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 30, 2017

@danieleds I already replied to that comment you tagged me in... went a different route with that so it should be fine there. I'm just ready to get this merged so I can move on to the next painful thing I have to smack around to get WebEngine working. -.-

static void invalidateEditorBuffer();

//FIXME: Possibly un-necessary?
/*
struct LanguageGreater {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

who sorts languages now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do they actually need to be sorted? From what I can tell QMap is sorting everything anyways... exactly like the sorting function was doing, lol.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect! If that's the case, then we can remove it.

@danieleds
Copy link
Member

Good to know! :D

Okay then, let's also forget about that stuff in CommunicationsManager for now.

@danieleds
Copy link
Member

Hmm, segfault on startup at languagecache.cpp#94... I need to investigate.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 30, 2017

@danieleds, that's new to me... I tested the cache heavily without any oddities.

@Teklad
Copy link
Collaborator Author

Teklad commented Mar 30, 2017

Care to share the full gdb output on that?

@danieleds
Copy link
Member

GNU gdb (Ubuntu 7.11.90.20161005-0ubuntu1) 7.11.90.20161005-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from out/debug/lib/notepadqq-bin...done.
(gdb) run
Starting program: /home/daniele/Progetti/qt/notepadqq/out/debug/lib/notepadqq-bin 
warning: the debug information found in "/lib64/ld-2.24.so" does not match "/lib64/ld-linux-x86-64.so.2" (CRC mismatch).

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Start-time benchmark started.
WARNING: Notepadqq is running in DEBUG mode.
[New Thread 0x7fffe2439700 (LWP 16202)]
[New Thread 0x7fffe180e700 (LWP 16203)]
[0401/232102:ERROR:browser_main_loop.cc(217)] Running without the SUID sandbox! See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md for more information on developing with the sandbox on.
[New Thread 0x7fffd97f7700 (LWP 16206)]
[New Thread 0x7fffd8ff6700 (LWP 16211)]
[New Thread 0x7fffcffff700 (LWP 16212)]
[New Thread 0x7fffcf7fe700 (LWP 16213)]
[New Thread 0x7fffceffd700 (LWP 16214)]
[New Thread 0x7fffce7fc700 (LWP 16215)]
[New Thread 0x7fffcdffb700 (LWP 16216)]
[New Thread 0x7fffcd7fa700 (LWP 16217)]
[New Thread 0x7fffccff9700 (LWP 16218)]
[New Thread 0x7fffabfff700 (LWP 16219)]
[New Thread 0x7fffab7fe700 (LWP 16220)]
[New Thread 0x7fffaaffd700 (LWP 16221)]
[New Thread 0x7fffaa7fc700 (LWP 16222)]
[New Thread 0x7fffa9ffb700 (LWP 16223)]
[New Thread 0x7fffa8ff9700 (LWP 16225)]
[New Thread 0x7fffa97fa700 (LWP 16224)]
[New Thread 0x7fff93fff700 (LWP 16226)]
[New Thread 0x7fff937fe700 (LWP 16227)]
[New Thread 0x7fff929ad700 (LWP 16228)]
[New Thread 0x7fff921ac700 (LWP 16229)]
Extension support is not installed.
[New Thread 0x7fff90d87700 (LWP 16234)]

Thread 1 "notepadqq-bin" received signal SIGSEGV, Segmentation fault.
0x00007ffff5904b20 in QJsonObject::keyAt(int) const () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Core.so.5



(gdb) bt
#0  0x00007ffff5904b20 in QJsonObject::keyAt(int) const () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Core.so.5
#1  0x00005555555e9bac in QJsonObject::const_iterator::key (this=0x7fffffffc790)
    at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qjsonobject.h:168
#2  0x00005555555e8d03 in EditorNS::LanguageCache::LanguageCache (
    this=0x5555558e0190 <EditorNS::LanguageCache::getInstance()::instance>) at ../ui/EditorNS/languagecache.cpp:94
#3  0x00005555555e99c8 in EditorNS::LanguageCache::getInstance () at ../ui/EditorNS/languagecache.cpp:161
#4  0x00005555555daadb in EditorNS::Editor::getLanguage (this=0x555555abbea0) at ../ui/EditorNS/editor.cpp:301
#5  0x0000555555589616 in MainWindow::refreshEditorUiInfoAll (this=0x555555d65450, editor=0x555555abbea0)
    at ../ui/mainwindow.cpp:1150
#6  0x0000555555588bc2 in MainWindow::on_currentEditorChanged (this=0x555555d65450, tabWidget=0x555555d56dd0, tab=0)
    at ../ui/mainwindow.cpp:1081
#7  0x00005555555b86fd in QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<EditorTabWidget*, int>, void, void (MainWindow::*)(EditorTabWidget*, int)>::call (f=
    (void (MainWindow::*)(MainWindow * const, EditorTabWidget *, int)) 0x555555588b86 <MainWindow::on_currentEditorChanged(EditorTabWidget*, int)>, o=0x555555d65450, arg=0x7fffffffcb90)
    at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:507
#8  0x00005555555b71aa in QtPrivate::FunctionPointer<void (MainWindow::*)(EditorTabWidget*, int)>::call<QtPrivate::List<EditorTabWidget*, int>, void> (f=
    (void (MainWindow::*)(MainWindow * const, EditorTabWidget *, int)) 0x555555588b86 <MainWindow::on_currentEditorChanged(EditorTabWidget*, int)>, o=0x555555d65450, arg=0x7fffffffcb90)
    at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:526
#9  0x00005555555b4141 in QtPrivate::QSlotObject<void (MainWindow::*)(EditorTabWidget*, int), QtPrivate::List<EditorTabWidget*, int>, void>::impl (which=1, this_=0x555555e43da0, r=0x555555d65450, a=0x7fffffffcb90, ret=0x0)
    at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobject_impl.h:149
#10 0x00007ffff594877d in QMetaObject::activate(QObject*, int, int, void**) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Core.so.5
#11 0x0000555555629a93 in TopEditorContainer::currentEditorChanged (this=0x555555d57410, _t1=0x555555d56dd0, _t2=0)
    at ../../out/build_data/moc_topeditorcontainer.cpp:316
#12 0x00005555555bb0b9 in TopEditorContainer::on_currentTabChanged (this=0x555555d57410, index=0)
    at ../ui/topeditorcontainer.cpp:103
#13 0x00005555555bc848 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<int>, void, void (TopEditorContainer::*)(int)>::call (f=
    (void (TopEditorContainer::*)(TopEditorContainer * const, int)) 0x5555555baff6 <TopEditorContainer::on_currentTabChanged(int)>, o=0x555555d57410, arg=0x7fffffffcdd0) at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:507
#14 0x00005555555bc6cd in QtPrivate::FunctionPointer<void (TopEditorContainer::*)(int)>::call<QtPrivate::List<int>, void> (f=
    (void (TopEditorContainer::*)(TopEditorContainer * const, int)) 0x5555555baff6 <TopEditorContainer::on_currentTabChanged(int)>, o=0x555555d57410, arg=0x7fffffffcdd0) at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobjectdefs_impl.h:526
#15 0x00005555555bc265 in QtPrivate::QSlotObject<void (TopEditorContainer::*)(int), QtPrivate::List<int>, void>::impl (
    which=1, this_=0x555555d6d440, r=0x555555d57410, a=0x7fffffffcdd0, ret=0x0)
    at /home/daniele/Qt/5.7/gcc_64/include/QtCore/qobject_impl.h:149
#16 0x00007ffff594877d in QMetaObject::activate(QObject*, int, int, void**) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Core.so.5
#17 0x00007ffff73cc4ee in QTabWidget::currentChanged(int) () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#18 0x00007ffff73ce5e7 in ?? () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#19 0x00007ffff5948056 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Core.so.5
#20 0x00007ffff73c052e in QTabBar::currentChanged(int) () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#21 0x00007ffff73c53b0 in QTabBar::setCurrentIndex(int) () from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#22 0x00007ffff73ca36b in QTabBar::insertTab(int, QIcon const&, QString const&) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#23 0x00007ffff73cd0ac in QTabWidget::insertTab(int, QWidget*, QIcon const&, QString const&) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#24 0x00007ffff73cd154 in QTabWidget::insertTab(int, QWidget*, QString const&) ()
   from /home/daniele/Qt/5.7/gcc_64/lib/libQt5Widgets.so.5
#25 0x00005555555bd3f8 in EditorTabWidget::rawAddEditorTab (this=0x555555d56dd0, setFocus=false, title=..., 
    source=0x0, sourceTabIndex=0) at ../ui/editortabwidget.cpp:132
#26 0x00005555555bcccc in EditorTabWidget::addEditorTab (this=0x555555d56dd0, setFocus=false, title=...)
    at ../ui/editortabwidget.cpp:40
#27 0x00005555555c1b11 in DocEngine::loadDocuments (this=0x555555d34040, fileNames=..., tabWidget=0x555555d56dd0, 
    reload=false, codec=0x0, bom=false, rememberLastSelectedDir=false) at ../ui/docengine.cpp:164
#28 0x00005555555c16c0 in DocEngine::loadDocumentSilent (this=0x555555d34040, fileName=..., tabWidget=0x555555d56dd0)
    at ../ui/docengine.cpp:110
#29 0x000055555561d3de in Sessions::loadSession (docEngine=0x555555d34040, editorContainer=0x555555d57410, 
    sessionPath=...) at ../ui/Sessions/sessions.cpp:384
#30 0x0000555555581c52 in MainWindow::MainWindow (this=0x555555d65450, workingDirectory=..., arguments=..., parent=0x0)
    at ../ui/mainwindow.cpp:138
#31 0x0000555555582186 in MainWindow::MainWindow (this=0x555555d65450, arguments=..., parent=0x0)
    at ../ui/mainwindow.cpp:191
#32 0x000055555557eca3 in main (argc=1, argv=0x7fffffffde28) at ../ui/main.cpp:122
(gdb) 

@danieleds
Copy link
Member

danieleds commented Apr 1, 2017

Quite interestingly, it doesn't happen if you replace the iterator with this (optimizable) code:

    for (QString key : json.object().keys()) {
        QJsonObject mode = json.object().value(key).toObject();
        Language newMode;
        newMode.id = key;
        newMode.name = mode.value("name").toString();
        newMode.mime = mode.value("mime").toString();
        newMode.mode = mode.value("mode").toString();
        newMode.fileNames = mode.value("fileNames")
            .toVariant().toStringList();
        newMode.fileExtensions = mode.value("fileExtensions")
            .toVariant().toStringList();
        newMode.firstNonBlankLine = mode.value("firstNonBlankLine")
            .toVariant().toStringList();
        m_languages.append(std::move(newMode));
    }

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

I'm gonna guess it's a bug in the iterator for QT 5.7... which isn't a big deal, but it's annoying, nonetheless.... one sec and I'll modify to use your code.

@danieleds
Copy link
Member

I believe that too. Qt bugs are starting to get annoying.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

Try this commit and see if it fixes it for you.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

There's a lot of black magic under the hood of QT that I'm not very fond of... It doesn't bother me to write a little extra code to make something work the way I want it... I don't need QT implying "optimizations" for me.

I started programming before we had fancy smart pointers and such, after all. :P Oh the days of malloc() and free() were simpler times.

@danieleds
Copy link
Member

Yup, working.
But does the assignment of json.object().keys() to a variable actually increase performance? I thought the range expression in the range based loop was only evaluated once.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

Is it? It might not increase performance in that case... but that "eval once" optimization might not apply to every compiler under the sun, so it doesn't hurt anything at least.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

I think it actually slows it down a bit with it as a variable (odd)... removed it. :)

@danieleds
Copy link
Member

Actually, the semantic would be completely different in that case. I think that behavior must be well defined somewhere, as it's not a decision that should be left to the compiler implementation.

Actually, you can find it in the official specification, between page 141 and 142: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

(just nitpicking :P)

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

The performance is very decent, language initialization is roughly 1/100th of a second(on my hardware) on average... and lookups are on a scale I can't really measure accurately, as they should be.

The only way to make it faster at this point would be to write a JSON parser from scratch and read it directly... but I'm not that hellbent on juicing something so simple, lol.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

Also, initialization doesn't happen until the first call of getInstance(), which keeps it self-contained, much like nqqsettings

@danieleds
Copy link
Member

Yeah it's not a performance-critical portion of code.

I was pointing it out just because of your old comment above that line, which was fine for the old loop but now it wasn't true anymore :P

Can you delete that commented stuff which was used to sort languages?

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

Done.

@Teklad
Copy link
Collaborator Author

Teklad commented Apr 1, 2017

Before we close this PR... should probably touch on what else needs to be done to complete QWebEngine... we're getting reasonably close, I think. I'm just not sure if there are anymore barriers that we're unaware of as of yet.

@danieleds
Copy link
Member

danieleds commented Apr 1, 2017

I still have problems with performance.

I guess that now is a good time for little fixes (I saw some glitches somewhere) and smart performance optimizations.

Other than that, it seems that the difficult part is over.

@danieleds danieleds merged commit 8896a26 into notepadqq:webengine-beta Apr 1, 2017
@Teklad Teklad deleted the webengine-dynajs branch April 1, 2017 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants