annotate data/model/Model.cpp @ 360:ac300d385ab2

* Various fixes to object lifetime management, particularly in the spectrum layer and for notification of main model deletion. The main purpose of this is to improve the behaviour of the spectrum, but I think it may also help with #1840922 Various crashes in Layer Summary window.
author Chris Cannam
date Wed, 23 Jan 2008 15:43:27 +0000
parents 700cd3350391
children d77e1fa49e26
rev   line source
Chris@150 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@150 2
Chris@150 3 /*
Chris@150 4 Sonic Visualiser
Chris@150 5 An audio file viewer and annotation editor.
Chris@150 6 Centre for Digital Music, Queen Mary, University of London.
Chris@150 7 This file copyright 2006 Chris Cannam.
Chris@150 8
Chris@150 9 This program is free software; you can redistribute it and/or
Chris@150 10 modify it under the terms of the GNU General Public License as
Chris@150 11 published by the Free Software Foundation; either version 2 of the
Chris@150 12 License, or (at your option) any later version. See the file
Chris@150 13 COPYING included with this distribution for more information.
Chris@150 14 */
Chris@150 15
Chris@150 16 #include "Model.h"
Chris@319 17 #include "AlignmentModel.h"
Chris@150 18 #include "base/PlayParameterRepository.h"
Chris@150 19
Chris@150 20 #include <QTextStream>
Chris@150 21
Chris@150 22 #include <iostream>
Chris@150 23
Chris@150 24 const int Model::COMPLETION_UNKNOWN = -1;
Chris@150 25
Chris@150 26 Model::~Model()
Chris@150 27 {
Chris@360 28 std::cerr << "Model::~Model(" << this << ")" << std::endl;
Chris@150 29
Chris@319 30 if (!m_aboutToDelete) {
Chris@319 31 std::cerr << "NOTE: Model::~Model(" << this << ", \""
Chris@319 32 << objectName().toStdString() << "\"): Model deleted "
Chris@319 33 << "with no aboutToDelete notification" << std::endl;
Chris@319 34 }
Chris@319 35
Chris@319 36 if (m_alignment) {
Chris@319 37 m_alignment->aboutToDelete();
Chris@319 38 delete m_alignment;
Chris@319 39 }
Chris@319 40
Chris@150 41 // Subclasses have to handle adding themselves to the repository,
Chris@150 42 // if they want to be played. We can't do it from here because
Chris@150 43 // the repository would be unable to tell whether we were playable
Chris@150 44 // or not (because dynamic_cast won't work from the base class ctor)
Chris@150 45 PlayParameterRepository::getInstance()->removeModel(this);
Chris@150 46 }
Chris@150 47
Chris@150 48 void
Chris@319 49 Model::setSourceModel(Model *model)
Chris@319 50 {
Chris@319 51 if (m_sourceModel) {
Chris@319 52 disconnect(m_sourceModel, SIGNAL(aboutToBeDeleted()),
Chris@319 53 this, SLOT(sourceModelAboutToBeDeleted()));
Chris@319 54 }
Chris@319 55
Chris@319 56 m_sourceModel = model;
Chris@319 57
Chris@319 58 if (m_sourceModel) {
Chris@333 59 connect(m_sourceModel, SIGNAL(alignmentCompletionChanged()),
Chris@333 60 this, SIGNAL(alignmentCompletionChanged()));
Chris@319 61 connect(m_sourceModel, SIGNAL(aboutToBeDeleted()),
Chris@319 62 this, SLOT(sourceModelAboutToBeDeleted()));
Chris@319 63 }
Chris@319 64 }
Chris@319 65
Chris@319 66 void
Chris@319 67 Model::aboutToDelete()
Chris@319 68 {
Chris@360 69 std::cerr << "Model(" << this << ")::aboutToDelete()" << std::endl;
Chris@360 70
Chris@319 71 if (m_aboutToDelete) {
Chris@319 72 std::cerr << "WARNING: Model(" << this << ", \""
Chris@319 73 << objectName().toStdString() << "\")::aboutToDelete: "
Chris@319 74 << "aboutToDelete called more than once for the same model"
Chris@319 75 << std::endl;
Chris@319 76 }
Chris@319 77
Chris@319 78 emit aboutToBeDeleted();
Chris@319 79 m_aboutToDelete = true;
Chris@319 80 }
Chris@319 81
Chris@319 82 void
Chris@319 83 Model::sourceModelAboutToBeDeleted()
Chris@319 84 {
Chris@319 85 m_sourceModel = 0;
Chris@319 86 }
Chris@319 87
Chris@319 88 void
Chris@319 89 Model::setAlignment(AlignmentModel *alignment)
Chris@319 90 {
Chris@319 91 if (m_alignment) {
Chris@319 92 m_alignment->aboutToDelete();
Chris@319 93 delete m_alignment;
Chris@319 94 }
Chris@319 95 m_alignment = alignment;
Chris@319 96 connect(m_alignment, SIGNAL(completionChanged()),
Chris@319 97 this, SIGNAL(alignmentCompletionChanged()));
Chris@319 98 }
Chris@319 99
Chris@319 100 const Model *
Chris@319 101 Model::getAlignmentReference() const
Chris@319 102 {
Chris@333 103 if (!m_alignment) {
Chris@333 104 if (m_sourceModel) return m_sourceModel->getAlignmentReference();
Chris@333 105 return this;
Chris@333 106 }
Chris@319 107 return m_alignment->getReferenceModel();
Chris@319 108 }
Chris@319 109
Chris@319 110 size_t
Chris@319 111 Model::alignToReference(size_t frame) const
Chris@319 112 {
Chris@333 113 if (!m_alignment) {
Chris@333 114 if (m_sourceModel) return m_sourceModel->alignToReference(frame);
Chris@333 115 else return frame;
Chris@333 116 }
Chris@333 117 size_t refFrame = m_alignment->toReference(frame);
Chris@340 118 const Model *m = m_alignment->getReferenceModel();
Chris@340 119 if (m && refFrame > m->getEndFrame()) refFrame = m->getEndFrame();
Chris@333 120 return refFrame;
Chris@319 121 }
Chris@319 122
Chris@319 123 size_t
Chris@319 124 Model::alignFromReference(size_t refFrame) const
Chris@319 125 {
Chris@333 126 if (!m_alignment) {
Chris@333 127 if (m_sourceModel) return m_sourceModel->alignFromReference(refFrame);
Chris@333 128 else return refFrame;
Chris@333 129 }
Chris@333 130 size_t frame = m_alignment->fromReference(refFrame);
Chris@340 131 if (frame > getEndFrame()) frame = getEndFrame();
Chris@333 132 return frame;
Chris@319 133 }
Chris@319 134
Chris@319 135 int
Chris@319 136 Model::getAlignmentCompletion() const
Chris@319 137 {
Chris@323 138 // std::cerr << "Model::getAlignmentCompletion" << std::endl;
Chris@333 139 if (!m_alignment) {
Chris@333 140 if (m_sourceModel) return m_sourceModel->getAlignmentCompletion();
Chris@333 141 else return 100;
Chris@333 142 }
Chris@319 143 int completion = 0;
Chris@319 144 (void)m_alignment->isReady(&completion);
Chris@323 145 // std::cerr << " -> " << completion << std::endl;
Chris@319 146 return completion;
Chris@319 147 }
Chris@319 148
Chris@333 149 QString
Chris@333 150 Model::getTitle() const
Chris@333 151 {
Chris@333 152 if (m_sourceModel) return m_sourceModel->getTitle();
Chris@345 153 else return "";
Chris@333 154 }
Chris@333 155
Chris@333 156 QString
Chris@333 157 Model::getMaker() const
Chris@333 158 {
Chris@333 159 if (m_sourceModel) return m_sourceModel->getMaker();
Chris@345 160 else return "";
Chris@345 161 }
Chris@345 162
Chris@345 163 QString
Chris@345 164 Model::getLocation() const
Chris@345 165 {
Chris@345 166 if (m_sourceModel) return m_sourceModel->getLocation();
Chris@345 167 else return "";
Chris@333 168 }
Chris@333 169
Chris@319 170 void
Chris@150 171 Model::toXml(QTextStream &stream, QString indent,
Chris@150 172 QString extraAttributes) const
Chris@150 173 {
Chris@150 174 stream << indent;
Chris@150 175 stream << QString("<model id=\"%1\" name=\"%2\" sampleRate=\"%3\" start=\"%4\" end=\"%5\" %6/>\n")
Chris@150 176 .arg(getObjectExportId(this))
Chris@150 177 .arg(encodeEntities(objectName()))
Chris@150 178 .arg(getSampleRate())
Chris@150 179 .arg(getStartFrame())
Chris@150 180 .arg(getEndFrame())
Chris@150 181 .arg(extraAttributes);
Chris@150 182 }
Chris@150 183
Chris@150 184