Mercurial > hg > svapp
changeset 329:f72d58d1ccb0 tonioni
Adapt additional models created during a transform so they can be returned through a callback in an async method
author | Chris Cannam |
---|---|
date | Wed, 29 Jan 2014 17:32:47 +0000 |
parents | d2c13ec0f148 |
children | 350a410e0555 |
files | framework/Document.cpp framework/Document.h framework/SVFileReader.cpp |
diffstat | 3 files changed, 195 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/framework/Document.cpp Fri Jan 17 11:59:49 2014 -0500 +++ b/framework/Document.cpp Wed Jan 29 17:32:47 2014 +0000 @@ -224,7 +224,7 @@ const ModelTransformer::Input &input) { QString message; - vector<Model *> newModels = addDerivedModels(transforms, input, message); + vector<Model *> newModels = addDerivedModels(transforms, input, message, 0); if (newModels.empty()) { //!!! This identifier may be wrong! @@ -235,8 +235,101 @@ emit modelGenerationWarning(transforms[0].getIdentifier(), message); } + QStringList names; + for (int i = 0; i < newModels.size(); ++i) { + names.push_back(getUniqueLayerName + (TransformFactory::getInstance()-> + getTransformFriendlyName + (transforms[i].getIdentifier()))); + } + + vector<Layer *> layers = createLayersForDerivedModels(newModels, names); + return layers; +} + +class AdditionalModelConverter : + public ModelTransformerFactory::AdditionalModelHandler +{ +public: + AdditionalModelConverter(Document *doc, + Document::LayerCreationHandler *handler) : + m_doc(doc), + m_handler(handler) { + } + + virtual ~AdditionalModelConverter() { } + + void + setPrimaryLayers(vector<Layer *> layers) { + m_primary = layers; + } + + void + moreModelsAvailable(vector<Model *> models) { + std::cerr << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << std::endl; + // We can't automatically regenerate the additional models on + // reload -- we should delete them instead + QStringList names; + foreach (Model *model, models) { + m_doc->addAdditionalModel(model); + names.push_back(QString()); + } + vector<Layer *> layers = m_doc->createLayersForDerivedModels + (models, names); + m_handler->layersCreated(m_primary, layers); + delete this; + } + + void + noMoreModelsAvailable() { + std::cerr << "AdditionalModelConverter::noMoreModelsAvailable" << std::endl; + delete this; + } + +private: + Document *m_doc; + vector<Layer *> m_primary; + Document::LayerCreationHandler *m_handler; //!!! how to handle destruction of this? +}; + +void +Document::createDerivedLayersAsync(const Transforms &transforms, + const ModelTransformer::Input &input, + LayerCreationHandler *handler) +{ + QString message; + + AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler); + + vector<Model *> newModels = addDerivedModels + (transforms, input, message, amc); + + QStringList names; + for (int i = 0; i < newModels.size(); ++i) { + names.push_back(getUniqueLayerName + (TransformFactory::getInstance()-> + getTransformFriendlyName + (transforms[i].getIdentifier()))); + } + + vector<Layer *> layers = createLayersForDerivedModels(newModels, names); + amc->setPrimaryLayers(layers); + + if (newModels.empty()) { + //!!! This identifier may be wrong! + emit modelGenerationFailed(transforms[0].getIdentifier(), message); + } else if (message != "") { + //!!! This identifier may be wrong! + emit modelGenerationWarning(transforms[0].getIdentifier(), message); + } +} + +vector<Layer *> +Document::createLayersForDerivedModels(vector<Model *> newModels, + QStringList names) +{ vector<Layer *> layers; - + for (int i = 0; i < (int)newModels.size(); ++i) { Model *newModel = newModels[i]; @@ -245,7 +338,7 @@ LayerFactory::getInstance()->getValidLayerTypes(newModel); if (types.empty()) { - cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transforms[i].getIdentifier() << endl; + cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl; //!!! inadequate cleanup: newModel->aboutToDelete(); emit modelAboutToBeDeleted(newModel); @@ -275,10 +368,7 @@ // model pointer in both layers, so they can't actually be cloned. if (newLayer) { - newLayer->setObjectName(getUniqueLayerName - (TransformFactory::getInstance()-> - getTransformFriendlyName - (transforms[i].getIdentifier()))); + newLayer->setObjectName(names[i]); } emit layerAdded(newLayer); @@ -423,6 +513,14 @@ } for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { + if (i->second.additional) { + Model *m = i->first; + emit modelAboutToBeDeleted(m); + delete m; + } + } + + for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { Model *m = i->first; @@ -457,21 +555,21 @@ } void -Document::addDerivedModel(const Transform &transform, - const ModelTransformer::Input &input, - Model *outputModelToAdd) +Document::addAlreadyDerivedModel(const Transform &transform, + const ModelTransformer::Input &input, + Model *outputModelToAdd) { if (m_models.find(outputModelToAdd) != m_models.end()) { - cerr << "WARNING: Document::addDerivedModel: Model already added" + cerr << "WARNING: Document::addAlreadyDerivedModel: Model already added" << endl; return; } #ifdef DEBUG_DOCUMENT if (input.getModel()) { - cerr << "Document::addDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl; + cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl; } else { - cerr << "Document::addDerivedModel: source is " << input.getModel() << endl; + cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl; } #endif @@ -479,6 +577,7 @@ rec.source = input.getModel(); rec.channel = input.getChannel(); rec.transform = transform; + rec.additional = false; rec.refcount = 0; outputModelToAdd->setSourceModel(input.getModel()); @@ -486,7 +585,7 @@ m_models[outputModelToAdd] = rec; #ifdef DEBUG_DOCUMENT - SVDEBUG << "Document::addDerivedModel: Added model " << outputModelToAdd << endl; + cerr << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl; cerr << "Models now: "; for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { cerr << i->first << " "; @@ -510,6 +609,7 @@ ModelRecord rec; rec.source = 0; rec.refcount = 0; + rec.additional = false; m_models[model] = rec; @@ -527,6 +627,36 @@ emit modelAdded(model); } +void +Document::addAdditionalModel(Model *model) +{ + if (m_models.find(model) != m_models.end()) { + cerr << "WARNING: Document::addAdditionalModel: Model already added" + << endl; + return; + } + + ModelRecord rec; + rec.source = 0; + rec.refcount = 0; + rec.additional = true; + + m_models[model] = rec; + +#ifdef DEBUG_DOCUMENT + SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl; + cerr << "Models now: "; + for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) { + cerr << i->first << " "; + } + cerr << endl; +#endif + + if (m_autoAlignment) alignModel(model); + + emit modelAdded(model); +} + Model * Document::addDerivedModel(const Transform &transform, const ModelTransformer::Input &input, @@ -543,7 +673,7 @@ Transforms tt; tt.push_back(transform); - vector<Model *> mm = addDerivedModels(tt, input, message); + vector<Model *> mm = addDerivedModels(tt, input, message, 0); if (mm.empty()) return 0; else return mm[0]; } @@ -551,11 +681,12 @@ vector<Model *> Document::addDerivedModels(const Transforms &transforms, const ModelTransformer::Input &input, - QString &message) + QString &message, + AdditionalModelConverter *amc) { vector<Model *> mm = ModelTransformerFactory::getInstance()->transformMultiple - (transforms, input, message); + (transforms, input, message, amc); for (int j = 0; j < (int)mm.size(); ++j) { @@ -579,7 +710,7 @@ if (!model) { cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl; } else { - addDerivedModel(applied, input, model); + addAlreadyDerivedModel(applied, input, model); } }
--- a/framework/Document.h Fri Jan 17 11:59:49 2014 -0500 +++ b/framework/Document.h Wed Jan 29 17:32:47 2014 +0000 @@ -30,6 +30,8 @@ class View; class WaveFileModel; +class AdditionalModelConverter; + /** * A Sonic Visualiser document consists of a set of data models, and * also the visualisation layers used to display them. Changes to the @@ -121,11 +123,37 @@ * Create and return suitable layers for the given transforms, * which must be identical apart from the output (i.e. must use * the same plugin and configuration). The layers are returned in - * the same order as the transformed are supplied. + * the same order as the transforms are supplied. */ std::vector<Layer *> createDerivedLayers(const Transforms &, const ModelTransformer::Input &); + class LayerCreationHandler { + public: + virtual ~LayerCreationHandler() { } + + /** + * The primary layers are those corresponding 1-1 to the input + * models, listed in the same order as the input models. The + * additional layers vector contains any layers (from all + * models) that were returned separately at the end of + * processing. + */ + virtual void layersCreated(std::vector<Layer *> primary, + std::vector<Layer *> additional) = 0; + }; + + /** + * Create suitable layers for the given transforms, which must be + * identical apart from the output (i.e. must use the same plugin + * and configuration). This method returns after initialising the + * transformer process, and the layers are returned through a + * subsequent call to the provided handler (which must be non-null). + */ + void createDerivedLayersAsync(const Transforms &, + const ModelTransformer::Input &, + LayerCreationHandler *handler); + /** * Delete the given layer, and also its associated model if no * longer used by any other layer. In general, this should be the @@ -168,18 +196,20 @@ * transforms, running the transforms and returning the resulting * models. */ + friend class AdditionalModelConverter; std::vector<Model *> addDerivedModels(const Transforms &transforms, const ModelTransformer::Input &input, - QString &returnedMessage); + QString &returnedMessage, + AdditionalModelConverter *); /** * Add a derived model associated with the given transform. This * is necessary to register any derived model that was not created * by the document using createDerivedModel or createDerivedLayer. */ - void addDerivedModel(const Transform &transform, - const ModelTransformer::Input &input, - Model *outputModelToAdd); + void addAlreadyDerivedModel(const Transform &transform, + const ModelTransformer::Input &input, + Model *outputModelToAdd); /** * Add an imported (non-derived, non-main) model. This is @@ -298,6 +328,7 @@ const Model *source; int channel; Transform transform; + bool additional; // Count of the number of layers using this model. int refcount; @@ -306,6 +337,12 @@ typedef std::map<Model *, ModelRecord> ModelMap; ModelMap m_models; + /** + * Add an extra derived model (returned at the end of processing a + * transform). + */ + void addAdditionalModel(Model *); + class AddLayerCommand : public Command { public: @@ -357,6 +394,9 @@ void toXml(QTextStream &, QString, QString, bool asTemplate) const; void writePlaceholderMainModel(QTextStream &, QString) const; + std::vector<Layer *> createLayersForDerivedModels(std::vector<Model *>, + QStringList names); + /** * And these are the layers. We also control the lifespans of * these (usually through the commands used to add and remove them).
--- a/framework/SVFileReader.cpp Fri Jan 17 11:59:49 2014 -0500 +++ b/framework/SVFileReader.cpp Wed Jan 29 17:32:47 2014 +0000 @@ -325,7 +325,7 @@ } } } else { - m_document->addDerivedModel + m_document->addAlreadyDerivedModel (m_currentTransform, ModelTransformer::Input(m_currentTransformSource, m_currentTransformChannel),