diff transform/ModelTransformerFactory.cpp @ 1740:fe3f7f8df3a3 by-id

More work on transformers
author Chris Cannam
date Wed, 26 Jun 2019 17:25:20 +0100
parents 8efce64dd85e
children 5f8fbbde08ff
line wrap: on
line diff
--- a/transform/ModelTransformerFactory.cpp	Wed Jun 26 14:59:09 2019 +0100
+++ b/transform/ModelTransformerFactory.cpp	Wed Jun 26 17:25:20 2019 +0100
@@ -56,8 +56,8 @@
 
 ModelTransformer::Input
 ModelTransformerFactory::getConfigurationForTransform(Transform &transform,
-                                                      const vector<Model *> &candidateInputModels,
-                                                      Model *defaultInputModel,
+                                                      vector<ModelId> candidateInputModels,
+                                                      ModelId defaultInputModel,
                                                       AudioPlaySource *source,
                                                       sv_frame_t startFrame,
                                                       sv_frame_t duration,
@@ -65,26 +65,39 @@
 {
     QMutexLocker locker(&m_mutex);
     
-    ModelTransformer::Input input(nullptr);
+    ModelTransformer::Input input({});
 
     if (candidateInputModels.empty()) return input;
 
     //!!! This will need revision -- we'll have to have a callback
     //from the dialog for when the candidate input model is changed,
     //as we'll need to reinitialise the channel settings in the dialog
-    Model *inputModel = candidateInputModels[0];
+    ModelId inputModel = candidateInputModels[0];
     QStringList candidateModelNames;
     QString defaultModelName;
-    QMap<QString, Model *> modelMap;
-    for (int i = 0; i < (int)candidateInputModels.size(); ++i) {
-        QString modelName = candidateInputModels[i]->objectName();
+    QMap<QString, ModelId> modelMap;
+
+    sv_samplerate_t defaultSampleRate;
+    {   auto im = ModelById::get(inputModel);
+        if (!im) return input;
+        defaultSampleRate = im->getSampleRate();
+    }
+    
+    for (int i = 0; in_range_for(candidateInputModels, i); ++i) {
+
+        auto model = ModelById::get(candidateInputModels[i]);
+        if (!model) return input;
+        
+        QString modelName = model->objectName();
         QString origModelName = modelName;
         int dupcount = 1;
         while (modelMap.contains(modelName)) {
             modelName = tr("%1 <%2>").arg(origModelName).arg(++dupcount);
         }
+        
         modelMap[modelName] = candidateInputModels[i];
         candidateModelNames.push_back(modelName);
+        
         if (candidateInputModels[i] == defaultInputModel) {
             defaultModelName = modelName;
         }
@@ -105,7 +118,7 @@
         
         RealTimePluginFactory *factory = RealTimePluginFactory::instanceFor(id);
 
-        sv_samplerate_t sampleRate = inputModel->getSampleRate();
+        sv_samplerate_t sampleRate = defaultSampleRate;
         int blockSize = 1024;
         int channels = 1;
         if (source) {
@@ -125,7 +138,7 @@
 
         Vamp::Plugin *vp =
             FeatureExtractionPluginFactory::instance()->instantiatePlugin
-            (id, float(inputModel->getSampleRate()));
+            (id, float(defaultSampleRate));
 
         plugin = vp;
     }
@@ -196,7 +209,7 @@
     return transformer;
 }
 
-Model *
+ModelId
 ModelTransformerFactory::transform(const Transform &transform,
                                    const ModelTransformer::Input &input,
                                    QString &message,
@@ -206,12 +219,12 @@
 
     Transforms transforms;
     transforms.push_back(transform);
-    vector<Model *> mm = transformMultiple(transforms, input, message, handler);
-    if (mm.empty()) return nullptr;
+    vector<ModelId> mm = transformMultiple(transforms, input, message, handler);
+    if (mm.empty()) return {};
     else return mm[0];
 }
 
-vector<Model *>
+vector<ModelId>
 ModelTransformerFactory::transformMultiple(const Transforms &transforms,
                                            const ModelTransformer::Input &input,
                                            QString &message,
@@ -220,9 +233,12 @@
     SVDEBUG << "ModelTransformerFactory::transformMultiple: Constructing transformer with input model " << input.getModel() << endl;
     
     QMutexLocker locker(&m_mutex);
+
+    auto inputModel = ModelById::get(input.getModel());
+    if (!inputModel) return {};
     
     ModelTransformer *t = createTransformer(transforms, input);
-    if (!t) return vector<Model *>();
+    if (!t) return {};
 
     if (handler) {
         m_handlers[t] = handler;
@@ -233,22 +249,24 @@
     connect(t, SIGNAL(finished()), this, SLOT(transformerFinished()));
 
     t->start();
-    vector<Model *> models = t->detachOutputModels();
-
+    vector<ModelId> models = t->getOutputModels();
+    
     if (!models.empty()) {
-        QString imn = input.getModel()->objectName();
+        QString imn = inputModel->objectName();
         QString trn =
             TransformFactory::getInstance()->getTransformFriendlyName
             (transforms[0].getIdentifier());
-        for (int i = 0; i < (int)models.size(); ++i) {
+        for (int i = 0; in_range_for(models, i); ++i) {
+            auto model = ModelById::get(models[i]);
+            if (!model) continue;
             if (imn != "") {
                 if (trn != "") {
-                    models[i]->setObjectName(tr("%1: %2").arg(imn).arg(trn));
+                    model->setObjectName(tr("%1: %2").arg(imn).arg(trn));
                 } else {
-                    models[i]->setObjectName(imn);
+                    model->setObjectName(imn);
                 }
             } else if (trn != "") {
-                models[i]->setObjectName(trn);
+                model->setObjectName(trn);
             }
         }
     } else {
@@ -284,12 +302,12 @@
 
     m_runningTransformers.erase(transformer);
 
-    map<AdditionalModelHandler *, vector<Model *>> toNotifyOfMore;
+    map<AdditionalModelHandler *, vector<ModelId>> toNotifyOfMore;
     vector<AdditionalModelHandler *> toNotifyOfNoMore;
     
     if (m_handlers.find(transformer) != m_handlers.end()) {
         if (transformer->willHaveAdditionalOutputModels()) {
-            vector<Model *> mm = transformer->detachAdditionalOutputModels();
+            vector<ModelId> mm = transformer->getAdditionalOutputModels();
             toNotifyOfMore[m_handlers[transformer]] = mm;
         } else {
             toNotifyOfNoMore.push_back(m_handlers[transformer]);
@@ -299,11 +317,9 @@
 
     m_mutex.unlock();
 
-    // These calls have to be made without the mutex held, as they may
-    // ultimately call back on us (e.g. we have one baroque situation
-    // where this could trigger a command to create a layer, which
-    // triggers the command history to clip the stack, which deletes a
-    // spare old model, which calls back on our modelAboutToBeDeleted)
+    // We make these calls without the mutex held, in case they
+    // ultimately call back on us - not such a concern as in the old
+    // model lifecycle but just in case
     
     for (const auto &i: toNotifyOfMore) {
         i.first->moreModelsAvailable(i.second);
@@ -322,43 +338,6 @@
     delete transformer;
 }
 
-void
-ModelTransformerFactory::modelAboutToBeDeleted(Model *m)
-{
-    TransformerSet affected;
-
-    {
-        QMutexLocker locker(&m_mutex);
-    
-        for (TransformerSet::iterator i = m_runningTransformers.begin();
-             i != m_runningTransformers.end(); ++i) {
-
-            ModelTransformer *t = *i;
-
-            if (t->getInputModel() == m) {
-                affected.insert(t);
-            } else {
-                vector<Model *> mm = t->getOutputModels();
-                for (int i = 0; i < (int)mm.size(); ++i) {
-                    if (mm[i] == m) affected.insert(t);
-                }
-            }
-        }
-    }
-
-    for (TransformerSet::iterator i = affected.begin();
-         i != affected.end(); ++i) {
-
-        ModelTransformer *t = *i;
-
-        t->abandon();
-
-        t->wait(); // this should eventually call back on
-                   // transformerFinished, which will remove from
-                   // m_runningTransformers and delete.
-    }
-}
-
 bool
 ModelTransformerFactory::haveRunningTransformers() const
 {