changeset 2550:a004f981f6f5 startup-timing

Some work to try to get the main window up & functioning quicker - without waiting for the transforms to be populated first. Needs a lot more testing, not to be merged until after 4.1.
author Chris Cannam
date Wed, 03 Jun 2020 14:12:14 +0100 (2020-06-03)
parents 8ac67c315afa
children 59aa2fb55523
files main/MainWindow.cpp main/MainWindow.h main/main.cpp repoint-lock.json repoint-project.json version.h
diffstat 6 files changed, 134 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/main/MainWindow.cpp	Mon May 18 15:29:46 2020 +0100
+++ b/main/MainWindow.cpp	Wed Jun 03 14:12:14 2020 +0100
@@ -176,7 +176,8 @@
     m_activityLog(new ActivityLog()),
     m_unitConverter(new UnitConverter()),
     m_keyReference(new KeyReference()),
-    m_templateWatcher(nullptr)
+    m_templateWatcher(nullptr),
+    m_transformPopulater(nullptr)
 {
     Profiler profiler("MainWindow::MainWindow");
 
@@ -334,7 +335,7 @@
     NetworkPermissionTester tester(withOSCSupport);
     bool networkPermission = tester.havePermission();
     if (networkPermission) {
-        SVDEBUG << "MainWindow: Starting transform population thread" << endl;
+        SVDEBUG << "MainWindow: Starting uninstalled-transform population thread" << endl;
         TransformFactory::getInstance()->startPopulationThread();
 
         m_surveyer = nullptr;
@@ -382,19 +383,20 @@
         startOSCQueue(false);
     }
     
-    QTimer::singleShot(500, this, SLOT(betaReleaseWarning()));
+//    QTimer::singleShot(500, this, SLOT(betaReleaseWarning()));
     
-    QString warning = PluginScan::getInstance()->getStartupFailureReport();
-    if (warning != "") {
-        QTimer::singleShot(500, this, SLOT(pluginPopulationWarning()));
-    }
-
     SVDEBUG << "MainWindow: Constructor done" << endl;
 }
 
 MainWindow::~MainWindow()
 {
 //    SVDEBUG << "MainWindow::~MainWindow" << endl;
+
+    if (m_transformPopulater) {
+        m_transformPopulater->wait();
+        delete m_transformPopulater;
+    }
+    
     delete m_keyReference;
     delete m_activityLog;
     delete m_unitConverter;
@@ -409,6 +411,8 @@
 void
 MainWindow::setupMenus()
 {
+    SVDEBUG << "MainWindow::setupMenus" << endl;
+    
     if (!m_mainMenusCreated) {
 
 #ifdef Q_OS_LINUX
@@ -459,9 +463,11 @@
     setupEditMenu();
     setupViewMenu();
     setupPaneAndLayerMenus();
-    setupTransformsMenu();
+    prepareTransformsMenu();
 
     m_mainMenusCreated = true;
+
+    SVDEBUG << "MainWindow::setupMenus: done" << endl;
 }
 
 void
@@ -513,6 +519,8 @@
 void
 MainWindow::setupFileMenu()
 {
+    SVDEBUG << "MainWindow::setupFileMenu" << endl;
+    
     if (m_mainMenusCreated) return;
 
     QMenu *menu = menuBar()->addMenu(tr("&File"));
@@ -686,8 +694,7 @@
     menu->addAction(action);
         
     menu->addSeparator();
-    action = new QAction(il.load("exit"),
-                         tr("&Quit"), this);
+    action = new QAction(il.load("exit"), tr("&Quit"), this);
     action->setShortcut(tr("Ctrl+Q"));
     action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName()));
     connect(action, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
@@ -698,6 +705,8 @@
 void
 MainWindow::setupEditMenu()
 {
+    SVDEBUG << "MainWindow::setupEditMenu" << endl;
+    
     if (m_mainMenusCreated) return;
 
     QMenu *menu = menuBar()->addMenu(tr("&Edit"));
@@ -946,6 +955,8 @@
 void
 MainWindow::setupViewMenu()
 {
+    SVDEBUG << "MainWindow::setupViewMenu" << endl;
+    
     if (m_mainMenusCreated) return;
 
     IconLoader il;
@@ -1226,6 +1237,8 @@
 void
 MainWindow::setupPaneAndLayerMenus()
 {
+    SVDEBUG << "MainWindow::setupPaneAndLayerMenus" << endl;
+    
     Profiler profiler("MainWindow::setupPaneAndLayerMenus");
     
     if (m_paneMenu) {
@@ -1690,11 +1703,58 @@
 }
 
 void
-MainWindow::setupTransformsMenu()
+MainWindow::prepareTransformsMenu()
 {
+    SVDEBUG << "MainWindow::prepareTransformsMenu" << endl;
+
+    if (m_transformsMenu) {
+        return;
+    }
+    
+    m_transformsMenu = menuBar()->addMenu(tr("&Transform")); 
+    m_transformsMenu->setTearOffEnabled(true);
+    m_transformsMenu->setSeparatorsCollapsible(true);
+
+    SVDEBUG << "MainWindow::prepareTransformsMenu: Starting installed-transform population thread" << endl;
+    m_transformPopulater = new TransformPopulater(this);
+    m_transformPopulater->start();
+}
+
+void
+MainWindow::TransformPopulater::run()
+{
+    usleep(200000);
+    
+    TransformFactory *tf = TransformFactory::getInstance();
+    if (!tf) return;
+
+    connect(tf, SIGNAL(transformsPopulated()),
+            m_mw, SLOT(populateTransformsMenu()));
+
+    SVDEBUG << "MainWindow::TransformPopulater::run: scanning" << endl;
+    
+    PluginScan::getInstance()->scan();
+
+    QString warning = PluginScan::getInstance()->getStartupFailureReport();
+    if (warning != "") {
+        QTimer::singleShot(500, m_mw, SLOT(pluginPopulationWarning()));
+    }
+
+    SVDEBUG << "MainWindow::TransformPopulater::run: populating" << endl;
+    
+    (void)tf->haveTransform({}); // populate!
+
+    SVDEBUG << "MainWindow::TransformPopulater::run: done" << endl;
+}
+
+void
+MainWindow::populateTransformsMenu()
+{
+    SVDEBUG << "MainWindow::populateTransformsMenu" << endl;
+
     if (m_transformsMenu) {
         m_transformsMenu->clear();
-        m_recentTransformsMenu->clear();
+        m_rightButtonTransformsMenu->clear();
         m_transformActionsReverse.clear();
         m_transformActions.clear();
         for (auto a: m_transformActions) {
@@ -1941,11 +2001,15 @@
     m_rightButtonTransformsMenu->addAction(action);
 
     setupRecentTransformsMenu();
+
+    updateMenuStates();
 }
 
 void
 MainWindow::setupHelpMenu()
 {
+    SVDEBUG << "MainWindow::setupHelpMenu" << endl;
+    
     QMenu *menu = menuBar()->addMenu(tr("&Help"));
     menu->setTearOffEnabled(true);
     
@@ -1984,6 +2048,8 @@
 void
 MainWindow::setupRecentFilesMenu()
 {
+    SVDEBUG << "MainWindow::setupRecentFilesMenu" << endl;
+    
     m_recentFilesMenu->clear();
     vector<QString> files = m_recentFiles.getRecent();
     for (size_t i = 0; i < files.size(); ++i) {
@@ -2004,6 +2070,8 @@
 void
 MainWindow::setupTemplatesMenu()
 {
+    SVDEBUG << "MainWindow::setupTemplatesMenu" << endl;
+    
     m_templatesMenu->clear();
 
     QAction *defaultAction = m_templatesMenu->addAction(tr("Standard Waveform"));
@@ -2053,6 +2121,8 @@
 void
 MainWindow::setupRecentTransformsMenu()
 {
+    SVDEBUG << "MainWindow::setupRecentTransformsMenu" << endl;
+    
     m_recentTransformsMenu->clear();
     vector<QString> transforms = m_recentTransforms.getRecent();
     for (size_t i = 0; i < transforms.size(); ++i) {
@@ -2080,6 +2150,8 @@
 void
 MainWindow::setupExistingLayersMenus()
 {
+    SVDEBUG << "MainWindow::setupExistingLayersMenus" << endl;
+    
     if (!m_existingLayersMenu) return; // should have been created by setupMenus
 
 //    SVDEBUG << "MainWindow::setupExistingLayersMenu" << endl;
@@ -2169,6 +2241,8 @@
 void
 MainWindow::setupToolbars()
 {
+    SVDEBUG << "MainWindow::setupToolbars" << endl;
+    
     m_keyReference->setCategory(tr("Playback and Transport Controls"));
 
     IconLoader il;
@@ -2285,25 +2359,23 @@
     connect(m_soloAction, SIGNAL(triggered()), this, SLOT(playSoloToggled()));
     connect(this, SIGNAL(canChangeSolo(bool)), m_soloAction, SLOT(setEnabled(bool)));
 
-    QAction *alAction = nullptr;
-    if (Document::canAlign()) {
-        alAction = toolbar->addAction(il.load("align"),
-                                      tr("Align File Timelines"));
-        alAction->setCheckable(true);
-        alAction->setChecked(m_viewManager->getAlignMode());
-        alAction->setStatusTip(tr("Treat multiple audio files as versions of the same work, and align their timelines"));
-        connect(m_viewManager, SIGNAL(alignModeChanged(bool)),
-                alAction, SLOT(setChecked(bool)));
-        connect(alAction, SIGNAL(triggered()), this, SLOT(alignToggled()));
-        connect(this, SIGNAL(canAlign(bool)), alAction, SLOT(setEnabled(bool)));
-    }
+    QAction *alAction = toolbar->addAction(il.load("align"),
+                                           tr("Align File Timelines"));
+    alAction->setCheckable(true);
+    alAction->setChecked(m_viewManager->getAlignMode());
+    alAction->setStatusTip(tr("Treat multiple audio files as versions of the same work, and align their timelines"));
+    alAction->setEnabled(false); // until canAlign emitted
+    connect(m_viewManager, SIGNAL(alignModeChanged(bool)),
+            alAction, SLOT(setChecked(bool)));
+    connect(alAction, SIGNAL(triggered()), this, SLOT(alignToggled()));
+    connect(this, SIGNAL(canAlign(bool)), alAction, SLOT(setEnabled(bool)));
 
     m_keyReference->registerShortcut(m_playAction);
     m_keyReference->registerShortcut(m_recordAction);
     m_keyReference->registerShortcut(m_playSelectionAction);
     m_keyReference->registerShortcut(m_playLoopAction);
     m_keyReference->registerShortcut(m_soloAction);
-    if (alAction) m_keyReference->registerShortcut(alAction);
+    m_keyReference->registerShortcut(alAction);
     m_keyReference->registerShortcut(m_rwdAction);
     m_keyReference->registerShortcut(m_ffwdAction);
     m_keyReference->registerShortcut(m_rwdSimilarAction);
@@ -2316,7 +2388,7 @@
     menu->addAction(m_playSelectionAction);
     menu->addAction(m_playLoopAction);
     menu->addAction(m_soloAction);
-    if (alAction) menu->addAction(alAction);
+    menu->addAction(alAction);
     menu->addSeparator();
     menu->addAction(m_rwdAction);
     menu->addAction(m_ffwdAction);
@@ -2532,6 +2604,8 @@
 void
 MainWindow::updateMenuStates()
 {
+    SVDEBUG << "MainWindow::updateMenuStates" << endl;
+    
     MainWindowBase::updateMenuStates();
 
     Pane *currentPane = nullptr;
@@ -2562,7 +2636,10 @@
     
     bool alignMode = m_viewManager && m_viewManager->getAlignMode();
     emit canChangeSolo(havePlayTarget && !alignMode);
-    emit canAlign(havePlayTarget && m_document && m_document->canAlign());
+
+    if (TransformFactory::getInstance()->havePopulated()) {
+        emit canAlign(havePlayTarget && m_document && m_document->canAlign());
+    }
 
     emit canChangePlaybackSpeed(true);
     int v = m_playSpeed->value();
--- a/main/MainWindow.h	Mon May 18 15:29:46 2020 +0100
+++ b/main/MainWindow.h	Wed Jun 03 14:12:14 2020 +0100
@@ -156,6 +156,8 @@
     virtual void midiEventsAvailable();
     virtual void playStatusChanged(bool);
 
+    void populateTransformsMenu();
+    
     virtual void betaReleaseWarning();
     virtual void pluginPopulationWarning();
 
@@ -284,21 +286,31 @@
     QString getReleaseText() const;
     
     void setupMenus() override;
-    virtual void setupFileMenu();
-    virtual void setupEditMenu();
-    virtual void setupViewMenu();
-    virtual void setupPaneAndLayerMenus();
-    virtual void setupTransformsMenu();
-    virtual void setupHelpMenu();
-    virtual void setupExistingLayersMenus();
-    virtual void setupToolbars();
 
-    virtual void addPane(const LayerConfiguration &configuration, QString text);
+    void setupFileMenu();
+    void setupEditMenu();
+    void setupViewMenu();
+    void setupPaneAndLayerMenus();
+    void prepareTransformsMenu();
+    void setupHelpMenu();
+    void setupExistingLayersMenus();
+    void setupToolbars();
+
+    class TransformPopulater : public QThread {
+    public:
+        TransformPopulater(MainWindow *mw) : QThread(mw), m_mw(mw) { }
+        void run() override;
+    private:
+        MainWindow *m_mw;
+    };
+    TransformPopulater *m_transformPopulater;
+    
+    void addPane(const LayerConfiguration &configuration, QString text);
 
     void closeEvent(QCloseEvent *e) override;
     bool checkSaveModified() override;
 
-    virtual void exportAudio(bool asData);
+    void exportAudio(bool asData);
 
     void updateVisibleRangeDisplay(Pane *p) const override;
     void updatePositionStatusDisplays() const override;
--- a/main/main.cpp	Mon May 18 15:29:46 2020 +0100
+++ b/main/main.cpp	Wed Jun 03 14:12:14 2020 +0100
@@ -436,10 +436,6 @@
             << QSslSocket::sslLibraryBuildVersionString()
             << endl;
 #endif
-    
-    // Make known-plugins query as early as possible after showing
-    // splash screen.
-    PluginScan::getInstance()->scan();
 
     if (showSplash) {
         application.processEvents();
@@ -546,6 +542,8 @@
                 << "\"" << endl;
         gui->cueOSCScript(scriptFile);
     }
+
+    SVDEBUG << "Entering main event loop" << endl;
     
     int rv = application.exec();
 
--- a/repoint-lock.json	Mon May 18 15:29:46 2020 +0100
+++ b/repoint-lock.json	Wed Jun 03 14:12:14 2020 +0100
@@ -4,13 +4,13 @@
       "pin": "0e32c328b02a"
     },
     "svcore": {
-      "pin": "4c5736a517e0"
+      "pin": "7b6e18380e8f"
     },
     "svgui": {
       "pin": "bd1a7c84da8c"
     },
     "svapp": {
-      "pin": "cf4e0f3c2406"
+      "pin": "7bded7599874"
     },
     "checker": {
       "pin": "e839338d3869"
--- a/repoint-project.json	Mon May 18 15:29:46 2020 +0100
+++ b/repoint-project.json	Wed Jun 03 14:12:14 2020 +0100
@@ -16,7 +16,8 @@
         },
         "svcore": {
             "vcs": "hg",
-            "service": "soundsoftware"
+            "service": "soundsoftware",
+            "branch": "startup-timing"
         },
         "svgui": {
             "vcs": "hg",
--- a/version.h	Mon May 18 15:29:46 2020 +0100
+++ b/version.h	Wed Jun 03 14:12:14 2020 +0100
@@ -1,1 +1,1 @@
-#define SV_VERSION "4.1-pre1"
+#define SV_VERSION "4.1"