changeset 877:b109b88bfa85 tonioni

Callback handler for additional models at end of processing
author Chris Cannam
date Wed, 29 Jan 2014 15:58:15 +0000
parents 47aa3aeb687b
children a2689db084f4
files transform/FeatureExtractionModelTransformer.cpp transform/FeatureExtractionModelTransformer.h transform/ModelTransformer.cpp transform/ModelTransformer.h transform/ModelTransformerFactory.cpp transform/ModelTransformerFactory.h
diffstat 6 files changed, 104 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/transform/FeatureExtractionModelTransformer.cpp	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/FeatureExtractionModelTransformer.cpp	Wed Jan 29 15:58:15 2014 +0000
@@ -418,8 +418,8 @@
         // descriptor to a list of models indexed by bin-1). But we
         // don't create the additional models yet, as this case has to
         // work even if the number of bins is unknown at this point --
-        // we just create an additional model (copying its parameters
-        // from the default one) each time a new bin is encountered.
+        // we create an additional model (copying its parameters from
+        // the default one) each time a new bin is encountered.
 
         if (!haveBinCount || binCount > 1) {
             m_needAdditionalModels[n] = true;
@@ -499,6 +499,17 @@
     return mm;
 }
 
+bool
+FeatureExtractionModelTransformer::willHaveAdditionalOutputModels()
+{
+    for (std::map<int, bool>::const_iterator i =
+             m_needAdditionalModels.begin(); 
+         i != m_needAdditionalModels.end(); ++i) {
+        if (i->second) return true;
+    }
+    return false;
+}
+
 SparseTimeValueModel *
 FeatureExtractionModelTransformer::getAdditionalModel(int n, int binNo)
 {
@@ -558,7 +569,7 @@
     Transform primaryTransform = m_transforms[0];
 
     while (!input->isReady() && !m_abandoned) {
-        SVDEBUG << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << endl;
+        cerr << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << endl;
         usleep(500000);
     }
     if (m_abandoned) return;
--- a/transform/FeatureExtractionModelTransformer.h	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/FeatureExtractionModelTransformer.h	Wed Jan 29 15:58:15 2014 +0000
@@ -44,6 +44,10 @@
 
     virtual ~FeatureExtractionModelTransformer();
 
+    // ModelTransformer method, retrieve the additional models
+    Models getAdditionalOutputModels();
+    bool willHaveAdditionalOutputModels();
+
 protected:
     bool initialise();
 
@@ -61,9 +65,6 @@
     AdditionalModelMap m_additionalModels;
     SparseTimeValueModel *getAdditionalModel(int transformNo, int binNo);
 
-    // ModelTransformer method, retrieve the additional models
-    Models getAdditionalOutputModels();
-
     void addFeature(int n,
                     size_t blockFrame,
 		    const Vamp::Plugin::Feature &feature);
--- a/transform/ModelTransformer.cpp	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/ModelTransformer.cpp	Wed Jan 29 15:58:15 2014 +0000
@@ -18,6 +18,7 @@
 ModelTransformer::ModelTransformer(Input input, const Transform &transform) :
     m_input(input),
     m_detached(false),
+    m_detachedAdd(false),
     m_abandoned(false)
 {
     m_transforms.push_back(transform);
@@ -27,6 +28,7 @@
     m_transforms(transforms),
     m_input(input),
     m_detached(false),
+    m_detachedAdd(false),
     m_abandoned(false)
 {
 }
@@ -36,19 +38,12 @@
     m_abandoned = true;
     wait();
     if (!m_detached) {
-        Models mine = getOutputModels(); // including any additional ones
-        foreach (Model *m, mine) {
-            delete m;
-        }
+        Models mine = getOutputModels();
+        foreach (Model *m, mine) delete m;
+    }
+    if (!m_detachedAdd) {
+        Models mine = getAdditionalOutputModels();
+        foreach (Model *m, mine) delete m;
     }
 }
 
-ModelTransformer::Models
-ModelTransformer::getOutputModels()
-{
-    Models out(m_outputs);
-    Models add(getAdditionalOutputModels());
-    foreach (Model *m, add) out.push_back(m);
-    return out;
-}
-
--- a/transform/ModelTransformer.h	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/ModelTransformer.h	Wed Jan 29 15:58:15 2014 +0000
@@ -83,14 +83,42 @@
      * be initialised; an error message may be available via
      * getMessage() in this situation.
      */
-    Models getOutputModels();        
+    Models getOutputModels() { return m_outputs; }
 
     /**
      * Return the set of output models, also detaching them from the
      * transformer so that they will not be deleted when the
      * transformer is.  The caller takes ownership of the models.
      */
-    Models detachOutputModels() { m_detached = true; return getOutputModels(); }
+    Models detachOutputModels() { 
+        m_detached = true; 
+        return getOutputModels(); 
+    }
+
+    /**
+     * Return any additional models that were created during
+     * processing. This might happen if, for example, a transform was
+     * configured to split a multi-bin output into separate single-bin
+     * models as it processed. These should not be queried until after
+     * the transform has completed.
+     */
+    virtual Models getAdditionalOutputModels() { return Models(); }
+
+    /**
+     * Return true if the current transform is one that may produce
+     * additional models (to be retrieved through
+     * getAdditionalOutputModels above).
+     */
+    virtual bool willHaveAdditionalOutputModels() { return false; }
+
+    /**
+     * Return the set of additional models, also detaching them from
+     * the transformer.  The caller takes ownership of the models.
+     */
+    virtual Models detachAdditionalOutputModels() { 
+        m_detachedAdd = true;
+        return getAdditionalOutputModels();
+    }
 
     /**
      * Return a warning or error message.  If getOutputModel returned
@@ -104,18 +132,11 @@
     ModelTransformer(Input input, const Transform &transform);
     ModelTransformer(Input input, const Transforms &transforms);
 
-    /**
-     * Return any additional models that were created during
-     * processing. This might happen if, for example, a transform was
-     * configured to split a multi-bin output into separate single-bin
-     * models as it processed.
-     */
-    virtual Models getAdditionalOutputModels() { return Models(); }
-
     Transforms m_transforms;
     Input m_input; // I don't own the model in this
     Models m_outputs; // I own this, unless...
     bool m_detached; // ... this is true.
+    bool m_detachedAdd;
     bool m_abandoned;
     QString m_message;
 };
--- a/transform/ModelTransformerFactory.cpp	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/ModelTransformerFactory.cpp	Wed Jan 29 15:58:15 2014 +0000
@@ -195,13 +195,14 @@
 Model *
 ModelTransformerFactory::transform(const Transform &transform,
                                    const ModelTransformer::Input &input,
-                                   QString &message) 
+                                   QString &message,
+                                   AdditionalModelHandler *handler) 
 {
     SVDEBUG << "ModelTransformerFactory::transform: Constructing transformer with input model " << input.getModel() << endl;
 
     Transforms transforms;
     transforms.push_back(transform);
-    vector<Model *> mm = transformMultiple(transforms, input, message);
+    vector<Model *> mm = transformMultiple(transforms, input, message, handler);
     if (mm.empty()) return 0;
     else return mm[0];
 }
@@ -209,17 +210,22 @@
 vector<Model *>
 ModelTransformerFactory::transformMultiple(const Transforms &transforms,
                                            const ModelTransformer::Input &input,
-                                           QString &message) 
+                                           QString &message,
+                                           AdditionalModelHandler *handler) 
 {
     SVDEBUG << "ModelTransformerFactory::transformMultiple: Constructing transformer with input model " << input.getModel() << endl;
     
     ModelTransformer *t = createTransformer(transforms, input);
     if (!t) return vector<Model *>();
 
-    connect(t, SIGNAL(finished()), this, SLOT(transformerFinished()));
+    if (handler) {
+        m_handlers[t] = handler;
+    }
 
     m_runningTransformers.insert(t);
 
+    connect(t, SIGNAL(finished()), this, SLOT(transformerFinished()));
+
     t->start();
     vector<Model *> models = t->detachOutputModels();
 
@@ -270,6 +276,14 @@
 
     m_runningTransformers.erase(transformer);
 
+    if (m_handlers.find(transformer) != m_handlers.end()) {
+        if (transformer->willHaveAdditionalOutputModels()) {
+            vector<Model *> mm = transformer->detachAdditionalOutputModels();
+            m_handlers[transformer]->moreModelsAvailable(mm);
+        }
+        m_handlers.erase(transformer);
+    }
+
     transformer->wait(); // unnecessary but reassuring
     delete transformer;
 }
--- a/transform/ModelTransformerFactory.h	Wed Jan 29 09:31:22 2014 +0000
+++ b/transform/ModelTransformerFactory.h	Wed Jan 29 15:58:15 2014 +0000
@@ -70,6 +70,11 @@
                                  size_t startFrame = 0,
                                  size_t duration = 0,
                                  UserConfigurator *configurator = 0);
+
+    class AdditionalModelHandler {
+    public:
+        virtual void moreModelsAvailable(std::vector<Model *> models) = 0;
+    };
     
     /**
      * Return the output model resulting from applying the named
@@ -82,12 +87,21 @@
      * problem occurs, return 0.  Set message if there is any error or
      * warning to report.
      * 
+     * Some transforms may return additional models at the end of
+     * processing. (For example, a transform that splits an output
+     * into multiple one-per-bin models.) If an additionalModelHandler
+     * is provided here, its moreModelsAvailable method will be called
+     * when those models become available, and ownership of those
+     * models will be transferred to the handler. Otherwise (if the
+     * handler is null) any such models will be discarded.
+     *
      * The returned model is owned by the caller and must be deleted
      * when no longer needed.
      */
     Model *transform(const Transform &transform,
                      const ModelTransformer::Input &input,
-                     QString &message);
+                     QString &message,
+                     AdditionalModelHandler *handler = 0);
 
     /**
      * Return the multiple output models resulting from applying the
@@ -105,13 +119,22 @@
      * for the given transform, or if some other problem occurs,
      * return 0.  Set message if there is any error or warning to
      * report.
-     * 
+     *
+     * Some transforms may return additional models at the end of
+     * processing. (For example, a transform that splits an output
+     * into multiple one-per-bin models.) If an additionalModelHandler
+     * is provided here, its moreModelsAvailable method will be called
+     * when those models become available, and ownership of those
+     * models will be transferred to the handler. Otherwise (if the
+     * handler is null) any such models will be discarded.
+     *
      * The returned models are owned by the caller and must be deleted
      * when no longer needed.
      */
     std::vector<Model *> transformMultiple(const Transforms &transform,
                                            const ModelTransformer::Input &input,
-                                           QString &message);
+                                           QString &message,
+                                           AdditionalModelHandler *handler = 0);
 
 protected slots:
     void transformerFinished();
@@ -128,6 +151,9 @@
     typedef std::set<ModelTransformer *> TransformerSet;
     TransformerSet m_runningTransformers;
 
+    typedef std::map<ModelTransformer *, AdditionalModelHandler *> HandlerMap;
+    HandlerMap m_handlers;
+
     static ModelTransformerFactory *m_instance;
 };